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

Bad selection for method call with nested instanceof argument #848

Closed
trancexpress opened this issue Mar 16, 2023 · 6 comments
Closed

Bad selection for method call with nested instanceof argument #848

trancexpress opened this issue Mar 16, 2023 · 6 comments
Assignees
Labels
bug Something isn't working regression Something was broken by a previous change
Milestone

Comments

@trancexpress
Copy link
Contributor

trancexpress commented Mar 16, 2023

See: https://bugs.eclipse.org/bugs/show_bug.cgi?id=575150

Navigate to the call to CompletionEngine.findMethods() in CompletionEngine.completionOnMessageSend(), try computing a call hierarchy or using F3, observe nothing meaningful is shown.

The method is:

org.eclipse.jdt.internal.codeassist.CompletionEngine.findMethods(char[], TypeBinding[], TypeBinding[], ReferenceBinding, Scope, ObjectVector, boolean, boolean, InvocationSite, Scope, boolean, boolean, boolean, Binding[], int[], int[], boolean, char[], int, int)

Reproducible also with:

public class Test {

	public static class X {
		public Object o = new Object();
	}

	public static void main(String[] args) {
		X x = new X();
		foo(
			x.o instanceof Object
		);
	}

	private static void foo(boolean b) {
	}
}

Select the call to foo() in main() and use F3, see the status error text in the bottom left (the left part of the status line).

@trancexpress trancexpress added the bug Something isn't working label Mar 16, 2023
@trancexpress
Copy link
Contributor Author

Seems like an exception is thrown while Engine.parseBlockStatements() is trying to find the right method for the selection:

java.lang.ArrayIndexOutOfBoundsException: Index -1 out of bounds for length 10
	at org.eclipse.jdt.internal.codeassist.impl.AssistParser.getTypeReference(AssistParser.java:1513)
	at org.eclipse.jdt.internal.codeassist.select.SelectionParser.consumeInstanceOfExpression(SelectionParser.java:825)
	at org.eclipse.jdt.internal.compiler.parser.Parser.consumeRule(Parser.java:7468)
	at org.eclipse.jdt.internal.compiler.parser.Parser.parse(Parser.java:13156)
	at org.eclipse.jdt.internal.codeassist.impl.AssistParser.parseBlockStatements(AssistParser.java:2100)
	at org.eclipse.jdt.internal.codeassist.impl.AssistParser.parseBlockStatements(AssistParser.java:1940)
	at org.eclipse.jdt.internal.codeassist.impl.Engine.parseBlockStatements(Engine.java:350)
	at org.eclipse.jdt.internal.codeassist.impl.Engine.parseBlockStatements(Engine.java:312)
	at org.eclipse.jdt.internal.codeassist.SelectionEngine.select(SelectionEngine.java:1081)
	at org.eclipse.jdt.internal.core.Openable.codeSelect(Openable.java:167)
	at org.eclipse.jdt.internal.core.ClassFile.codeSelect(ClassFile.java:134)
	at org.eclipse.jdt.internal.core.AbstractClassFile.codeSelect(AbstractClassFile.java:117)
	at org.eclipse.jdt.internal.ui.text.java.hover.AbstractJavaEditorTextHover.getJavaElementsAt(AbstractJavaEditorTextHover.java:121)
	at org.eclipse.jdt.internal.ui.text.java.hover.JavadocHover.internalGetHoverInfo(JavadocHover.java:662)
	at org.eclipse.jdt.internal.ui.text.java.hover.JavadocHover.getHoverInfo2(JavadocHover.java:658)
	at org.eclipse.jdt.internal.ui.text.java.hover.BestMatchHover.getHoverInfo2(BestMatchHover.java:163)
	at org.eclipse.jdt.internal.ui.text.java.hover.BestMatchHover.getHoverInfo2(BestMatchHover.java:130)
	at org.eclipse.jdt.internal.ui.text.java.hover.JavaEditorTextHoverProxy.getHoverInfo2(JavaEditorTextHoverProxy.java:89)
	at org.eclipse.jface.text.TextViewerHoverManager$1.run(TextViewerHoverManager.java:155)
