Bug 573223 - Improve chained array variable hovering
With this fix it adds array field hovering on local variables in static
frames which are chained.
Change-Id: I7073ab705470b3e6110dad4671287928210e8087
Signed-off-by: Gayan Perera <gayanper@gmail.com>
Reviewed-on: https://git.eclipse.org/r/c/jdt/eclipse.jdt.debug/+/182274
Tested-by: JDT Bot <jdt-bot@eclipse.org>
Reviewed-by: Sarika Sinha <sarika.sinha@in.ibm.com>
diff --git a/org.eclipse.jdt.debug.tests/java8/Bug572629.java b/org.eclipse.jdt.debug.tests/java8/Bug572629.java
index 84c5fb4..9fb653c 100644
--- a/org.eclipse.jdt.debug.tests/java8/Bug572629.java
+++ b/org.eclipse.jdt.debug.tests/java8/Bug572629.java
@@ -60,6 +60,8 @@
new Bug572629("p").equals(new Bug572629("r"));
new Bug572629("p").hoverOverLocal(new String[] {"name"});
new Bug572629("p").hoverOnThis();
+ Bug572629 local = new Bug572629("p");
+ System.out.println(local.names.length);
}
public static class Parent {
@@ -72,4 +74,5 @@
public String name = "name";
}
+ public String[] names = new String[]{"foo"};
}
\ No newline at end of file
diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/ui/DebugHoverTests.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/ui/DebugHoverTests.java
index 037fc01..89d20be 100644
--- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/ui/DebugHoverTests.java
+++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/ui/DebugHoverTests.java
@@ -801,6 +801,117 @@
}
}
+ public void testBug572629_onThisExpression() throws Exception {
+ sync(() -> TestUtil.waitForJobs(getName(), 1000, 10000, ProcessConsole.class));
+
+ final String typeName = "Bug572629";
+ final String expectedMethod = "equals";
+ final int frameNumber = 2;
+ final int bpLine = 37;
+
+ IJavaBreakpoint bp = createLineBreakpoint(bpLine, "", typeName + ".java", typeName);
+ bp.setSuspendPolicy(IJavaBreakpoint.SUSPEND_THREAD);
+ IFile file = (IFile) bp.getMarker().getResource();
+ assertEquals(typeName + ".java", file.getName());
+
+ IJavaThread thread = null;
+ try {
+ thread = launchToBreakpoint(typeName);
+ CompilationUnitEditor part = openEditorAndValidateStack(expectedMethod, frameNumber, file, thread);
+
+ JavaDebugHover hover = new JavaDebugHover();
+ hover.setEditor(part);
+
+ String variableName = "payload";
+ int offset = part.getViewer().getDocument().get().indexOf("return this.payload") + "return this.".length();
+ IRegion region = new Region(offset, "payload".length());
+ String text = selectAndReveal(part, bpLine, region);
+ assertEquals(variableName, text);
+ IVariable info = (IVariable) sync(() -> hover.getHoverInfo2(part.getViewer(), region));
+
+ assertNotNull(info);
+ assertEquals("payload", info.getName());
+ assertEquals("p", info.getValue().getValueString());
+ } finally {
+ terminateAndRemove(thread);
+ removeAllBreakpoints();
+ }
+ }
+
+ public void testBug573223_onLocalVarChain_onArrayField() throws Exception {
+ sync(() -> TestUtil.waitForJobs(getName(), 1000, 10000, ProcessConsole.class));
+
+ final String typeName = "Bug572629";
+ final String expectedMethod = "main";
+ final int frameNumber = 1;
+ final int bpLine = 64;
+
+ IJavaBreakpoint bp = createLineBreakpoint(bpLine, "", typeName + ".java", typeName);
+ bp.setSuspendPolicy(IJavaBreakpoint.SUSPEND_THREAD);
+ IFile file = (IFile) bp.getMarker().getResource();
+ assertEquals(typeName + ".java", file.getName());
+
+ IJavaThread thread = null;
+ try {
+ thread = launchToBreakpoint(typeName);
+ CompilationUnitEditor part = openEditorAndValidateStack(expectedMethod, frameNumber, file, thread);
+
+ JavaDebugHover hover = new JavaDebugHover();
+ hover.setEditor(part);
+
+ String variableName = "names";
+ int offset = part.getViewer().getDocument().get().lastIndexOf("local.names") + "local.".length();
+ IRegion region = new Region(offset, "names".length());
+ String text = selectAndReveal(part, bpLine, region);
+ assertEquals(variableName, text);
+ IVariable info = (IVariable) sync(() -> hover.getHoverInfo2(part.getViewer(), region));
+
+ assertNotNull(info);
+ assertEquals("local.names", info.getName());
+ assertTrue("Not an array variable", info.getValue() instanceof IJavaArray);
+ } finally {
+ terminateAndRemove(thread);
+ removeAllBreakpoints();
+ }
+ }
+
+ public void testBug573223_onLocalVarChain_onArrayLength() throws Exception {
+ sync(() -> TestUtil.waitForJobs(getName(), 1000, 10000, ProcessConsole.class));
+
+ final String typeName = "Bug572629";
+ final String expectedMethod = "main";
+ final int frameNumber = 1;
+ final int bpLine = 64;
+
+ IJavaBreakpoint bp = createLineBreakpoint(bpLine, "", typeName + ".java", typeName);
+ bp.setSuspendPolicy(IJavaBreakpoint.SUSPEND_THREAD);
+ IFile file = (IFile) bp.getMarker().getResource();
+ assertEquals(typeName + ".java", file.getName());
+
+ IJavaThread thread = null;
+ try {
+ thread = launchToBreakpoint(typeName);
+ CompilationUnitEditor part = openEditorAndValidateStack(expectedMethod, frameNumber, file, thread);
+
+ JavaDebugHover hover = new JavaDebugHover();
+ hover.setEditor(part);
+
+ String variableName = "length";
+ int offset = part.getViewer().getDocument().get().lastIndexOf("local.names.length") + "local.names.".length();
+ IRegion region = new Region(offset, "length".length());
+ String text = selectAndReveal(part, bpLine, region);
+ assertEquals(variableName, text);
+ IVariable info = (IVariable) sync(() -> hover.getHoverInfo2(part.getViewer(), region));
+
+ assertNotNull(info);
+ assertEquals("local.names.length", info.getName());
+ assertEquals("1", info.getValue().getValueString());
+ } finally {
+ terminateAndRemove(thread);
+ removeAllBreakpoints();
+ }
+ }
+
private CompilationUnitEditor openEditorAndValidateStack(final String expectedMethod, final int expectedFramesNumber, IFile file, IJavaThread thread) throws Exception, DebugException {
// Let now all pending jobs proceed, ignore console jobs
sync(() -> TestUtil.waitForJobs(getName(), 1000, 10000, ProcessConsole.class));
diff --git a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JavaDebugHover.java b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JavaDebugHover.java
index 88742e1..4076ce1 100644
--- a/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JavaDebugHover.java
+++ b/org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JavaDebugHover.java
@@ -359,8 +359,9 @@
}
}
} else {
- if (!frame.isStatic() && !frame.isNative()) {
- // ensure that we only resolve a field access on 'this':
+ if ((!frame.isStatic() || isLocalOrMemberVariable(javaElement)) && !frame.isNative()) {
+ // we resolve chain elements which are either on "this" or local variables. In case of
+ // local variables we also consider static frames.
if (!(codeAssist instanceof ITypeRoot)) {
return null;
}