Skip to content

Commit

Permalink
Use resolved JavaElement from binding for CompletionContext.enclosing
Browse files Browse the repository at this point in the history
  • Loading branch information
mickaelistria committed Dec 16, 2024
1 parent 525cd23 commit 44f1a95
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,11 @@
import com.sun.tools.javac.api.JavacTaskImpl;
import com.sun.tools.javac.api.JavacTrees;
import com.sun.tools.javac.code.Attribute;
import com.sun.tools.javac.code.Attribute.Compound;
import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.code.Symtab;
import com.sun.tools.javac.code.TypeTag;
import com.sun.tools.javac.code.Types;
import com.sun.tools.javac.code.Attribute.Compound;
import com.sun.tools.javac.code.Symbol.ClassSymbol;
import com.sun.tools.javac.code.Symbol.MethodSymbol;
import com.sun.tools.javac.code.Symbol.ModuleSymbol;
Expand All @@ -57,7 +60,6 @@
import com.sun.tools.javac.code.Symbol.TypeSymbol;
import com.sun.tools.javac.code.Symbol.TypeVariableSymbol;
import com.sun.tools.javac.code.Symbol.VarSymbol;
import com.sun.tools.javac.code.Symtab;
import com.sun.tools.javac.code.Type.ArrayType;
import com.sun.tools.javac.code.Type.ClassType;
import com.sun.tools.javac.code.Type.ErrorType;
Expand All @@ -69,9 +71,8 @@
import com.sun.tools.javac.code.Type.ModuleType;
import com.sun.tools.javac.code.Type.PackageType;
import com.sun.tools.javac.code.Type.TypeVar;
import com.sun.tools.javac.code.TypeTag;
import com.sun.tools.javac.code.Types;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.TreeInfo;
import com.sun.tools.javac.tree.JCTree.JCAnnotatedType;
import com.sun.tools.javac.tree.JCTree.JCAnnotation;
import com.sun.tools.javac.tree.JCTree.JCArrayTypeTree;
Expand All @@ -95,7 +96,6 @@
import com.sun.tools.javac.tree.JCTree.JCTypeParameter;
import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
import com.sun.tools.javac.tree.JCTree.JCWildcard;
import com.sun.tools.javac.tree.TreeInfo;
import com.sun.tools.javac.util.Context;

/**
Expand Down Expand Up @@ -378,7 +378,12 @@ public IBinding getBinding(final Symbol owner, final com.sun.tools.javac.code.Ty
} else if (owner instanceof TypeSymbol typeSymbol) {
return getTypeBinding(isTypeOfType(type) ? type : typeSymbol.type);
} else if (owner instanceof final MethodSymbol other) {
return getMethodBinding(type instanceof com.sun.tools.javac.code.Type.MethodType methodType ? methodType : owner.type.asMethodType(), other, null, false);
var methodType = type instanceof com.sun.tools.javac.code.Type.MethodType aMethodType ? aMethodType :
owner.type != null ? owner.type.asMethodType() :
null;
if (methodType != null) {
return getMethodBinding(methodType, other, null, false);
}
} else if (owner instanceof final VarSymbol other) {
return getVariableBinding(other);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ class DOMCompletionContext extends CompletionContext {
: previousNodeBeforeWhitespaces; // use previous node
this.expectedTypes = new ExpectedTypes(assistOptions, this.node, offset);
this.token = tokenBefore(cuBuffer).toCharArray();
this.enclosingElement = computeEnclosingElement(modelUnit);
this.enclosingElement = computeEnclosingElement(domUnit, modelUnit);
this.bindingsAcquirer = bindings::stream;
this.isJustAfterStringLiteral = this.node instanceof StringLiteral && this.node.getLength() > 1 && this.offset >= node.getStartPosition() + node.getLength() && cuBuffer.getChar(this.offset - 1) == '"';
}
Expand All @@ -84,16 +84,51 @@ private String tokenBefore(IBuffer cuBuffer) {
return builder.toString();
}

private IJavaElement computeEnclosingElement(ICompilationUnit modelUnit) {
private IJavaElement computeEnclosingElement(CompilationUnit domUnit, ICompilationUnit modelUnit) {
IJavaElement enclosingElement = modelUnit;
try {
if (modelUnit == null)
return null;
IJavaElement enclosingElement = modelUnit.getElementAt(this.offset);
return enclosingElement == null ? modelUnit : enclosingElement;
enclosingElement = modelUnit.getElementAt(this.offset);
} catch (JavaModelException e) {
ILog.get().error(e.getMessage(), e);
return null;
}
if (enclosingElement == null) {
return modelUnit;
}
// then refine to get "resolved" element from the matching binding
// pitfall: currently resolve O(depth(node)) bindings while we can
// most likely find a O(1) solution
ASTNode node = NodeFinder.perform(domUnit, this.offset, 0);
while (node != null) {
IBinding binding = resolveBindingForContext(node);
if (binding != null) {
IJavaElement bindingBasedJavaElement = binding.getJavaElement();
if (enclosingElement.equals(bindingBasedJavaElement)) {
return bindingBasedJavaElement;
}
}
node = node.getParent();
}
return enclosingElement;
}

private IBinding resolveBindingForContext(ASTNode node) {
var res = DOMCodeSelector.resolveBinding(node);
if (res != null) {
return res;
}
// Some declaration types are intentionally skipped by
// DOMCodeSelector.resolveBinding() as they're not
// expected by `codeSelect` add them here
if (node instanceof TypeDeclaration typeDecl) {
return typeDecl.resolveBinding();
}
if (node instanceof MethodDeclaration methodDecl) {
return methodDecl.resolveBinding();
}
if (node instanceof VariableDeclaration varDecl) {
return varDecl.resolveBinding();
}
return null;
}

@Override
Expand Down

0 comments on commit 44f1a95

Please sign in to comment.