Skip to content

Commit 16b7b13

Browse files
datho7561mickaelistria
authored andcommitted
Assorted completion bug fixes
- Don't complete enum constant declarations - Better handling of completion of qualified `super` and `this` (take into account if you're in an interface) - Improve `JavacConverter` to handle "field access" split across two lines as in `CompletionTests.testBug573632` (signatures don't match properly so it's not passing) Should fix 4 and improve many more Signed-off-by: David Thompson <[email protected]>
1 parent 9cd4136 commit 16b7b13

File tree

3 files changed

+40
-14
lines changed

3 files changed

+40
-14
lines changed

org.eclipse.jdt.core.javac/src/org/eclipse/jdt/core/dom/JavacConverter.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1270,6 +1270,11 @@ private Expression convertExpressionImpl(JCExpression javac) {
12701270
// when there are syntax errors where the statement is not completed.
12711271
qualifiedName = this.ast.newSimpleName(FAKE_IDENTIFIER);
12721272
qualifiedName.setFlags(ASTNode.RECOVERED);
1273+
} else {
1274+
int qualifiedOffset = this.rawText.indexOf(qualifiedName.toString(), qualifierName.getStartPosition() + qualifierName.getLength() + 1);
1275+
if (qualifiedOffset != -1) {
1276+
qualifiedName.setSourceRange(qualifiedOffset, qualifiedName.toString().length());
1277+
}
12731278
}
12741279
QualifiedName res = this.ast.newQualifiedName(qualifierName, qualifiedName);
12751280
commonSettings(res, javac);

