From 4df73d073da0a99cffb9a01e862a454fcfd6759d Mon Sep 17 00:00:00 2001 From: sougandhs Date: Thu, 2 Apr 2026 08:32:56 +0530 Subject: [PATCH] Fix Debug Hover showing SuperClass Field's value in Subclass Field This commit adds an additional computation for finding the subclass class field if superclass has same field as of subclass Fixes : https://github.com/eclipse-jdt/eclipse.jdt.debug/issues/924 --- .../java8/SubClass.java | 25 +++++++++++++ .../java8/SuperClass.java | 20 +++++++++++ .../jdt/debug/tests/AbstractDebugTest.java | 2 ++ .../jdt/debug/tests/ui/DebugHoverTests.java | 35 +++++++++++++++++++ .../debug/core/model/JDIObjectValue.java | 13 ++++++- 5 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 org.eclipse.jdt.debug.tests/java8/SubClass.java create mode 100644 org.eclipse.jdt.debug.tests/java8/SuperClass.java diff --git a/org.eclipse.jdt.debug.tests/java8/SubClass.java b/org.eclipse.jdt.debug.tests/java8/SubClass.java new file mode 100644 index 0000000000..2f172eb426 --- /dev/null +++ b/org.eclipse.jdt.debug.tests/java8/SubClass.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2026 IBM Corporation. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +public class SubClass extends SuperClass { + private boolean fInitialized; + + public SubClass() { + fInitialized = false; + System.out.println("SubClass constructor"); + } + + public static void main(String[] args) { + new SubClass(); + } +} \ No newline at end of file diff --git a/org.eclipse.jdt.debug.tests/java8/SuperClass.java b/org.eclipse.jdt.debug.tests/java8/SuperClass.java new file mode 100644 index 0000000000..75a0e75d65 --- /dev/null +++ b/org.eclipse.jdt.debug.tests/java8/SuperClass.java @@ -0,0 +1,20 @@ +/******************************************************************************* + * Copyright (c) 2026 IBM Corporation. + * + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +public class SuperClass { + private boolean fInitialized = true; + + public SuperClass() { + + } +} diff --git a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AbstractDebugTest.java b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AbstractDebugTest.java index e9d41c2d7d..be9bb57186 100644 --- a/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AbstractDebugTest.java +++ b/org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AbstractDebugTest.java @@ -552,6 +552,8 @@ synchronized void assert18Project() { cfgs.add(createLaunchConfiguration(jp, "GH275")); cfgs.add(createLaunchConfiguration(jp, "LambdaTest")); cfgs.add(createLaunchConfiguration(jp, "InnerClassBug")); + cfgs.add(createLaunchConfiguration(jp, "SuperClass")); + cfgs.add(createLaunchConfiguration(jp, "SubClass")); loaded18 = true; waitForBuild(); } 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 97beb2cd07..86ba550361 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 @@ -1559,4 +1559,39 @@ public void testHoverOnInnerClassConstructorVariables() throws Exception { } } + public void testResolveSameFieldsInSuperAndSub() throws Exception { + sync(() -> TestUtil.waitForJobs(getName(), 1000, 10000, ProcessConsole.class)); + + final String typeName = "SubClass"; + final String expectedMethod = ""; + final int framesNumber = 2; + final int bpLine1 = 18; + + IJavaBreakpoint bp1 = createLineBreakpoint(bpLine1, "", typeName + ".java", typeName); + bp1.setSuspendPolicy(IJavaBreakpoint.SUSPEND_THREAD); + IFile file = (IFile) bp1.getMarker().getResource(); + assertEquals(typeName + ".java", file.getName()); + + IJavaThread thread = null; + try { + thread = launchToBreakpoint(typeName); + CompilationUnitEditor part = openEditorAndValidateStack(expectedMethod, framesNumber, file, thread); + + JavaDebugHover hover = new JavaDebugHover(); + hover.setEditor(part); + int offset = part.getViewer().getDocument().get().indexOf("fInitialized = "); + String variableName = "fInitialized"; + IRegion region = new Region(offset, variableName.length()); + String text = selectAndReveal(part, bpLine1, region); + assertEquals(variableName, text); + IVariable info = (IVariable) sync(() -> hover.getHoverInfo2(part.getViewer(), region)); + assertNotNull(info); + assertEquals(variableName, info.getName()); + assertEquals("false", info.getValue().getValueString()); + } finally { + terminateAndRemove(thread); + removeAllBreakpoints(); + } + } + } diff --git a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIObjectValue.java b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIObjectValue.java index ee9ece2bed..6b3d1cd4c4 100644 --- a/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIObjectValue.java +++ b/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/model/JDIObjectValue.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2015 IBM Corporation and others. + * Copyright (c) 2000, 2026 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -277,6 +277,17 @@ public IJavaFieldVariable getField(final String name, final String declaringType field = fieldTmp; break; } + List fieldList = ref.allFields(); // Possible sub class fields with same name as of super class + fieldList.remove(fieldTmp); + for (Field fieldCurrentTmp : fieldList) { + if (name.equals(fieldCurrentTmp.name())) { + String signatureCurrent = fieldCurrentTmp.declaringType().signature(); + if (declaringTypeSignature.equals(signatureCurrent)) { + field = fieldCurrentTmp; + break main; + } + } + } // check if we are inside local type - Signature.createTypeSignature // can't create proper type name out of source field in JavaDebugHover // we get LDebugHoverTest$InnerClass2; instead of LDebugHoverTest$1InnerClass2;