java.lang.ArrayIndexOutOfBoundsException: Index -1 out of bounds for length 10
	at org.eclipse.jdt.internal.codeassist.impl.AssistParser.getTypeReference(AssistParser.java:1513)
	at org.eclipse.jdt.internal.codeassist.select.SelectionParser.consumeInstanceOfExpression(SelectionParser.java:825)
	at org.eclipse.jdt.internal.compiler.parser.Parser.consumeRule(Parser.java:7468)
	at org.eclipse.jdt.internal.compiler.parser.Parser.parse(Parser.java:13156)
	at org.eclipse.jdt.internal.codeassist.impl.AssistParser.parseBlockStatements(AssistParser.java:2100)
	at org.eclipse.jdt.internal.codeassist.impl.AssistParser.parseBlockStatements(AssistParser.java:1940)
	at org.eclipse.jdt.internal.codeassist.impl.Engine.parseBlockStatements(Engine.java:350)
	at org.eclipse.jdt.internal.codeassist.impl.Engine.parseBlockStatements(Engine.java:312)
	at org.eclipse.jdt.internal.codeassist.SelectionEngine.select(SelectionEngine.java:1081)
	at org.eclipse.jdt.internal.core.Openable.codeSelect(Openable.java:167)
	at org.eclipse.jdt.internal.core.ClassFile.codeSelect(ClassFile.java:134)
	at org.eclipse.jdt.internal.core.AbstractClassFile.codeSelect(AbstractClassFile.java:117)
	at org.eclipse.jdt.internal.ui.actions.SelectionConverter.codeResolve(SelectionConverter.java:270)
	at org.eclipse.jdt.internal.ui.actions.SelectionConverter$1CodeResolveRunnable.run(SelectionConverter.java:254)
	at org.eclipse.jface.operation.ModalContext$ModalContextThread.run(ModalContext.java:122)
java.lang.ArrayIndexOutOfBoundsException: Index -1 out of bounds for length 10
	at org.eclipse.jdt.internal.codeassist.impl.AssistParser.getTypeReference(AssistParser.java:1513)
	at org.eclipse.jdt.internal.codeassist.select.SelectionParser.consumeInstanceOfExpression(SelectionParser.java:825)
	at org.eclipse.jdt.internal.compiler.parser.Parser.consumeRule(Parser.java:7468)
	at org.eclipse.jdt.internal.compiler.parser.Parser.parse(Parser.java:13156)
	at org.eclipse.jdt.internal.codeassist.impl.AssistParser.parseBlockStatements(AssistParser.java:2100)
	at org.eclipse.jdt.internal.codeassist.impl.AssistParser.parseBlockStatements(AssistParser.java:1940)
	at org.eclipse.jdt.internal.codeassist.impl.Engine.parseBlockStatements(Engine.java:350)
	at org.eclipse.jdt.internal.codeassist.impl.Engine.parseBlockStatements(Engine.java:312)
	at org.eclipse.jdt.internal.codeassist.SelectionEngine.select(SelectionEngine.java:1081)
	at org.eclipse.jdt.internal.core.Openable.codeSelect(Openable.java:167)
	at org.eclipse.jdt.internal.core.ClassFile.codeSelect(ClassFile.java:134)
	at org.eclipse.jdt.internal.core.AbstractClassFile.codeSelect(AbstractClassFile.java:117)
	at org.eclipse.jdt.internal.ui.text.java.hover.AbstractJavaEditorTextHover.getJavaElementsAt(AbstractJavaEditorTextHover.java:121)
	at org.eclipse.jdt.internal.ui.text.java.hover.JavadocHover.internalGetHoverInfo(JavadocHover.java:662)
	at org.eclipse.jdt.internal.ui.text.java.hover.JavadocHover.getHoverInfo2(JavadocHover.java:658)
	at org.eclipse.jdt.internal.ui.text.java.hover.BestMatchHover.getHoverInfo2(BestMatchHover.java:163)
	at org.eclipse.jdt.internal.ui.text.java.hover.BestMatchHover.getHoverInfo2(BestMatchHover.java:130)
	at org.eclipse.jdt.internal.ui.text.java.hover.JavaEditorTextHoverProxy.getHoverInfo2(JavaEditorTextHoverProxy.java:89)
	at org.eclipse.jface.text.TextViewerHoverManager$1.run(TextViewerHoverManager.java:155)

Also an exception is thrown during the selection itself. The method in the loop is:

private void completionOnMessageSend(ASTNode astNode, Binding qualifiedBinding, Scope scope) {
}

And the exception is:

java.lang.ArrayIndexOutOfBoundsException: Index -1 out of bounds for length 10
	at org.eclipse.jdt.internal.codeassist.impl.AssistParser.getTypeReference(AssistParser.java:1513)
	at org.eclipse.jdt.internal.codeassist.select.SelectionParser.consumeInstanceOfExpression(SelectionParser.java:825)
	at org.eclipse.jdt.internal.compiler.parser.Parser.consumeRule(Parser.java:7468)
	at org.eclipse.jdt.internal.compiler.parser.Parser.parse(Parser.java:13156)
	at org.eclipse.jdt.internal.codeassist.impl.AssistParser.parseBlockStatements(AssistParser.java:2100)
	at org.eclipse.jdt.internal.codeassist.impl.AssistParser.parseBlockStatements(AssistParser.java:1940)
	at org.eclipse.jdt.internal.codeassist.impl.Engine.parseBlockStatements(Engine.java:350)
	at org.eclipse.jdt.internal.codeassist.impl.Engine.parseBlockStatements(Engine.java:312)
	at org.eclipse.jdt.internal.codeassist.SelectionEngine.select(SelectionEngine.java:1081)
	at org.eclipse.jdt.internal.core.Openable.codeSelect(Openable.java:167)
	at org.eclipse.jdt.internal.core.ClassFile.codeSelect(ClassFile.java:134)
	at org.eclipse.jdt.internal.core.AbstractClassFile.codeSelect(AbstractClassFile.java:117)
	at org.eclipse.jdt.internal.ui.text.java.hover.AbstractJavaEditorTextHover.getJavaElementsAt(AbstractJavaEditorTextHover.java:121)
	at org.eclipse.jdt.internal.ui.text.java.hover.JavadocHover.internalGetHoverInfo(JavadocHover.java:662)
	at org.eclipse.jdt.internal.ui.text.java.hover.JavadocHover.getHoverInfo2(JavadocHover.java:658)
	at org.eclipse.jdt.internal.ui.text.java.hover.BestMatchHover.getHoverInfo2(BestMatchHover.java:163)
	at org.eclipse.jdt.internal.ui.text.java.hover.BestMatchHover.getHoverInfo2(BestMatchHover.java:130)
	at org.eclipse.jdt.internal.ui.text.java.hover.JavaEditorTextHoverProxy.getHoverInfo2(JavaEditorTextHoverProxy.java:89)
	at org.eclipse.jface.text.TextViewerHoverManager$1.run(TextViewerHoverManager.java:155)

From what I can tell this is the line that causes the problem:

diff --git a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java
index 1b4d8dc10e..63a4defaf6 100644
--- a/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java
+++ b/org.eclipse.jdt.core/codeassist/org/eclipse/jdt/internal/codeassist/CompletionEngine.java
@@ -3319,7 +3319,7 @@ public final class CompletionEngine
                                messageSend,
                                scope,
                                false,
-                               messageSend.receiver instanceof SuperReference,
+                               false,//messageSend.receiver instanceof SuperReference,
                                false,
                                null,
                                null,

After this change the selection works as expected.

@trancexpress
Copy link
Contributor Author

trancexpress commented Mar 16, 2023

If I remove SelectionParser.consumeInstanceOfExpression(), which was added for https://bugs.eclipse.org/bugs/show_bug.cgi?id=577508, the bug is gone. Oddly, Stephan reported the bug against 4.21 and supposedly the change was done for 4.22+...

Maybe some earlier attempts at supporting pattern instanceof caused the problem already in 4.21.

@trancexpress trancexpress added the regression Something was broken by a previous change label Mar 16, 2023
trancexpress added a commit to trancexpress/eclipse.jdt.core that referenced this issue Mar 16, 2023
Selecting a method with a call as follows results in an AIOOBE:

foo(x.y instanceof Object);

This change adjusts SelectionParser.consumeInstanceOfExpression() to not
try to parse a type reference if there are no generic identifiers. This
prevents an AIOOBE in the method.

Fixes: eclipse-jdt#848
Signed-off-by: Simeon Andreev <simeon.danailov.andreev@gmail.com>
@iloveeclipse iloveeclipse added this to the 4.28 M1 milestone Mar 17, 2023
@iloveeclipse
Copy link
Member

Just another manifestation of same issue from #853 :

import java.util.concurrent.CompletableFuture;

public class F3NotWorking {
    public CompletableFuture<String> readOutStream() {
        return CompletableFuture.supplyAsync(() -> { // <-- F3 to open supplyAsync() declaration doesn't work
        	try {
                return "";
            } catch (Throwable e) {
                String message = "";
                if (e instanceof Exception) { // replace with message == "" and F3 will work again
                    message = "This instanceof breaks F3 above!!!";
                }
                throw new RuntimeException(message, e);
            }
        });
    }
}

@trancexpress trancexpress changed the title Cannot select CompletionEngine.findMethods() Bad selection for method call with nested instanceof argument Mar 18, 2023
@trancexpress trancexpress self-assigned this Mar 30, 2023
@mpalat mpalat modified the milestones: 4.28 M1, 4.28 M2 Apr 6, 2023
@mpalat
Copy link
Contributor

mpalat commented Apr 6, 2023

Moving this out of M1

@srikanth-sankaran
Copy link
Contributor

I can review this candidate fix early next week.

@iloveeclipse iloveeclipse modified the milestones: 4.28 M2, 4.28 M3 May 2, 2023
jarthana added a commit to jarthana/eclipse.jdt.core that referenced this issue May 4, 2023
trancexpress pushed a commit to jarthana/eclipse.jdt.core that referenced this issue May 4, 2023
jarthana added a commit that referenced this issue May 4, 2023
…1028)

Remove the overridden SelectionParser#consumeInstanceOfExpression()
@trancexpress
Copy link
Contributor Author

I checked, this is fixed with: #1028

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working regression Something was broken by a previous change
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants