From 335473a23e668b0ca73cac3fda9556abb0c22073 Mon Sep 17 00:00:00 2001 From: wenytang-ms Date: Mon, 10 Nov 2025 13:29:21 +0800 Subject: [PATCH 1/9] chore: update --- .../ext/core/parser/ContextResolver.java | 293 +++++++++++++++--- 1 file changed, 248 insertions(+), 45 deletions(-) diff --git a/jdtls.ext/com.microsoft.jdtls.ext.core/src/com/microsoft/jdtls/ext/core/parser/ContextResolver.java b/jdtls.ext/com.microsoft.jdtls.ext.core/src/com/microsoft/jdtls/ext/core/parser/ContextResolver.java index b5d4ee30..6aeacf5a 100644 --- a/jdtls.ext/com.microsoft.jdtls.ext.core/src/com/microsoft/jdtls/ext/core/parser/ContextResolver.java +++ b/jdtls.ext/com.microsoft.jdtls.ext.core/src/com/microsoft/jdtls/ext/core/parser/ContextResolver.java @@ -862,13 +862,15 @@ public static String generateClassDescription(org.eclipse.jdt.core.IType type, S // ================ JavaDoc Extraction Methods ================ /** - * Extracts relevant code snippets from Javadoc. - * This method is optimized to extract code from `` tags and markdown code fences, - * and formats them in an LLM-readable format. + * Extracts relevant JavaDoc content including description text and code snippets. + * This method extracts: + * 1. Class description (first paragraph of text) + * 2. Code snippets from ,
, and ``` blocks
+     * 3. @deprecated tag if present
      *
      * @param type the type to extract Javadoc from.
      * @param monitor the progress monitor.
-     * @return A string containing all found code snippets, formatted as markdown code blocks.
+     * @return A string containing description and code snippets in LLM-readable format.
      */
     private static String extractRelevantJavaDocContent(org.eclipse.jdt.core.IType type, IProgressMonitor monitor) {
         try {
@@ -883,7 +885,6 @@ private static String extractRelevantJavaDocContent(org.eclipse.jdt.core.IType t
             }
             
             String rawJavadoc;
-            boolean isHtml = false;
 
             // Extract JavaDoc from source code (fast - no I/O, no network, no HTML parsing)
             org.eclipse.jdt.core.ISourceRange javadocRange = type.getJavadocRange();
@@ -896,49 +897,118 @@ private static String extractRelevantJavaDocContent(org.eclipse.jdt.core.IType t
                 return "";
             }
 
-            StringBuilder allCodeSnippets = new StringBuilder();
+            StringBuilder result = new StringBuilder();
             Set seenCodeSnippets = new HashSet<>();
+            
+            // Clean Javadoc comment for processing
+            String cleanedJavadoc = cleanJavadocComment(rawJavadoc);
+            cleanedJavadoc = convertHtmlEntities(cleanedJavadoc);
+
+            // === High Priority: Extract class description text (first paragraph) ===
+            String description = extractClassDescription(cleanedJavadoc);
+            if (isNotEmpty(description)) {
+                result.append("Description:\n").append(description).append("\n\n");
+            }
+            
+            // === High Priority: Check for @deprecated tag ===
+            if (isDeprecated(cleanedJavadoc)) {
+                result.append("⚠️ DEPRECATED: This class is deprecated and should not be used in new code.\n\n");
+            }
 
+            // === Extract code snippets ===
             // 1. Extract markdown code blocks (```...```)
             Matcher markdownMatcher = MARKDOWN_CODE_PATTERN.matcher(rawJavadoc);
             while (markdownMatcher.find()) {
                 String code = markdownMatcher.group(1).trim();
                 if (isNotEmpty(code) && seenCodeSnippets.add(code)) {
-                    allCodeSnippets.append("```java\n").append(code).append("\n```\n\n");
+                    result.append("Example:\n```java\n").append(code).append("\n```\n\n");
                 }
             }
 
             // 2. Extract HTML 
 and  blocks
-            // Clean Javadoc comment for HTML extraction
-            String cleanedForHtml = isHtml ? rawJavadoc : cleanJavadocComment(rawJavadoc);
-            cleanedForHtml = convertHtmlEntities(cleanedForHtml);
-
             // Priority 1: 
 blocks (often contain well-formatted code)
-            Matcher preMatcher = HTML_PRE_PATTERN.matcher(cleanedForHtml);
+            Matcher preMatcher = HTML_PRE_PATTERN.matcher(cleanedJavadoc);
             while (preMatcher.find()) {
                 String code = preMatcher.group(1).replaceAll("(?i)]*>", "").replaceAll("(?i)", "").trim();
                 if (isNotEmpty(code) && seenCodeSnippets.add(code)) {
-                    allCodeSnippets.append("```java\n").append(code).append("\n```\n\n");
+                    result.append("Example:\n```java\n").append(code).append("\n```\n\n");
                 }
             }
 
             // Priority 2:  blocks (for inline snippets)
-            Matcher codeMatcher = HTML_CODE_PATTERN.matcher(cleanedForHtml);
+            Matcher codeMatcher = HTML_CODE_PATTERN.matcher(cleanedJavadoc);
             while (codeMatcher.find()) {
                 String code = codeMatcher.group(1).trim();
                 // Use HashSet for O(1) duplicate checking
                 if (isNotEmpty(code) && seenCodeSnippets.add(code)) {
-                    allCodeSnippets.append("```java\n").append(code).append("\n```\n\n");
+                    result.append("Example:\n```java\n").append(code).append("\n```\n\n");
                 }
             }
 
-            return allCodeSnippets.toString().trim();
+            return result.toString().trim();
 
         } catch (Exception e) {
             JdtlsExtActivator.logException("Error extracting relevant JavaDoc content for: " + type.getElementName(), e);
             return "";
         }
     }
+    
+    /**
+     * Extract the main description paragraph from class JavaDoc (before @tags and code blocks).
+     * Returns the first paragraph of descriptive text, limited to reasonable length.
+     */
+    private static String extractClassDescription(String cleanedJavadoc) {
+        if (!isNotEmpty(cleanedJavadoc)) {
+            return "";
+        }
+        
+        // Remove code blocks first to get pure text
+        String textOnly = cleanedJavadoc;
+        textOnly = MARKDOWN_CODE_PATTERN.matcher(textOnly).replaceAll("");
+        textOnly = HTML_PRE_PATTERN.matcher(textOnly).replaceAll("");
+        textOnly = HTML_CODE_PATTERN.matcher(textOnly).replaceAll("");
+        
+        // Extract description before @tags
+        String description = extractJavadocDescription(textOnly);
+        
+        // Limit to first 2-3 sentences or ~200 characters
+        if (description.length() > 200) {
+            // Try to find a good break point (., !, ?)
+            int[] boundaries = {
+                description.indexOf(". ", 100),
+                description.indexOf(".\n", 100),
+                description.indexOf("! ", 100),
+                description.indexOf("? ", 100)
+            };
+            
+            int breakPoint = -1;
+            for (int boundary : boundaries) {
+                if (boundary != -1 && boundary < 250 && (breakPoint == -1 || boundary < breakPoint)) {
+                    breakPoint = boundary;
+                }
+            }
+            
+            if (breakPoint != -1) {
+                description = description.substring(0, breakPoint + 1).trim();
+            } else {
+                // No good break point, just truncate with ellipsis
+                int lastSpace = description.lastIndexOf(' ', 200);
+                description = description.substring(0, lastSpace > 100 ? lastSpace : 200).trim() + "...";
+            }
+        }
+        
+        return description.trim();
+    }
+    
+    /**
+     * Check if the JavaDoc contains @deprecated tag.
+     */
+    private static boolean isDeprecated(String cleanedJavadoc) {
+        if (!isNotEmpty(cleanedJavadoc)) {
+            return false;
+        }
+        return cleanedJavadoc.contains("@deprecated");
+    }
 
     /**
      * Clean up raw JavaDoc comment by removing comment markers and asterisks
@@ -1001,11 +1071,142 @@ private static String convertHtmlEntities(String text) {
     }
 
     /**
-     * Extract summary description from method JavaDoc
-     * Returns the first sentence or paragraph of the JavaDoc as a brief description
+     * Extract detailed JavaDoc summary from method including @param, @return, and @throws tags.
+     * Returns a formatted string with the method description and parameter/return information.
      */
     private static String extractMethodJavaDocSummary(IMethod method) {
-        return extractJavaDocSummaryFromElement(method);
+        try {
+            org.eclipse.jdt.core.ISourceRange javadocRange = method.getJavadocRange();
+            if (javadocRange == null) {
+                return "";
+            }
+            
+            String rawJavadoc = method.getCompilationUnit().getSource()
+                .substring(javadocRange.getOffset(), javadocRange.getOffset() + javadocRange.getLength());
+            
+            if (!isNotEmpty(rawJavadoc)) {
+                return "";
+            }
+            
+            String cleaned = cleanJavadocComment(rawJavadoc);
+            StringBuilder result = new StringBuilder();
+            
+            // Extract main description (first sentence)
+            String description = extractJavadocDescription(cleaned);
+            String firstSentence = getFirstSentenceOrLimit(description, 120);
+            if (isNotEmpty(firstSentence)) {
+                result.append(firstSentence);
+            }
+            
+            // === Medium Priority: Parse @param tags ===
+            List params = extractJavadocTag(cleaned, "@param");
+            if (!params.isEmpty()) {
+                result.append(" | Params: ");
+                for (int i = 0; i < params.size() && i < 3; i++) { // Limit to 3 params
+                    if (i > 0) result.append(", ");
+                    result.append(params.get(i));
+                }
+                if (params.size() > 3) {
+                    result.append("...");
+                }
+            }
+            
+            // === Medium Priority: Parse @return tag ===
+            List returns = extractJavadocTag(cleaned, "@return");
+            if (!returns.isEmpty()) {
+                String returnDesc = returns.get(0);
+                // Limit return description to 60 chars
+                if (returnDesc.length() > 60) {
+                    returnDesc = returnDesc.substring(0, 57) + "...";
+                }
+                result.append(" | Returns: ").append(returnDesc);
+            }
+            
+            // === Medium Priority: Parse @throws tags ===
+            List throwsTags = extractJavadocTag(cleaned, "@throws");
+            if (throwsTags.isEmpty()) {
+                throwsTags = extractJavadocTag(cleaned, "@exception");
+            }
+            if (!throwsTags.isEmpty()) {
+                result.append(" | Throws: ");
+                for (int i = 0; i < throwsTags.size() && i < 2; i++) { // Limit to 2 exceptions
+                    if (i > 0) result.append(", ");
+                    // Extract just the exception class name (first word)
+                    String exceptionInfo = throwsTags.get(i);
+                    int spaceIndex = exceptionInfo.indexOf(' ');
+                    if (spaceIndex != -1) {
+                        result.append(exceptionInfo.substring(0, spaceIndex));
+                    } else {
+                        result.append(exceptionInfo);
+                    }
+                }
+                if (throwsTags.size() > 2) {
+                    result.append("...");
+                }
+            }
+            
+            // === High Priority: Mark deprecated methods ===
+            if (cleaned.contains("@deprecated")) {
+                result.append(" [DEPRECATED]");
+            }
+            
+            return result.toString();
+            
+        } catch (Exception e) {
+            return "";
+        }
+    }
+    
+    /**
+     * Extract JavaDoc tags of a specific type (e.g., @param, @return, @throws).
+     * Returns a list of tag values (without the tag name itself).
+     * 
+     * @param cleanedJavadoc Cleaned JavaDoc text
+     * @param tagName Tag name to search for (e.g., "@param")
+     * @return List of tag values
+     */
+    private static List extractJavadocTag(String cleanedJavadoc, String tagName) {
+        List results = new ArrayList<>();
+        
+        if (!isNotEmpty(cleanedJavadoc)) {
+            return results;
+        }
+        
+        String[] lines = cleanedJavadoc.split("\\n");
+        StringBuilder currentTag = null;
+        
+        for (String line : lines) {
+            String trimmed = line.trim();
+            
+            // Check if this line starts with the target tag
+            if (trimmed.startsWith(tagName + " ")) {
+                // Save previous tag if exists
+                if (currentTag != null) {
+                    results.add(currentTag.toString().trim());
+                }
+                // Start new tag (remove tag name)
+                currentTag = new StringBuilder(trimmed.substring(tagName.length() + 1).trim());
+            }
+            // Check if this line starts with any other tag
+            else if (trimmed.startsWith("@")) {
+                // Save previous tag if exists
+                if (currentTag != null) {
+                    results.add(currentTag.toString().trim());
+                    currentTag = null;
+                }
+            }
+            // Continuation of current tag
+            else if (currentTag != null && isNotEmpty(trimmed)) {
+                currentTag.append(" ").append(trimmed);
+            }
+        }
+        
+        // Don't forget the last tag
+        if (currentTag != null) {
+            results.add(currentTag.toString().trim());
+        }
+        
+        return results;
     }
 
     /**
@@ -1074,10 +1275,35 @@ private static String getFirstSentenceOrLimit(String text, int maxLength) {
     }
 
     /**
-     * Extract summary description from field JavaDoc
+     * Extract summary description from field JavaDoc, including @deprecated marking.
      */
     private static String extractFieldJavaDocSummary(org.eclipse.jdt.core.IField field) {
-        return extractJavaDocSummaryFromElement(field);
+        try {
+            org.eclipse.jdt.core.ISourceRange javadocRange = field.getJavadocRange();
+            if (javadocRange == null) {
+                return "";
+            }
+            
+            String rawJavadoc = field.getCompilationUnit().getSource()
+                .substring(javadocRange.getOffset(), javadocRange.getOffset() + javadocRange.getLength());
+            
+            if (!isNotEmpty(rawJavadoc)) {
+                return "";
+            }
+            
+            String cleaned = cleanJavadocComment(rawJavadoc);
+            String description = extractJavadocDescription(cleaned);
+            String summary = getFirstSentenceOrLimit(description, 120);
+            
+            // === High Priority: Mark deprecated fields ===
+            if (cleaned.contains("@deprecated")) {
+                summary += " [DEPRECATED]";
+            }
+            
+            return summary;
+        } catch (Exception e) {
+            return "";
+        }
     }
 
     /**
@@ -1228,30 +1454,7 @@ private static String simplifyTypeName(String qualifiedName) {
         return lastDot == -1 ? qualifiedName : qualifiedName.substring(lastDot + 1);
     }
 
-    /**
-     * Unified JavaDoc summary extractor for methods and fields
-     */
-    private static String extractJavaDocSummaryFromElement(org.eclipse.jdt.core.IMember element) {
-        try {
-            org.eclipse.jdt.core.ISourceRange javadocRange = element.getJavadocRange();
-            if (javadocRange == null) {
-                return "";
-            }
-            
-            String rawJavadoc = element.getCompilationUnit().getSource()
-                .substring(javadocRange.getOffset(), javadocRange.getOffset() + javadocRange.getLength());
-            
-            if (rawJavadoc == null || rawJavadoc.isEmpty()) {
-                return "";
-            }
-            
-            String cleaned = cleanJavadocComment(rawJavadoc);
-            String description = extractJavadocDescription(cleaned);
-            return getFirstSentenceOrLimit(description, 120);
-        } catch (Exception e) {
-            return "";
-        }
-    }
+
 
     /**
      * Unified method signature generator (handles both source and binary types)

From 0d83ea9d41fc4ec065033abebd6e74d8794aedde Mon Sep 17 00:00:00 2001
From: wenytang-ms 
Date: Mon, 10 Nov 2025 14:16:06 +0800
Subject: [PATCH 2/9] chore: update

---
 .../ext/core/parser/ContextResolver.java      | 103 +++++++++---------
 1 file changed, 52 insertions(+), 51 deletions(-)

diff --git a/jdtls.ext/com.microsoft.jdtls.ext.core/src/com/microsoft/jdtls/ext/core/parser/ContextResolver.java b/jdtls.ext/com.microsoft.jdtls.ext.core/src/com/microsoft/jdtls/ext/core/parser/ContextResolver.java
index 6aeacf5a..eacfcdea 100644
--- a/jdtls.ext/com.microsoft.jdtls.ext.core/src/com/microsoft/jdtls/ext/core/parser/ContextResolver.java
+++ b/jdtls.ext/com.microsoft.jdtls.ext.core/src/com/microsoft/jdtls/ext/core/parser/ContextResolver.java
@@ -231,16 +231,14 @@ private static boolean isCommonJdkType(String typeName) {
             return false;
         }
         
-        // Extract package name from fully qualified type name
         int lastDotIndex = typeName.lastIndexOf('.');
         if (lastDotIndex == -1) {
-            return false; // No package (default package)
+            return false;
         }
         
         String packageName = typeName.substring(0, lastDotIndex);
         
-        // Check if package matches any common JDK package
-        // This includes both exact matches and sub-packages
+        // Check exact match or sub-package match
         return SKIP_COMMON_JDK_PACKAGES.contains(packageName) || 
                SKIP_COMMON_JDK_PACKAGES.stream().anyMatch(pkg -> packageName.startsWith(pkg + "."));
     }
@@ -958,7 +956,7 @@ private static String extractRelevantJavaDocContent(org.eclipse.jdt.core.IType t
      * Returns the first paragraph of descriptive text, limited to reasonable length.
      */
     private static String extractClassDescription(String cleanedJavadoc) {
-        if (!isNotEmpty(cleanedJavadoc)) {
+        if (cleanedJavadoc == null || cleanedJavadoc.isEmpty()) {
             return "";
         }
         
@@ -973,25 +971,10 @@ private static String extractClassDescription(String cleanedJavadoc) {
         
         // Limit to first 2-3 sentences or ~200 characters
         if (description.length() > 200) {
-            // Try to find a good break point (., !, ?)
-            int[] boundaries = {
-                description.indexOf(". ", 100),
-                description.indexOf(".\n", 100),
-                description.indexOf("! ", 100),
-                description.indexOf("? ", 100)
-            };
-            
-            int breakPoint = -1;
-            for (int boundary : boundaries) {
-                if (boundary != -1 && boundary < 250 && (breakPoint == -1 || boundary < breakPoint)) {
-                    breakPoint = boundary;
-                }
-            }
-            
+            int breakPoint = findBestBreakpoint(description, 100, 250);
             if (breakPoint != -1) {
                 description = description.substring(0, breakPoint + 1).trim();
             } else {
-                // No good break point, just truncate with ellipsis
                 int lastSpace = description.lastIndexOf(' ', 200);
                 description = description.substring(0, lastSpace > 100 ? lastSpace : 200).trim() + "...";
             }
@@ -1004,10 +987,7 @@ private static String extractClassDescription(String cleanedJavadoc) {
      * Check if the JavaDoc contains @deprecated tag.
      */
     private static boolean isDeprecated(String cleanedJavadoc) {
-        if (!isNotEmpty(cleanedJavadoc)) {
-            return false;
-        }
-        return cleanedJavadoc.contains("@deprecated");
+        return cleanedJavadoc != null && cleanedJavadoc.contains("@deprecated");
     }
 
     /**
@@ -1057,17 +1037,15 @@ private static String convertHtmlEntities(String text) {
         if (text == null || text.isEmpty()) {
             return text;
         }
-        String result = text;
-        result = result.replace(" ", " ");
-        result = result.replace("<", "<");
-        result = result.replace(">", ">");
-        result = result.replace("&", "&");
-        result = result.replace(""", "\"");
-        result = result.replace("'", "'");
-        result = result.replace("'", "'");
-        result = result.replace("—", "-");
-        result = result.replace("–", "-");
-        return result;
+        return text.replace(" ", " ")
+                   .replace("<", "<")
+                   .replace(">", ">")
+                   .replace("&", "&")
+                   .replace(""", "\"")
+                   .replace("'", "'")
+                   .replace("'", "'")
+                   .replace("—", "-")
+                   .replace("–", "-");
     }
 
     /**
@@ -1129,16 +1107,11 @@ private static String extractMethodJavaDocSummary(IMethod method) {
             }
             if (!throwsTags.isEmpty()) {
                 result.append(" | Throws: ");
-                for (int i = 0; i < throwsTags.size() && i < 2; i++) { // Limit to 2 exceptions
+                for (int i = 0; i < Math.min(throwsTags.size(), 2); i++) {
                     if (i > 0) result.append(", ");
-                    // Extract just the exception class name (first word)
                     String exceptionInfo = throwsTags.get(i);
                     int spaceIndex = exceptionInfo.indexOf(' ');
-                    if (spaceIndex != -1) {
-                        result.append(exceptionInfo.substring(0, spaceIndex));
-                    } else {
-                        result.append(exceptionInfo);
-                    }
+                    result.append(spaceIndex != -1 ? exceptionInfo.substring(0, spaceIndex) : exceptionInfo);
                 }
                 if (throwsTags.size() > 2) {
                     result.append("...");
@@ -1168,7 +1141,7 @@ private static String extractMethodJavaDocSummary(IMethod method) {
     private static List extractJavadocTag(String cleanedJavadoc, String tagName) {
         List results = new ArrayList<>();
         
-        if (!isNotEmpty(cleanedJavadoc)) {
+        if (cleanedJavadoc == null || cleanedJavadoc.isEmpty()) {
             return results;
         }
         
@@ -1251,13 +1224,7 @@ private static String getFirstSentenceOrLimit(String text, int maxLength) {
         }
         
         // Find first sentence boundary (., !, ?)
-        int[] boundaries = {text.indexOf(". "), text.indexOf(".\n"), text.indexOf("! "), text.indexOf("? ")};
-        int firstSentenceEnd = -1;
-        for (int boundary : boundaries) {
-            if (boundary != -1 && (firstSentenceEnd == -1 || boundary < firstSentenceEnd)) {
-                firstSentenceEnd = boundary;
-            }
-        }
+        int firstSentenceEnd = findFirstSentenceBoundary(text);
         
         // Return first sentence if within reasonable length
         if (firstSentenceEnd != -1 && firstSentenceEnd < maxLength) {
@@ -1273,6 +1240,40 @@ private static String getFirstSentenceOrLimit(String text, int maxLength) {
         
         return text.trim();
     }
+    
+    /**
+     * Find the first sentence boundary in text
+     */
+    private static int findFirstSentenceBoundary(String text) {
+        int[] boundaries = {text.indexOf(". "), text.indexOf(".\n"), text.indexOf("! "), text.indexOf("? ")};
+        int result = -1;
+        for (int boundary : boundaries) {
+            if (boundary != -1 && (result == -1 || boundary < result)) {
+                result = boundary;
+            }
+        }
+        return result;
+    }
+    
+    /**
+     * Find the best breakpoint for truncating text within a range
+     */
+    private static int findBestBreakpoint(String text, int minPos, int maxPos) {
+        int[] boundaries = {
+            text.indexOf(". ", minPos),
+            text.indexOf(".\n", minPos),
+            text.indexOf("! ", minPos),
+            text.indexOf("? ", minPos)
+        };
+        
+        int result = -1;
+        for (int boundary : boundaries) {
+            if (boundary != -1 && boundary < maxPos && (result == -1 || boundary < result)) {
+                result = boundary;
+            }
+        }
+        return result;
+    }
 
     /**
      * Extract summary description from field JavaDoc, including @deprecated marking.

From 19fb8bfaab92d776160062043988542b1e4a9d69 Mon Sep 17 00:00:00 2001
From: wenyutang-ms 
Date: Mon, 10 Nov 2025 14:55:21 +0800
Subject: [PATCH 3/9] fix: fix comments

---
 .../com/microsoft/jdtls/ext/core/parser/ContextResolver.java  | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/jdtls.ext/com.microsoft.jdtls.ext.core/src/com/microsoft/jdtls/ext/core/parser/ContextResolver.java b/jdtls.ext/com.microsoft.jdtls.ext.core/src/com/microsoft/jdtls/ext/core/parser/ContextResolver.java
index eacfcdea..c020a410 100644
--- a/jdtls.ext/com.microsoft.jdtls.ext.core/src/com/microsoft/jdtls/ext/core/parser/ContextResolver.java
+++ b/jdtls.ext/com.microsoft.jdtls.ext.core/src/com/microsoft/jdtls/ext/core/parser/ContextResolver.java
@@ -1120,7 +1120,7 @@ private static String extractMethodJavaDocSummary(IMethod method) {
             
             // === High Priority: Mark deprecated methods ===
             if (cleaned.contains("@deprecated")) {
-                result.append(" [DEPRECATED]");
+                result.append(result.length() > 0 ? " " : "").append("[DEPRECATED]");
             }
             
             return result.toString();
@@ -1298,7 +1298,7 @@ private static String extractFieldJavaDocSummary(org.eclipse.jdt.core.IField fie
             
             // === High Priority: Mark deprecated fields ===
             if (cleaned.contains("@deprecated")) {
-                summary += " [DEPRECATED]";
+                summary = summary.isEmpty() ? "[DEPRECATED]" : summary + " [DEPRECATED]";  
             }
             
             return summary;

From 5bbaaeda8ecd11d67e6c1cc56cd4790ef2d145fb Mon Sep 17 00:00:00 2001
From: wenyutang-ms 
Date: Mon, 10 Nov 2025 15:12:20 +0800
Subject: [PATCH 4/9] fix: update the code

---
 .../jdtls/ext/core/parser/ContextResolver.java   | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/jdtls.ext/com.microsoft.jdtls.ext.core/src/com/microsoft/jdtls/ext/core/parser/ContextResolver.java b/jdtls.ext/com.microsoft.jdtls.ext.core/src/com/microsoft/jdtls/ext/core/parser/ContextResolver.java
index c020a410..6df581bb 100644
--- a/jdtls.ext/com.microsoft.jdtls.ext.core/src/com/microsoft/jdtls/ext/core/parser/ContextResolver.java
+++ b/jdtls.ext/com.microsoft.jdtls.ext.core/src/com/microsoft/jdtls/ext/core/parser/ContextResolver.java
@@ -919,7 +919,7 @@ private static String extractRelevantJavaDocContent(org.eclipse.jdt.core.IType t
             while (markdownMatcher.find()) {
                 String code = markdownMatcher.group(1).trim();
                 if (isNotEmpty(code) && seenCodeSnippets.add(code)) {
-                    result.append("Example:\n```java\n").append(code).append("\n```\n\n");
+                    result.append("```java\n").append(code).append("\n```\n\n");
                 }
             }
 
@@ -929,7 +929,7 @@ private static String extractRelevantJavaDocContent(org.eclipse.jdt.core.IType t
             while (preMatcher.find()) {
                 String code = preMatcher.group(1).replaceAll("(?i)]*>", "").replaceAll("(?i)", "").trim();
                 if (isNotEmpty(code) && seenCodeSnippets.add(code)) {
-                    result.append("Example:\n```java\n").append(code).append("\n```\n\n");
+                    result.append("```java\n").append(code).append("\n```\n\n");
                 }
             }
 
@@ -939,7 +939,7 @@ private static String extractRelevantJavaDocContent(org.eclipse.jdt.core.IType t
                 String code = codeMatcher.group(1).trim();
                 // Use HashSet for O(1) duplicate checking
                 if (isNotEmpty(code) && seenCodeSnippets.add(code)) {
-                    result.append("Example:\n```java\n").append(code).append("\n```\n\n");
+                    result.append("```java\n").append(code).append("\n```\n\n");
                 }
             }
 
@@ -969,14 +969,14 @@ private static String extractClassDescription(String cleanedJavadoc) {
         // Extract description before @tags
         String description = extractJavadocDescription(textOnly);
         
-        // Limit to first 2-3 sentences or ~200 characters
-        if (description.length() > 200) {
-            int breakPoint = findBestBreakpoint(description, 100, 250);
+        // Limit to ~2000 characters
+        if (description.length() > 2000) {
+            int breakPoint = findBestBreakpoint(description, 1500, 2100);
             if (breakPoint != -1) {
                 description = description.substring(0, breakPoint + 1).trim();
             } else {
-                int lastSpace = description.lastIndexOf(' ', 200);
-                description = description.substring(0, lastSpace > 100 ? lastSpace : 200).trim() + "...";
+                int lastSpace = description.lastIndexOf(' ', 2000);
+                description = description.substring(0, lastSpace > 1500 ? lastSpace : 2000).trim() + "...";
             }
         }
         

From 20e13124c67376955265bb05b0b8b360a8e40667 Mon Sep 17 00:00:00 2001
From: wenyutang-ms 
Date: Mon, 10 Nov 2025 15:36:00 +0800
Subject: [PATCH 5/9] fix: update

---
 .../ext/core/parser/ContextResolver.java      | 130 ++----------------
 1 file changed, 8 insertions(+), 122 deletions(-)

diff --git a/jdtls.ext/com.microsoft.jdtls.ext.core/src/com/microsoft/jdtls/ext/core/parser/ContextResolver.java b/jdtls.ext/com.microsoft.jdtls.ext.core/src/com/microsoft/jdtls/ext/core/parser/ContextResolver.java
index 6df581bb..dc5dbb03 100644
--- a/jdtls.ext/com.microsoft.jdtls.ext.core/src/com/microsoft/jdtls/ext/core/parser/ContextResolver.java
+++ b/jdtls.ext/com.microsoft.jdtls.ext.core/src/com/microsoft/jdtls/ext/core/parser/ContextResolver.java
@@ -1049,8 +1049,8 @@ private static String convertHtmlEntities(String text) {
     }
 
     /**
-     * Extract detailed JavaDoc summary from method including @param, @return, and @throws tags.
-     * Returns a formatted string with the method description and parameter/return information.
+     * Extract method JavaDoc content directly for LLM consumption.
+     * Returns cleaned JavaDoc without artificial truncation - let LLM understand the full context.
      */
     private static String extractMethodJavaDocSummary(IMethod method) {
         try {
@@ -1066,122 +1066,15 @@ private static String extractMethodJavaDocSummary(IMethod method) {
                 return "";
             }
             
+            // Just clean and return - let LLM understand the full context
             String cleaned = cleanJavadocComment(rawJavadoc);
-            StringBuilder result = new StringBuilder();
-            
-            // Extract main description (first sentence)
-            String description = extractJavadocDescription(cleaned);
-            String firstSentence = getFirstSentenceOrLimit(description, 120);
-            if (isNotEmpty(firstSentence)) {
-                result.append(firstSentence);
-            }
-            
-            // === Medium Priority: Parse @param tags ===
-            List params = extractJavadocTag(cleaned, "@param");
-            if (!params.isEmpty()) {
-                result.append(" | Params: ");
-                for (int i = 0; i < params.size() && i < 3; i++) { // Limit to 3 params
-                    if (i > 0) result.append(", ");
-                    result.append(params.get(i));
-                }
-                if (params.size() > 3) {
-                    result.append("...");
-                }
-            }
-            
-            // === Medium Priority: Parse @return tag ===
-            List returns = extractJavadocTag(cleaned, "@return");
-            if (!returns.isEmpty()) {
-                String returnDesc = returns.get(0);
-                // Limit return description to 60 chars
-                if (returnDesc.length() > 60) {
-                    returnDesc = returnDesc.substring(0, 57) + "...";
-                }
-                result.append(" | Returns: ").append(returnDesc);
-            }
-            
-            // === Medium Priority: Parse @throws tags ===
-            List throwsTags = extractJavadocTag(cleaned, "@throws");
-            if (throwsTags.isEmpty()) {
-                throwsTags = extractJavadocTag(cleaned, "@exception");
-            }
-            if (!throwsTags.isEmpty()) {
-                result.append(" | Throws: ");
-                for (int i = 0; i < Math.min(throwsTags.size(), 2); i++) {
-                    if (i > 0) result.append(", ");
-                    String exceptionInfo = throwsTags.get(i);
-                    int spaceIndex = exceptionInfo.indexOf(' ');
-                    result.append(spaceIndex != -1 ? exceptionInfo.substring(0, spaceIndex) : exceptionInfo);
-                }
-                if (throwsTags.size() > 2) {
-                    result.append("...");
-                }
-            }
-            
-            // === High Priority: Mark deprecated methods ===
-            if (cleaned.contains("@deprecated")) {
-                result.append(result.length() > 0 ? " " : "").append("[DEPRECATED]");
-            }
-            
-            return result.toString();
+            return convertHtmlEntities(cleaned);
             
         } catch (Exception e) {
             return "";
         }
     }
     
-    /**
-     * Extract JavaDoc tags of a specific type (e.g., @param, @return, @throws).
-     * Returns a list of tag values (without the tag name itself).
-     * 
-     * @param cleanedJavadoc Cleaned JavaDoc text
-     * @param tagName Tag name to search for (e.g., "@param")
-     * @return List of tag values
-     */
-    private static List extractJavadocTag(String cleanedJavadoc, String tagName) {
-        List results = new ArrayList<>();
-        
-        if (cleanedJavadoc == null || cleanedJavadoc.isEmpty()) {
-            return results;
-        }
-        
-        String[] lines = cleanedJavadoc.split("\\n");
-        StringBuilder currentTag = null;
-        
-        for (String line : lines) {
-            String trimmed = line.trim();
-            
-            // Check if this line starts with the target tag
-            if (trimmed.startsWith(tagName + " ")) {
-                // Save previous tag if exists
-                if (currentTag != null) {
-                    results.add(currentTag.toString().trim());
-                }
-                // Start new tag (remove tag name)
-                currentTag = new StringBuilder(trimmed.substring(tagName.length() + 1).trim());
-            }
-            // Check if this line starts with any other tag
-            else if (trimmed.startsWith("@")) {
-                // Save previous tag if exists
-                if (currentTag != null) {
-                    results.add(currentTag.toString().trim());
-                    currentTag = null;
-                }
-            }
-            // Continuation of current tag
-            else if (currentTag != null && isNotEmpty(trimmed)) {
-                currentTag.append(" ").append(trimmed);
-            }
-        }
-        
-        // Don't forget the last tag
-        if (currentTag != null) {
-            results.add(currentTag.toString().trim());
-        }
-        
-        return results;
-    }
-
     /**
      * Extract the main description part from JavaDoc (before @tags)
      */
@@ -1276,7 +1169,8 @@ private static int findBestBreakpoint(String text, int minPos, int maxPos) {
     }
 
     /**
-     * Extract summary description from field JavaDoc, including @deprecated marking.
+     * Extract field JavaDoc content directly for LLM consumption.
+     * Returns cleaned JavaDoc without artificial truncation - let LLM understand the full context.
      */
     private static String extractFieldJavaDocSummary(org.eclipse.jdt.core.IField field) {
         try {
@@ -1292,16 +1186,10 @@ private static String extractFieldJavaDocSummary(org.eclipse.jdt.core.IField fie
                 return "";
             }
             
+            // Just clean and return - let LLM understand the full context
             String cleaned = cleanJavadocComment(rawJavadoc);
-            String description = extractJavadocDescription(cleaned);
-            String summary = getFirstSentenceOrLimit(description, 120);
-            
-            // === High Priority: Mark deprecated fields ===
-            if (cleaned.contains("@deprecated")) {
-                summary = summary.isEmpty() ? "[DEPRECATED]" : summary + " [DEPRECATED]";  
-            }
+            return convertHtmlEntities(cleaned);
             
-            return summary;
         } catch (Exception e) {
             return "";
         }
@@ -1321,8 +1209,6 @@ public static String generateFieldSignature(org.eclipse.jdt.core.IField field) {
         return generateFieldSignatureInternal(field, false);
     }
 
-
-
     /**
      * Convert JDT type signature to human-readable format
      */

From b6aa27d03a99e6a700eda4cf3d2ad5b3489253a8 Mon Sep 17 00:00:00 2001
From: wenyutang-ms 
Date: Mon, 10 Nov 2025 15:43:43 +0800
Subject: [PATCH 6/9] ci: update

---
 .../jdtls/ext/core/parser/ContextResolver.java       | 12 ------------
 1 file changed, 12 deletions(-)

diff --git a/jdtls.ext/com.microsoft.jdtls.ext.core/src/com/microsoft/jdtls/ext/core/parser/ContextResolver.java b/jdtls.ext/com.microsoft.jdtls.ext.core/src/com/microsoft/jdtls/ext/core/parser/ContextResolver.java
index dc5dbb03..3f853089 100644
--- a/jdtls.ext/com.microsoft.jdtls.ext.core/src/com/microsoft/jdtls/ext/core/parser/ContextResolver.java
+++ b/jdtls.ext/com.microsoft.jdtls.ext.core/src/com/microsoft/jdtls/ext/core/parser/ContextResolver.java
@@ -907,11 +907,6 @@ private static String extractRelevantJavaDocContent(org.eclipse.jdt.core.IType t
             if (isNotEmpty(description)) {
                 result.append("Description:\n").append(description).append("\n\n");
             }
-            
-            // === High Priority: Check for @deprecated tag ===
-            if (isDeprecated(cleanedJavadoc)) {
-                result.append("⚠️ DEPRECATED: This class is deprecated and should not be used in new code.\n\n");
-            }
 
             // === Extract code snippets ===
             // 1. Extract markdown code blocks (```...```)
@@ -982,13 +977,6 @@ private static String extractClassDescription(String cleanedJavadoc) {
         
         return description.trim();
     }
-    
-    /**
-     * Check if the JavaDoc contains @deprecated tag.
-     */
-    private static boolean isDeprecated(String cleanedJavadoc) {
-        return cleanedJavadoc != null && cleanedJavadoc.contains("@deprecated");
-    }
 
     /**
      * Clean up raw JavaDoc comment by removing comment markers and asterisks

From aa80feff8b7c9af03768e105d8baa5ffb49cc9e6 Mon Sep 17 00:00:00 2001
From: wenyutang-ms 
Date: Mon, 10 Nov 2025 16:08:11 +0800
Subject: [PATCH 7/9] pref: remove html tags

---
 .../ext/core/parser/ContextResolver.java      | 26 +++++++++++++++++++
 src/copilot/contextProvider.ts                |  4 ++-
 2 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/jdtls.ext/com.microsoft.jdtls.ext.core/src/com/microsoft/jdtls/ext/core/parser/ContextResolver.java b/jdtls.ext/com.microsoft.jdtls.ext.core/src/com/microsoft/jdtls/ext/core/parser/ContextResolver.java
index 3f853089..ab063ef0 100644
--- a/jdtls.ext/com.microsoft.jdtls.ext.core/src/com/microsoft/jdtls/ext/core/parser/ContextResolver.java
+++ b/jdtls.ext/com.microsoft.jdtls.ext.core/src/com/microsoft/jdtls/ext/core/parser/ContextResolver.java
@@ -900,6 +900,7 @@ private static String extractRelevantJavaDocContent(org.eclipse.jdt.core.IType t
             
             // Clean Javadoc comment for processing
             String cleanedJavadoc = cleanJavadocComment(rawJavadoc);
+            cleanedJavadoc = removeHtmlTags(cleanedJavadoc);
             cleanedJavadoc = convertHtmlEntities(cleanedJavadoc);
 
             // === High Priority: Extract class description text (first paragraph) ===
@@ -1036,6 +1037,29 @@ private static String convertHtmlEntities(String text) {
                    .replace("–", "-");
     }
 
+    /**
+     * Remove all HTML tags from text, keeping only plain text content.
+     * Preserves line breaks for block-level tags like 

,
,

. + */ + private static String removeHtmlTags(String text) { + if (text == null || text.isEmpty()) { + return text; + } + + // Replace block-level tags with line breaks + text = text.replaceAll("(?i)||]*>", "\n"); + + // Remove all remaining HTML tags + text = text.replaceAll("<[^>]+>", ""); + + // Clean up whitespace: collapse spaces, trim lines, limit line breaks + text = text.replaceAll("[ \\t]+", " ") + .replaceAll(" *\\n *", "\n") + .replaceAll("\\n{3,}", "\n\n"); + + return text.trim(); + } + /** * Extract method JavaDoc content directly for LLM consumption. * Returns cleaned JavaDoc without artificial truncation - let LLM understand the full context. @@ -1056,6 +1080,7 @@ private static String extractMethodJavaDocSummary(IMethod method) { // Just clean and return - let LLM understand the full context String cleaned = cleanJavadocComment(rawJavadoc); + cleaned = removeHtmlTags(cleaned); return convertHtmlEntities(cleaned); } catch (Exception e) { @@ -1176,6 +1201,7 @@ private static String extractFieldJavaDocSummary(org.eclipse.jdt.core.IField fie // Just clean and return - let LLM understand the full context String cleaned = cleanJavadocComment(rawJavadoc); + cleaned = removeHtmlTags(cleaned); return convertHtmlEntities(cleaned); } catch (Exception e) { diff --git a/src/copilot/contextProvider.ts b/src/copilot/contextProvider.ts index 4857b8e6..064662d0 100644 --- a/src/copilot/contextProvider.ts +++ b/src/copilot/contextProvider.ts @@ -44,6 +44,7 @@ export async function registerCopilotContextProviders( "status": "succeeded", "installCount": installCount }); + console.log(`Registered Java Copilot context provider on ${installCount} API(s).`); } catch (error) { const errorMessage = (error as Error).message || "unknown_error"; @@ -104,7 +105,7 @@ async function resolveJavaContext(request: ResolveRequest, copilotCancel: vscode ); JavaContextProviderUtils.checkCancellation(copilotCancel); items.push(...projectDependencyItems); - + JavaContextProviderUtils.checkCancellation(copilotCancel); // Resolve local imports and convert to context items @@ -113,6 +114,7 @@ async function resolveJavaContext(request: ResolveRequest, copilotCancel: vscode copilotCancel, JavaContextProviderUtils.checkCancellation ); + console.dir(localImportItems) JavaContextProviderUtils.checkCancellation(copilotCancel); items.push(...localImportItems); } catch (error: any) { From ad00330e1ac9aaf572e3e093c483e73df2b53193 Mon Sep 17 00:00:00 2001 From: wenyutang-ms Date: Mon, 10 Nov 2025 16:10:33 +0800 Subject: [PATCH 8/9] perf: remove useless code --- src/copilot/contextProvider.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/copilot/contextProvider.ts b/src/copilot/contextProvider.ts index 064662d0..071622aa 100644 --- a/src/copilot/contextProvider.ts +++ b/src/copilot/contextProvider.ts @@ -44,7 +44,6 @@ export async function registerCopilotContextProviders( "status": "succeeded", "installCount": installCount }); - console.log(`Registered Java Copilot context provider on ${installCount} API(s).`); } catch (error) { const errorMessage = (error as Error).message || "unknown_error"; @@ -114,7 +113,6 @@ async function resolveJavaContext(request: ResolveRequest, copilotCancel: vscode copilotCancel, JavaContextProviderUtils.checkCancellation ); - console.dir(localImportItems) JavaContextProviderUtils.checkCancellation(copilotCancel); items.push(...localImportItems); } catch (error: any) { From 9ff1df0c7f8e4984e9df6f3e61f7ad9b77396d1a Mon Sep 17 00:00:00 2001 From: wenyutang-ms Date: Mon, 10 Nov 2025 16:11:06 +0800 Subject: [PATCH 9/9] perf: remove useless code --- src/copilot/contextProvider.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/copilot/contextProvider.ts b/src/copilot/contextProvider.ts index 071622aa..4857b8e6 100644 --- a/src/copilot/contextProvider.ts +++ b/src/copilot/contextProvider.ts @@ -104,7 +104,7 @@ async function resolveJavaContext(request: ResolveRequest, copilotCancel: vscode ); JavaContextProviderUtils.checkCancellation(copilotCancel); items.push(...projectDependencyItems); - + JavaContextProviderUtils.checkCancellation(copilotCancel); // Resolve local imports and convert to context items