Skip to content

Commit

Permalink
Content assist does not activate, inside if() within a switch (eclips…
Browse files Browse the repository at this point in the history
…e-jdt#1953)

fixes eclipse-jdt#1561

---------

Co-authored-by: Gayan Perera <[email protected]>
  • Loading branch information
stephan-herrmann and gayanper committed Sep 7, 2024
1 parent 73119ee commit 403b855
Show file tree
Hide file tree
Showing 3 changed files with 176 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -983,4 +983,147 @@ public void testBugGH1095_2() throws Exception {
"implementMe[METHOD_DECLARATION]{public void implementMe(), LBaseInterface;, ()V, implementMe, null, " + (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_CASE + R_ABSTRACT_METHOD + R_UNQUALIFIED + R_NON_RESTRICTED) + "}",
requestor.getResults());
}

public void testGH1561_CompletionInIfConditionInsideASwitchStatement() throws JavaModelException {
this.workingCopies = new ICompilationUnit[1];
this.workingCopies[0] = getWorkingCopy("/Completion/src/SwitchIf.java",
"""
public class SwitchIf {
final String name = "test";
boolean namedFlag;
enum Type { A }
private void foo(Type input) {
switch (input) {
case A:
if (nam)
break;
}
}
}
""");
CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true, true, true, false);
String str = this.workingCopies[0].getSource();
String completeBehind = "if (nam";
int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
assertResults(
"name[FIELD_REF]{name, LSwitchIf;, Ljava.lang.String;, null, null, name, null, [165, 168], "
+ (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_CASE + R_UNQUALIFIED + R_NON_RESTRICTED) + "}\n" +
"namedFlag[FIELD_REF]{namedFlag, LSwitchIf;, Z, null, null, namedFlag, null, [165, 168], "
+ (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_CASE + R_UNQUALIFIED + R_NON_RESTRICTED + R_EXACT_EXPECTED_TYPE)+"}",
requestor.getResults());
}

public void testGH1561_CompletionInWhileConditionInsideASwitchStatement() throws JavaModelException {
this.workingCopies = new ICompilationUnit[1];
this.workingCopies[0] = getWorkingCopy("/Completion/src/SwitchIf.java",
"""
public class SwitchIf {
final String name = "test";
enum Type { A }
private void foo(Type input) {
switch (input) {
case A:
while (nam)
break;
}
}
}
""");
CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true, true, true, false);
String str = this.workingCopies[0].getSource();
String completeBehind = "while (nam";
int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
assertResults(
"name[FIELD_REF]{name, LSwitchIf;, Ljava.lang.String;, null, null, name, null, [147, 150], "
+ (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_CASE + R_UNQUALIFIED + R_NON_RESTRICTED) + "}",
requestor.getResults());
}

public void testGH1561_CompletionInForConditionInsideASwitchStatement() throws JavaModelException {
this.workingCopies = new ICompilationUnit[1];
this.workingCopies[0] = getWorkingCopy("/Completion/src/SwitchIf.java",
"""
public class SwitchIf {
final String name = "test";
enum Type { A }
private void foo(Type input) {
switch (input) {
case A:
for (int i = 0; i < nam)
break;
}
}
}
""");
CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true, true, true, false);
String str = this.workingCopies[0].getSource();
String completeBehind = "for (int i = 0; i < nam";
int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
assertResults(
"name[FIELD_REF]{name, LSwitchIf;, Ljava.lang.String;, null, null, name, null, [160, 163], "
+ (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_CASE + R_UNQUALIFIED + R_NON_RESTRICTED) + "}",
requestor.getResults());
}

public void testGH1561_CompletionInSwitchInsideASwitchStatement() throws JavaModelException {
this.workingCopies = new ICompilationUnit[1];
this.workingCopies[0] = getWorkingCopy("/Completion/src/SwitchIf.java",
"""
public class SwitchIf {
final String name = "test";
enum Type { A }
private void foo(Type input) {
switch (input) {
case A:
switch (nam
break;
}
}
}
""");
CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true, true, true, false);
String str = this.workingCopies[0].getSource();
String completeBehind = "switch (nam";
int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
assertResults(
"name[FIELD_REF]{name, LSwitchIf;, Ljava.lang.String;, null, null, name, null, [148, 151], "
+ (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_CASE + R_UNQUALIFIED + R_NON_RESTRICTED) + "}",
requestor.getResults());
}

public void testGH1561_CompletionInForInsideASwitchStatement() throws JavaModelException {
this.workingCopies = new ICompilationUnit[1];
this.workingCopies[0] = getWorkingCopy("/Completion/src/SwitchIf.java",
"""
public class SwitchIf {
final String name = "test";
enum Type { A }
private void foo(Type input) {
switch (input) {
case A:
for (int i = 0; nam)
break;
}
}
private boolean nameContains(String name) {
return false;
}
}
""");
CompletionTestsRequestor2 requestor = new CompletionTestsRequestor2(true, true, true, false);
String str = this.workingCopies[0].getSource();
String completeBehind = "for (int i = 0; nam";
int cursorLocation = str.lastIndexOf(completeBehind) + completeBehind.length();
this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);
assertResults("name[FIELD_REF]{name, LSwitchIf;, Ljava.lang.String;, null, null, name, null, [156, 159], "
+ (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_CASE + R_UNQUALIFIED + R_NON_RESTRICTED) + "}\n"
+ "nameContains[METHOD_REF]{nameContains(), LSwitchIf;, (Ljava.lang.String;)Z, null, null, nameContains, (name), [156, 159], "
+ (R_DEFAULT + R_RESOLVED + R_INTERESTING + R_CASE + R_UNQUALIFIED + R_NON_RESTRICTED
+ R_EXACT_EXPECTED_TYPE)
+ "}", requestor.getResults());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5950,8 +5950,10 @@ public void testBug574823_completeOn_methodInvocationWithParams_inIfConidtion_in
this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);

String result = requestor.getResults();
assertTrue(String.format("Result doesn't contain method forEach (%s)", result),
result.contains("forEach[METHOD_REF]{forEach(), Ljava.lang.Iterable<Ljava.lang.String;>;, (Ljava.util.function.Consumer<-Ljava.lang.String;>;)V, null, null, forEach, (arg0), replace[149, 149], token[149, 149], 60}"));
int relevance = R_DEFAULT + R_RESOLVED + R_INTERESTING + R_CASE + R_VOID + R_NON_STATIC + R_NON_RESTRICTED;
assertTrue(String.format("Result doesn't contain method forEach (%s)", result),
result.contains("forEach[METHOD_REF]{forEach(), Ljava.lang.Iterable<Ljava.lang.String;>;, (Ljava.util.function.Consumer<-Ljava.lang.String;>;)V," +
" null, null, forEach, (arg0), replace[149, 149], token[149, 149], "+relevance+"}"));
}
public void testBug574823_completeOn_methodInvocationWithParams_inIfConidtion_insideIf_followedByChainedStatment() throws Exception {
this.workingCopies = new ICompilationUnit[1];
Expand All @@ -5974,8 +5976,10 @@ public void testBug574823_completeOn_methodInvocationWithParams_inIfConidtion_in
this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);

