Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Content assist does not activate, inside if() within a switch #1953

Merged
merged 3 commits into from
Mar 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading