eclipse-jdt / eclipse-jdt/eclipse.jdt.core

Casted receiver completion with inline comment results in string index OOBE

Open
#3,740 0 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
Java
Stars
237
Forks
195
Avg merge
1d 12h
Merged PRs (30d)
47

Description

According to this test case: `CompletionTests.testCompletionAfterInstanceof19`, opening completion at the `|` and accepting `myField`:

```java
public class DemoClass {
int myField = 12;
public void myMethod() {
Object obj = new Object();
if (obj instanceof DemoClass) {
obj /* obj is definitely a DemoClass */ . myF`|`
}
}
}
```

should result in

```java
public class DemoClass {
int myField = 12;
public void myMethod() {
Object obj = new Object();
if (obj instanceof DemoClass) {
((DemoClass)obj) /* obj is definitely a DemoClass */ . myField
}
}
}
```

However, instead I get the following stacktrace:

Stacktrace with a `StringIndexOutOfBoundsException`

```
!ENTRY org.eclipse.jdt.ui 4 0 2025-02-14 15:25:05.278
!MESSAGE Error retrieving proposal text.
Display string:
myField : int - DemoClass
Pattern:
obj /* obj is definitely a DemoClass */ . myF
!STACK 0
java.lang.StringIndexOutOfBoundsException: Range [0, 45) out of bounds for length 25
at java.base/jdk.internal.util.Preconditions$1.apply(Preconditions.java:55)
at java.base/jdk.internal.util.Preconditions$1.apply(Preconditions.java:52)
at java.base/jdk.internal.util.Preconditions$4.apply(Preconditions.java:213)
at java.base/jdk.internal.util.Preconditions$4.apply(Preconditions.java:210)
at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:98)
at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckFromToIndex(Preconditions.java:112)
at java.base/jdk.internal.util.Preconditions.checkFromToIndex(Preconditions.java:349)
at java.base/java.lang.String.checkBoundsBeginEnd(String.java:4865)
at java.base/java.lang.String.substring(String.java:2834)
at org.eclipse.jdt.internal.ui.text.java.AbstractJavaCompletionProposal.getPatternMatchRule(AbstractJavaCompletionProposal.java:928)
at org.eclipse.jdt.internal.ui.text.java.AbstractJavaCompletionProposal.getStyledDisplayString(AbstractJavaCompletionProposal.java:1258)
at org.eclipse.jdt.internal.ui.text.java.JavaCompletionProposal.getStyledDisplayString(JavaCompletionProposal.java:186)
at org.eclipse.jface.text.contentassist.CompletionProposalPopup.handleSetData(CompletionProposalPopup.java:879)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:91)
at org.eclipse.swt.widgets.Display.sendEvent(Display.java:5857)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1652)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1678)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1661)
at org.eclipse.swt.widgets.Table.checkData(Table.java:289)
at org.eclipse.swt.widgets.Table.cellDataProc(Table.java:227)
at org.eclipse.swt.widgets.Display.cellDataProc(Display.java:995)
at org.eclipse.swt.internal.gtk.GTK.gtk_tree_view_column_cell_set_cell_data(Native Method)
at org.eclipse.swt.widgets.Table.getItemHeightInPixels(Table.java:1689)
at org.eclipse.swt.widgets.Table.getItemHeight(Table.java:1660)
at org.eclipse.jface.text.contentassist.CompletionProposalPopup.getMinimalHeight(CompletionProposalPopup.java:720)
at org.eclipse.jface.text.contentassist.ContentAssistant$LayoutManager.computeBoundsBelowAbove(ContentAssistant.java:705)
at org.eclipse.jface.text.contentassist.CompletionProposalPopup.getLocation(CompletionProposalPopup.java:1207)
at org.eclipse.jface.text.contentassist.CompletionProposalPopup.setProposals(CompletionProposalPopup.java:1192)
at org.eclipse.jface.text.contentassist.AsyncCompletionProposalPopup.computeAndPopulateProposals(AsyncCompletionProposalPopup.java:221)
at org.eclipse.jface.text.contentassist.AsyncCompletionProposalPopup.showProposals(AsyncCompletionProposalPopup.java:172)
at org.eclipse.jface.text.contentassist.ContentAssistant.showPossibleCompletions(ContentAssistant.java:1874)
at org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitEditor$AdaptedSourceViewer.doOperation(CompilationUnitEditor.java:189)
at org.eclipse.ui.texteditor.ContentAssistAction.lambda$0(ContentAssistAction.java:85)
at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:67)
at org.eclipse.ui.texteditor.ContentAssistAction.run(ContentAssistAction.java:84)
at org.eclipse.ui.texteditor.RetargetTextEditorAction.run(RetargetTextEditorAction.java:232)
at org.eclipse.jface.action.Action.runWithEvent(Action.java:474)
at org.eclipse.jface.commands.ActionHandler.execute(ActionHandler.java:124)
at org.eclipse.ui.internal.handlers.E4HandlerProxy.execute(E4HandlerProxy.java:98)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:56)
at org.eclipse.e4.core.internal.di.InjectorImpl.invokeUsingClass(InjectorImpl.java:299)
at org.eclipse.e4.core.internal.di.InjectorImpl.invoke(InjectorImpl.java:233)
at org.eclipse.e4.core.contexts.ContextInjectionFactory.invoke(ContextInjectionFactory.java:174)
at org.eclipse.e4.core.commands.internal.HandlerServiceHandler.execute(HandlerServiceHandler.java:165)
at org.eclipse.core.commands.Command.executeWithChecks(Command.java:488)
at org.eclipse.core.commands.ParameterizedCommand.executeWithChecks(ParameterizedCommand.java:485)
at org.eclipse.e4.core.commands.internal.HandlerServiceImpl.executeHandler(HandlerServiceImpl.java:204)
at org.eclipse.e4.ui.bindings.keys.KeyBindingDispatcher.executeCommand(KeyBindingDispatcher.java:308)
at org.eclipse.e4.ui.bindings.keys.KeyBindingDispatcher.press(KeyBindingDispatcher.java:569)
at org.eclipse.e4.ui.bindings.keys.KeyBindingDispatcher.processKeyEvent(KeyBindingDispatcher.java:644)
at org.eclipse.e4.ui.bindings.keys.KeyBindingDispatcher.filterKeySequenceBindings(KeyBindingDispatcher.java:439)
at org.eclipse.e4.ui.bindings.keys.KeyBindingDispatcher$KeyDownFilter.handleEvent(KeyBindingDispatcher.java:96)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:91)
at org.eclipse.swt.widgets.Display.filterEvent(Display.java:1956)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1651)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1678)
at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1661)
at org.eclipse.swt.widgets.Widget.sendKeyEvent(Widget.java:1700)
at org.eclipse.swt.widgets.Widget.gtk_key_press_event(Widget.java:996)
at org.eclipse.swt.widgets.Control.gtk_key_press_event(Control.java:3999)
at org.eclipse.swt.widgets.Composite.gtk_key_press_event(Composite.java:931)
at org.eclipse.swt.widgets.Widget.windowProc(Widget.java:2630)
at org.eclipse.swt.widgets.Control.windowProc(Control.java:6842)
at org.eclipse.swt.widgets.Display.windowProc(Display.java:6164)
at org.eclipse.swt.internal.gtk3.GTK3.gtk_main_do_event(Native Method)
at org.eclipse.swt.widgets.Display.eventProc(Display.java:1600)
at org.eclipse.swt.internal.gtk3.GTK3.gtk_main_iteration_do(Native Method)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:4516)
at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1151)
at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:339)
at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1042)
at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:153)
at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:668)
at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:339)
at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:576)
at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:173)
at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:178)
at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:208)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:149)
at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:115)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:467)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:298)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:668)
at org.eclipse.equinox.launcher.Main.basicRun(Main.java:605)
at org.eclipse.equinox.launcher.Main.run(Main.java:1481)
at org.eclipse.equinox.launcher.Main.main(Main.java:1454)
```
The stacktrace goes through jdt.ui. I think the root cause is that the receiver range ends after `obj` instead of at the `.`, and the jdt.ui code to calculate the display string gets tripped up by this. I think this could be resolved in jdt.core by adjusting the receiver range to include everything up to but excluding the `.`, but perhaps it's better to fix in jdt.ui?

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.