String result = requestor.getResults();
assertTrue(String.format("Result doesn't contain method forEach (%s)", result),
result.contains("forEach[METHOD_REF]{forEach(), Ljava.lang.Iterable<Ljava.lang.String;>;, (Ljava.util.function.Consumer<-Ljava.lang.String;>;)V, null, null, forEach, (arg0), replace[149, 149], token[149, 149], 60}"));
int relevance = R_DEFAULT + R_RESOLVED + R_INTERESTING + R_CASE + R_VOID + R_NON_STATIC + R_NON_RESTRICTED;
assertTrue(String.format("Result doesn't contain method forEach (%s)", result),
result.contains("forEach[METHOD_REF]{forEach(), Ljava.lang.Iterable<Ljava.lang.String;>;, (Ljava.util.function.Consumer<-Ljava.lang.String;>;)V," +
" null, null, forEach, (arg0), replace[149, 149], token[149, 149], "+relevance+"}"));
}
public void testBug574823_completeOn_methodInvocationWithParams_inWhileConidtion_insideWhileBlock_followedByChainedStatment() throws Exception {
this.workingCopies = new ICompilationUnit[1];
Expand All @@ -5999,8 +6003,10 @@ public void testBug574823_completeOn_methodInvocationWithParams_inWhileConidtion
this.workingCopies[0].codeComplete(cursorLocation, requestor, this.wcOwner);

String result = requestor.getResults();
assertTrue(String.format("Result doesn't contain method forEach (%s)", result),
result.contains("forEach[METHOD_REF]{forEach(), Ljava.lang.Iterable<Ljava.lang.String;>;, (Ljava.util.function.Consumer<-Ljava.lang.String;>;)V, null, null, forEach, (arg0), replace[152, 152], token[152, 152], 60}"));
int relevance = R_DEFAULT + R_RESOLVED + R_INTERESTING + R_CASE + R_VOID + R_NON_STATIC + R_NON_RESTRICTED;
assertTrue(String.format("Result doesn't contain method forEach (%s)", result),
result.contains("forEach[METHOD_REF]{forEach(), Ljava.lang.Iterable<Ljava.lang.String;>;, (Ljava.util.function.Consumer<-Ljava.lang.String;>;)V," +
" null, null, forEach, (arg0), replace[152, 152], token[152, 152], "+relevance+"}"));
}
public void testBug574823_completeOn_methodInvocationWithParams_inIfConidtionWithExpression_insideIfBlock_followedByChainedStatment() throws Exception {
this.workingCopies = new ICompilationUnit[1];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ protected boolean visitNode(ASTNode node) {
return !this.found;
}
}

/** Sentinel that signals when searchNode was found as a child of a potential parent but in an unsupported location of it. */
private static final ASTNode NOT_A_PARENT = new NullLiteral(0, 0);

public static boolean findAny(CompilationUnitDeclaration unit, ASTNode searchFor) {
FindAny visitor = new FindAny(searchFor);
unit.traverse(visitor, (CompilationUnitScope)null, false);
Expand Down Expand Up @@ -82,6 +86,8 @@ public boolean containsCompletionNode() {
}

public ASTNode getCompletionNodeParent() {
if (this.parent == NOT_A_PARENT)
return null;
return this.parent;
}
public Expression getCompletionNodeOuterExpression() {
Expand Down Expand Up @@ -172,6 +178,12 @@ public void endVisit(GuardedPattern guardedPattern, BlockScope scope) {
@Override
public void endVisit(IfStatement ifStatement, BlockScope scope) {
this.interestingEnclosings.pop();
endVisit(ifStatement);
if (this.parent == ifStatement && this.searchedNode != ifStatement.condition) {
// searchNode was found as a child of the ifStatement, but in a wrong position (only condition is supported)
// Remove the unwanted parent, but at the same time signal that we should not look for a parent in any enclosing ASTNode:
this.parent = NOT_A_PARENT;
}
}
@Override
public void endVisit(InstanceOfExpression instanceOfExpression, BlockScope scope) {
Expand Down Expand Up @@ -299,6 +311,15 @@ public void endVisit(ConstructorDeclaration constructorDeclaration, ClassScope s
throw new StopTraversal(); // don't associate with out-of-scope outer expression
}
@Override
public void endVisit(WhileStatement whileStatement, BlockScope scope) {
endVisit(whileStatement);
if (this.parent == whileStatement && this.searchedNode != whileStatement.condition) {
// searchNode was found as a child of the whileStatement, but in a wrong position (only condition is supported)
// Remove the unwanted parent, but at the same time signal that we should not look for a parent in any enclosing ASTNode:
this.parent = NOT_A_PARENT;
}
}
@Override
public boolean visit(AllocationExpression allocationExpression, BlockScope scope) {
return this.visit(allocationExpression);
}
Expand Down

0 comments on commit 403b855

Please sign in to comment.