drccrd commented on code in PR #3965:
URL: 
https://github.com/apache/incubator-kie-tools/pull/3965#discussion_r3843605163


##########
packages/drools-lsp/drools-completion/src/main/java/org/drools/completion/DRLCompletionHelper.java:
##########
@@ -208,6 +250,160 @@ private static List<CompletionItem> 
getFieldCompletionItems(DRL10Parser.Compilat
         return fieldItems(memberIndex.membersOf(fqcn));
     }
 
+    /**
+     * The dot-separated segments preceding a caret that sits immediately 
after a
+     * dot ({@code $ref.order.|} → {@code [$ref, order]}), or {@code null} 
when the
+     * caret follows something else. A numeric head is a decimal literal being
+     * typed, not a path.
+     */
+    private static String[] dottedChainBeforeCaret(String text, Position 
caret) {
+        if (text == null || caret == null) {
+            return null;
+        }
+        String[] lines = text.split("\n", -1);
+        int row = caret.getLine();
+        if (row < 0 || row >= lines.length) {
+            return null;
+        }
+        String line = lines[row];
+        int col = Math.min(caret.getCharacter(), line.length());
+        if (col == 0 || line.charAt(col - 1) != '.') {
+            return null;
+        }
+        int start = col - 1;
+        while (start > 0 && isChainChar(line.charAt(start - 1))) {
+            start--;
+        }
+        String path = line.substring(start, col - 1);
+        if (path.isEmpty() || path.endsWith(".") || 
Character.isDigit(path.charAt(0))) {
+            return null;
+        }
+        return path.split("\\.", -1);
+    }
+
+    private static boolean isChainChar(char c) {
+        return Character.isLetterOrDigit(c) || c == '_' || c == '$' || c == 
'.';
+    }
+
+    /**
+     * Member items for a dotted path the caret sits at the end of. The head 
is a
+     * binding ({@code $p.}), a field of the enclosing pattern's type ({@code 
ref.}
+     * inside {@code Fact(...)}), or a type name ({@code Status.}); the 
remaining
+     * segments are fields. Every hop goes through the same walker the 
bindings and
+     * hover use, so all three agree on what a path resolves to.
+     */
+    /**
+     * Completion items for the members of the type the chain resolves to, or
+     * {@code null} when the chain's head names no type the document knows — a
+     * qualified name rather than a member access. An empty list means the path
+     * did resolve and simply has no members to offer, which is an answer: 
after
+     * a dot nothing but a member is legal.
+     */
+    private static List<CompletionItem> memberItemsForChain(String[] chain, 
String text, Position caret,
+                                                            
DRL10Parser.CompilationUnitContext compilationUnit,
+                                                            int 
caretTokenIndex, ClassIndex classIndex,
+                                                            ClassMemberIndex 
memberIndex, Path documentPath,
+                                                            Map<Path, String> 
openFiles) {
+        if (compilationUnit == null) {
+            return null;
+        }
+        Map<String, DeclaredType> typeIndex = DRLWorkspaceTypeIndex.build(
+                
DRLDeclaredTypeParser.extractFromCompilationUnit(compilationUnit), 
documentPath, openFiles);
+
+        String head = chain[0];
+        String rootType;
+        int firstFieldSegment = 1;
+        if (head.startsWith("$")) {
+            rootType = LhsBindingResolver.resolveAt(text, 
DRLHoverHelper.positionToOffset(text, caret), typeIndex)
+                    .get(head.substring(1));
+        } else if (!head.isEmpty() && Character.isUpperCase(head.charAt(0))) {
+            rootType = head;
+        } else {
+            // A bare lower-case head is a field of the pattern the caret is 
in.
+            rootType = enclosingPatternTypeFromText(text, 
DRLHoverHelper.positionToOffset(text, caret));
+            firstFieldSegment = 0;
+        }
+        if (rootType == null || rootType.isEmpty()) {
+            // The head names no type the document knows, so this dot is not a
+            // member access at all — a qualified name, most likely.
+            return null;
+        }
+
+        String resolved = rootType.substring(rootType.lastIndexOf('.') + 1);
+        if (firstFieldSegment < chain.length) {
+            String path = String.join(".", Arrays.copyOfRange(chain, 
firstFieldSegment, chain.length));
+            resolved = LhsBindingResolver.resolvePath(
+                    LhsBindingResolver.typeOrClasspath(resolved, typeIndex), 
path, typeIndex);

Review Comment:
   Good catch - fixed in 4faab7fac2436ae1a76ea871c8de52a218b5d82b



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to