org.eclipse.jdt.core.javac/src/org/eclipse/jdt/internal/codeassist/DOMCompletionEngine.java

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@
8686
import org.eclipse.jdt.core.dom.ContinueStatement;
8787
import org.eclipse.jdt.core.dom.DoStatement;
8888
import org.eclipse.jdt.core.dom.EnhancedForStatement;
89+
import org.eclipse.jdt.core.dom.EnumConstantDeclaration;
8990
import org.eclipse.jdt.core.dom.EnumDeclaration;
9091
import org.eclipse.jdt.core.dom.Expression;
9192
import org.eclipse.jdt.core.dom.ExpressionMethodReference;
@@ -282,17 +283,7 @@ public Stream<CompletionProposal> toProposals() {
282283
public Stream<CompletionProposal> toProposals(boolean expectedOnly) {
283284

284285
// Needed to tell if `this` should be used
285-
List<ITypeBinding> parentTypeBinding = new ArrayList<>();
286-
ASTNode cursor = DOMCompletionEngine.this.toComplete;
287-
while (DOMCompletionUtils.findParentTypeDeclaration(cursor) != null) {
288-
ASTNode parentTypeDeclaration = DOMCompletionUtils.findParentTypeDeclaration(cursor);
289-
if (parentTypeDeclaration instanceof AbstractTypeDeclaration typeDecl) {
290-
parentTypeBinding.add(typeDecl.resolveBinding());
291-
} else {
292-
parentTypeBinding.add(((AnonymousClassDeclaration)parentTypeDeclaration).resolveBinding());
293-
}
294-
cursor = parentTypeDeclaration.getParent();
295-
}
286+
List<ITypeBinding> parentTypeBinding = DOMCompletionUtils.getParentTypeDeclarations(DOMCompletionEngine.this.toComplete);
296287

297288
return all() //
298289
.filter(binding -> pattern.matchesName(prefix.toCharArray(), binding.getName().toCharArray())) //
@@ -743,6 +734,7 @@ public void complete(org.eclipse.jdt.internal.compiler.env.ICompilationUnit sour
743734
|| simpleName.getParent() instanceof ContinueStatement
744735
|| simpleName.getParent() instanceof MarkerAnnotation
745736
|| simpleName.getParent() instanceof AnnotationTypeMemberDeclaration
737+
|| simpleName.getParent() instanceof EnumConstantDeclaration
746738
|| ((simpleName.getLocationInParent() == SwitchCase.EXPRESSIONS2_PROPERTY || simpleName.getLocationInParent() == SwitchCase.EXPRESSION_PROPERTY) && simpleName.getParent() instanceof SwitchCase)) {
747739
if (!this.toComplete.getLocationInParent().getId().equals(QualifiedName.QUALIFIER_PROPERTY.getId())) {
748740
context = this.toComplete.getParent();
@@ -956,6 +948,8 @@ public void complete(org.eclipse.jdt.internal.compiler.env.ICompilationUnit sour
956948
case SwitchCase _:
957949
completeSwitchCase();
958950
break;
951+
case EnumConstantDeclaration _:
952+
completeEnumConstantDeclaration();
959953
default:
960954
// Fall back to default completion strategy (accessible bindings + type search)
961955
}
@@ -1084,6 +1078,10 @@ public void complete(org.eclipse.jdt.internal.compiler.env.ICompilationUnit sour
10841078
}
10851079
}
10861080

1081+
private void completeEnumConstantDeclaration() {
1082+
this.suggestDefaultCompletions = false;
1083+
}
1084+
10871085
private void completeSwitchCase() {
10881086
// find the enum if there is one
10891087
ITypeBinding firstEnumType = null;
@@ -2194,16 +2192,23 @@ private void completeQualifiedName(QualifiedName qualifiedName) throws JavaModel
21942192
}
21952193
if (!(this.toComplete instanceof Type)) {
21962194
ASTNode parentTypeDeclaration = DOMCompletionUtils.findParentTypeDeclaration(qualifiedName);
2195+
List<ITypeBinding> parentTypeDeclarations = DOMCompletionUtils.getParentTypeDeclarations(this.toComplete);
21972196
MethodDeclaration methodDecl = (MethodDeclaration)DOMCompletionUtils.findParent(this.toComplete, new int[] { ASTNode.METHOD_DECLARATION });
21982197
if (parentTypeDeclaration != null && methodDecl != null && (methodDecl.getModifiers() & Flags.AccStatic) == 0) {
21992198
if (completionContext.getCurrentTypeBinding().isSubTypeCompatible(qualifierTypeBinding)) {
2200-
if (!isFailedMatch(this.prefix.toCharArray(), Keywords.THIS)) {
2199+
if (parentTypeDeclarations.stream().anyMatch(parent -> parent.getKey().equals(qualifierTypeBinding.getKey()))
2200+
&& !isFailedMatch(this.prefix.toCharArray(), Keywords.THIS)) {
22012201
CompletionProposal res = createKeywordProposal(Keywords.THIS, startPos, endPos);
22022202
res.setRelevance(res.getRelevance() + RelevanceConstants.R_NON_INHERITED);
22032203
this.requestor.accept(res);
22042204
}
2205-
if (!isFailedMatch(this.prefix.toCharArray(), Keywords.SUPER)) {
2206-
this.requestor.accept(createKeywordProposal(Keywords.SUPER, startPos, endPos));
2205+
if ((!completionContext.getCurrentTypeBinding().isInterface() || !completionContext.getCurrentTypeBinding().getKey().equals(qualifierTypeBinding.getKey()))
2206+
&& !isFailedMatch(this.prefix.toCharArray(), Keywords.SUPER)) {
2207+
CompletionProposal res = createKeywordProposal(Keywords.SUPER, startPos, endPos);
2208+
if (!completionContext.getCurrentTypeBinding().getKey().equals(qualifierTypeBinding.getKey())) {
2209+
res.setRelevance(res.getRelevance() + RelevanceConstants.R_NON_INHERITED);
2210+
}
2211+
this.requestor.accept(res);
22072212
}
22082213
}
22092214
if (!isFailedMatch(this.prefix.toCharArray(), Keywords.CLASS)) {

org.eclipse.jdt.core.javac/src/org/eclipse/jdt/internal/codeassist/DOMCompletionUtils.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
import org.eclipse.jdt.core.WorkingCopyOwner;
2929
import org.eclipse.jdt.core.dom.ASTNode;
3030
import org.eclipse.jdt.core.dom.ASTVisitor;
31+
import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
32+
import org.eclipse.jdt.core.dom.AnonymousClassDeclaration;
3133
import org.eclipse.jdt.core.dom.Expression;
3234
import org.eclipse.jdt.core.dom.ExpressionMethodReference;
3335
import org.eclipse.jdt.core.dom.FieldAccess;
@@ -316,4 +318,18 @@ public static TrueFalseCasts collectTrueFalseCasts(Expression e, IVariableBindin
316318
}
317319
}
318320

321+
public static List<ITypeBinding> getParentTypeDeclarations(ASTNode cursor) {
322+
List<ITypeBinding> parentTypeBinding = new ArrayList<>();
323+
while (DOMCompletionUtils.findParentTypeDeclaration(cursor) != null) {
324+
ASTNode parentTypeDeclaration = DOMCompletionUtils.findParentTypeDeclaration(cursor);
325+
if (parentTypeDeclaration instanceof AbstractTypeDeclaration typeDecl) {
326+
parentTypeBinding.add(typeDecl.resolveBinding());
327+
} else {
328+
parentTypeBinding.add(((AnonymousClassDeclaration)parentTypeDeclaration).resolveBinding());
329+
}
330+
cursor = parentTypeDeclaration.getParent();
331+
}
332+
return parentTypeBinding;
333+
}
334+
319335
}

0 commit comments

Comments
 (0)