diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests12To15.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests12To15.java index f05551545fe..d1624bbfa7a 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests12To15.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests12To15.java @@ -916,4 +916,43 @@ public void testBug577508_4() throws JavaModelException { elements ); } +// https://github.com/eclipse-jdt/eclipse.jdt.core/issues/1278 +// Wrong method redirect +public void testGH1278() throws JavaModelException { + this.wc = getWorkingCopy("/Resolve15/src/TestSelect.java", + "public class TestSelect {\n" + + " class Integer {}\n" + + " class Double {}\n" + + "\n" + + " public void foo(String s) {\n" + + "\n" + + " }\n" + + "\n" + + " public void foo(Integer i) {\n" + + "\n" + + " }\n" + + "\n" + + " public void foo(Double d) {\n" + + "\n" + + " }\n" + + "\n" + + " public void foo2(Integer i) {\n" + + " Object test = 1d;\n" + + " if (test instanceof Double test2) {\n" + + " foo(test2);\n" + + " }\n" + + " }\n" + + "\n" + + "}\n"); + String str = this.wc.getSource(); + String selection = "foo"; + int start = str.lastIndexOf(selection); + int length = selection.length(); + IJavaElement[] elements = this.wc.codeSelect(start, length); + assertElementsEqual( + "Unexpected elements", + "foo(Double) [in TestSelect [in [Working copy] TestSelect.java [in [in src [in Resolve15]]]]]", + elements + ); +} } diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionParser.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionParser.java index 1013efbf702..d8187a0df5d 100644 --- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionParser.java +++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/select/SelectionParser.java @@ -35,6 +35,7 @@ import org.eclipse.jdt.internal.compiler.ast.Annotation; import org.eclipse.jdt.internal.compiler.ast.Argument; import org.eclipse.jdt.internal.compiler.ast.ArrayAllocationExpression; +import org.eclipse.jdt.internal.compiler.ast.Block; import org.eclipse.jdt.internal.compiler.ast.CaseStatement; import org.eclipse.jdt.internal.compiler.ast.CastExpression; import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration; @@ -249,11 +250,38 @@ private void buildMoreCompletionContext(Expression expression) { wrapInIf = true; orphan = right; } else if (this.elementKindStack[i] == K_INSIDE_ELSE_STATEMENT) { + int newAstPtr = this.elementInfoStack[i]; + int length = this.astPtr - newAstPtr; + Statement[] statements = new Statement[length+1]; + System.arraycopy( + this.astStack, + newAstPtr + 1, + statements, + 0, + length); + statements[length] = orphan; + this.astPtr = newAstPtr; + Block b = new Block(0); + b.statements = statements; + elseStat = b; thenStat = (Statement) this.astStack[this.elementInfoStack[i]]; - elseStat = orphan; + this.astPtr--; } else if (this.elementKindStack[i] == K_INSIDE_THEN_STATEMENT) { Expression e = this.expressionStack[this.elementInfoStack[i]]; - if (thenStat == null) thenStat = orphan; + int newAstPtr = (int) this.elementObjectInfoStack[i]; + int length = this.astPtr - newAstPtr; + Statement[] statements = new Statement[length+1]; + System.arraycopy( + this.astStack, + newAstPtr + 1, + statements, + 0, + length); + statements[length] = orphan; + this.astPtr = newAstPtr; + Block b = new Block(0); + b.statements = statements; + if (thenStat == null) thenStat = b; parentNode = orphan = new IfStatement(e, thenStat, elseStat, 0, 0); } i--; @@ -834,7 +862,7 @@ protected void consumeGuard() { @Override protected void consumePostIfExpression() { super.consumePostIfExpression(); - pushOnElementStack(K_INSIDE_THEN_STATEMENT, this.expressionPtr); + pushOnElementStack(K_INSIDE_THEN_STATEMENT, this.expressionPtr, this.astPtr); } @Override @@ -1936,6 +1964,8 @@ protected int astPtr() { for (int i = 0; i <= this.elementPtr; i++) { if (this.elementKindStack[i] == K_INSIDE_SWITCH) return (int) this.elementObjectInfoStack[i]; + else if (this.elementKindStack[i] == K_INSIDE_THEN_STATEMENT) + return (int) this.elementObjectInfoStack[i]; } return super.astPtr(); }