Skip to content

Commit dcb5846

Browse files
committed
Add support for statement-level 'Step Over'
Introduce a debug preference to enable statement-level 'Step Over'. This allows the debugger to skip intermediate bytecode instructions in multi-line statements and suspend only at the next executable source statement. This avoids unnecessary stops at intermediate load instructions during step over. Fixes : #854
1 parent 0d00143 commit dcb5846

File tree

16 files changed

+342
-11
lines changed

16 files changed

+342
-11
lines changed
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2026 IBM Corporation.
3+
*
4+
* This program and the accompanying materials
5+
* are made available under the terms of the Eclipse Public License 2.0
6+
* which accompanies this distribution, and is available at
7+
* https://www.eclipse.org/legal/epl-2.0/
8+
*
9+
* SPDX-License-Identifier: EPL-2.0
10+
*
11+
* Contributors:
12+
* IBM Corporation - initial API and implementation
13+
*******************************************************************************/
14+
public class StatementStep {
15+
16+
public static void main(String[] args) {
17+
String s = ";;";
18+
String s2 = ";;";
19+
String s3 = ";;";
20+
String s4 = ";;";
21+
String s5 = ";;";
22+
tet(
23+
1.0f,
24+
s2,
25+
s3,
26+
tet2(s4,s4),
27+
s5);
28+
s2 = s + s2;
29+
s2 = s + s2;
30+
}
31+
32+
public static String tet(float s, String s2,String s3,String s4,String s5) {
33+
return "sou";
34+
}
35+
public static String tet2(String s, String s2) {
36+
return "sous";
37+
}
38+
39+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2026 IBM Corporation.
3+
*
4+
* This program and the accompanying materials
5+
* are made available under the terms of the Eclipse Public License 2.0
6+
* which accompanies this distribution, and is available at
7+
* https://www.eclipse.org/legal/epl-2.0/
8+
*
9+
* SPDX-License-Identifier: EPL-2.0
10+
*
11+
* Contributors:
12+
* IBM Corporation - initial API and implementation
13+
*******************************************************************************/
14+
public class StatementStepArgumnt {
15+
16+
public static void method1(String firstName, String lastName)
17+
{
18+
System.out.println("Method1 " +
19+
" : first name: " + firstName +
20+
" : last name: " + lastName);
21+
}
22+
23+
public static void main(String[] args) {
24+
25+
String firstName = "John";
26+
String lastName = "Smith";
27+
28+
lastName = "Smith";
29+
30+
method1(firstName,
31+
lastName
32+
);
33+
34+
System.out.println("End call method1");
35+
36+
} /* main( args ) */
37+
38+
} /* TestApp */
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2026 IBM Corporation.
3+
*
4+
* This program and the accompanying materials
5+
* are made available under the terms of the Eclipse Public License 2.0
6+
* which accompanies this distribution, and is available at
7+
* https://www.eclipse.org/legal/epl-2.0/
8+
*
9+
* SPDX-License-Identifier: EPL-2.0
10+
*
11+
* Contributors:
12+
* IBM Corporation - initial API and implementation
13+
*******************************************************************************/
14+
public class StatementStepNested {
15+
16+
public static void main(String[] args) {
17+
String s1 = "A";
18+
String s2 = "B";
19+
String s3 = "C";
20+
String s4 = "D";
21+
22+
test(
23+
s1,
24+
helper1(
25+
s2,
26+
helper1(s3,
27+
helper1(s2,
28+
s3)
29+
)
30+
),
31+
s4
32+
);
33+
34+
System.out.println("Sou");
35+
}
36+
37+
static String helper1(String a, String b) {
38+
return a + b;
39+
}
40+
41+
static String helper2(String a) {
42+
return a;
43+
}
44+
45+
static void test(String a, String b, String c) {
46+
}
47+
}
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2026 IBM Corporation.
3+
*
4+
* This program and the accompanying materials
5+
* are made available under the terms of the Eclipse Public License 2.0
6+
* which accompanies this distribution, and is available at
7+
* https://www.eclipse.org/legal/epl-2.0/
8+
*
9+
* SPDX-License-Identifier: EPL-2.0
10+
*
11+
* Contributors:
12+
* IBM Corporation - initial API and implementation
13+
*******************************************************************************/
14+
package org.eclipse.jdt.debug.test.stepping;
15+
16+
import org.eclipse.debug.core.DebugEvent;
17+
import org.eclipse.debug.core.model.ILineBreakpoint;
18+
import org.eclipse.jdt.debug.core.IJavaStackFrame;
19+
import org.eclipse.jdt.debug.core.IJavaThread;
20+
import org.eclipse.jdt.debug.testplugin.DebugEventWaiter;
21+
import org.eclipse.jdt.debug.tests.AbstractDebugTest;
22+
import org.eclipse.jdt.internal.debug.ui.IJDIPreferencesConstants;
23+
import org.eclipse.jdt.internal.debug.ui.JDIDebugUIPlugin;
24+
import org.eclipse.jface.preference.IPreferenceStore;
25+
26+
public class StatementStepOverTests extends AbstractDebugTest {
27+
28+
public StatementStepOverTests(String name) {
29+
super(name);
30+
}
31+
32+
/**
33+
* Tests a step over with lots of arguments
34+
*/
35+
public void testLotsOfMultilineArguments() throws Exception {
36+
37+
getPrefStore().setValue(IJDIPreferencesConstants.PREF_STATEMENT_LEVEL_STEPPING, true);
38+
String typeName = "StatementStep";
39+
ILineBreakpoint bp = createLineBreakpoint(21, typeName);
40+
IJavaThread thread = null;
41+
try {
42+
thread = launchToLineBreakpoint(typeName, bp, true);
43+
DebugEventWaiter waiter = new DebugEventWaiter(DebugEvent.STEP_END);
44+
IJavaStackFrame stackFrame = (IJavaStackFrame) thread.getTopStackFrame();
45+
thread.stepOver();
46+
waiter.waitForEvent();
47+
assertEquals("Should be at line 26", 26, stackFrame.getLineNumber());
48+
49+
thread.stepOver();
50+
waiter.waitForEvent();
51+
assertEquals("Should be at line 22", 22, stackFrame.getLineNumber());
52+
53+
thread.stepOver();
54+
waiter.waitForEvent();
55+
assertEquals("Should be at line 28", 28, stackFrame.getLineNumber());
56+
} finally {
57+
terminateAndRemove(thread);
58+
removeAllBreakpoints();
59+
}
60+
}
61+
62+
public void testStepOverWithSingleMultilineArgument() throws Exception {
63+
64+
getPrefStore().setValue(IJDIPreferencesConstants.PREF_STATEMENT_LEVEL_STEPPING, true);
65+
String typeName = "StatementStepArgumnt";
66+
ILineBreakpoint bp = createLineBreakpoint(28, typeName);
67+
IJavaThread thread = null;
68+
try {
69+
thread = launchToLineBreakpoint(typeName, bp, true);
70+
DebugEventWaiter waiter = new DebugEventWaiter(DebugEvent.STEP_END);
71+
IJavaStackFrame stackFrame = (IJavaStackFrame) thread.getTopStackFrame();
72+
thread.stepOver();
73+
waiter.waitForEvent();
74+
assertEquals("Should be at line 30", 30, stackFrame.getLineNumber());
75+
76+
thread.stepOver();
77+
waiter.waitForEvent();
78+
assertEquals("Should be at line 34", 34, stackFrame.getLineNumber());
79+
80+
} finally {
81+
terminateAndRemove(thread);
82+
removeAllBreakpoints();
83+
}
84+
}
85+
86+
public void testStepOverWithNestedMultiLineArgs() throws Exception {
87+
88+
getPrefStore().setValue(IJDIPreferencesConstants.PREF_STATEMENT_LEVEL_STEPPING, true);
89+
String typeName = "StatementStepNested";
90+
ILineBreakpoint bp = createLineBreakpoint(20, typeName);
91+
IJavaThread thread = null;
92+
try {
93+
thread = launchToLineBreakpoint(typeName, bp, true);
94+
DebugEventWaiter waiter = new DebugEventWaiter(DebugEvent.STEP_END);
95+
IJavaStackFrame stackFrame = (IJavaStackFrame) thread.getTopStackFrame();
96+
thread.stepOver();
97+
waiter.waitForEvent();
98+
assertEquals("Should be at line 27", 27, stackFrame.getLineNumber());
99+
100+
thread.stepOver();
101+
waiter.waitForEvent();
102+
assertEquals("Should be at line 26", 26, stackFrame.getLineNumber());
103+
104+
thread.stepOver();
105+
waiter.waitForEvent();
106+
assertEquals("Should be at line 24", 24, stackFrame.getLineNumber());
107+
108+
thread.stepOver();
109+
waiter.waitForEvent();
110+
assertEquals("Should be at line 22", 22, stackFrame.getLineNumber());
111+
112+
thread.stepOver();
113+
waiter.waitForEvent();
114+
assertEquals("Should be at line 34", 34, stackFrame.getLineNumber());
115+
116+
} finally {
117+
terminateAndRemove(thread);
118+
removeAllBreakpoints();
119+
}
120+
}
121+
122+
/**
123+
* Returns the <code>JDIDebugUIPlugin</code> preference store
124+
*/
125+
protected IPreferenceStore getPrefStore() {
126+
return JDIDebugUIPlugin.getDefault().getPreferenceStore();
127+
}
128+
}
129+

org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AbstractDebugTest.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,8 @@ public abstract class AbstractDebugTest extends TestCase implements IEvaluation
217217
"Bug534319earlyStart", "Bug534319lateStart", "Bug534319singleThread", "Bug534319startBetwen", "MethodCall", "Bug538303", "Bug540243",
218218
"OutSync", "OutSync2", "ConsoleOutputUmlaut", "ErrorRecurrence", "ModelPresentationTests", "Bug565982",
219219
"SuspendVMConditionalBreakpointsTestSnippet", "FileConditionSnippet2", "compare.CompareObjectsStringTest", "compare.CompareListObjects",
220-
"compare.CompareMapObjects", "compare.CompareSetObjects", "compare.CompareNormalObjects", "compare.CompareArrayObjects" };
220+
"compare.CompareMapObjects", "compare.CompareSetObjects", "compare.CompareNormalObjects", "compare.CompareArrayObjects",
221+
"StatementStep", "StatementStepArgumnt", "StatementStepNested" };
221222

222223
/**
223224
* the default timeout

org.eclipse.jdt.debug.tests/tests/org/eclipse/jdt/debug/tests/AutomatedSuite.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2000, 2025 IBM Corporation and others.
2+
* Copyright (c) 2000, 2026 IBM Corporation and others.
33
*
44
* This program and the accompanying materials
55
* are made available under the terms of the Eclipse Public License 2.0
@@ -17,6 +17,7 @@
1717

1818
import org.eclipse.core.runtime.Platform;
1919
import org.eclipse.jdt.debug.test.stepping.ForceReturnTests;
20+
import org.eclipse.jdt.debug.test.stepping.StatementStepOverTests;
2021
import org.eclipse.jdt.debug.test.stepping.StepFilterTests;
2122
import org.eclipse.jdt.debug.test.stepping.StepIntoSelectionTests;
2223
import org.eclipse.jdt.debug.test.stepping.StepIntoSelectionWithGenerics;
@@ -251,6 +252,7 @@ public AutomatedSuite() {
251252
if (JavaProjectHelper.isJava6Compatible()) {
252253
addTest(new TestSuite(ForceReturnTests.class));
253254
}
255+
addTest(new TestSuite(StatementStepOverTests.class));
254256

255257
//Classpath tests
256258
addTest(new TestSuite(JavaLibraryPathTests.class));

org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/DebugUIMessages.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2000, 2024 IBM Corporation and others.
2+
* Copyright (c) 2000, 2026 IBM Corporation and others.
33
*
44
* This program and the accompanying materials
55
* are made available under the terms of the Eclipse Public License 2.0
@@ -77,6 +77,8 @@ public class DebugUIMessages extends NLS {
7777
public static String JavaDebugPreferencePage_ShowStepResult_local;
7878
public static String JavaDebugPreferencePage_ShowStepResult_remote;
7979
public static String JavaDebugPreferencePage_ShowStepTimeout_ms_1;
80+
81+
public static String JavaDebugPreferencePage_StatementLevelStepOver1;
8082
public static String JavaDebugPreferencePage_Communication_1;
8183
public static String JavaDebugPreferencePage_Debugger__timeout__2;
8284
public static String JavaDebugPreferencePage__Launch_timeout__ms___1;

org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/DebugUIMessages.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ JavaDebugPreferencePage_ShowStepResult_1=Show method result after a step operati
3737
JavaDebugPreferencePage_ShowStepResult_local=Enable for local launc&h types
3838
JavaDebugPreferencePage_ShowStepResult_remote=Enable for remote connections (may be e&ven slower)
3939
JavaDebugPreferencePage_ShowStepTimeout_ms_1=Don't show &if step operation takes longer than (ms):
40+
JavaDebugPreferencePage_StatementLevelStepOver1=Enable statement-level 'Step Over'
4041
JavaDebugPreferencePage_Communication_1=Communication
4142
JavaDebugPreferencePage_Debugger__timeout__2=Debugger &timeout (ms):
4243
JavaDebugPreferencePage__Launch_timeout__ms___1=&Launch timeout (ms):

org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/IJDIPreferencesConstants.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2000, 2011 IBM Corporation and others.
2+
* Copyright (c) 2000, 2026 IBM Corporation and others.
33
*
44
* This program and the accompanying materials
55
* are made available under the terms of the Eclipse Public License 2.0
@@ -269,4 +269,9 @@ public interface IJDIPreferencesConstants {
269269
*/
270270
public static final String PREF_PROMPT_DELETE_CONDITIONAL_BREAKPOINT= IJavaDebugUIConstants.PLUGIN_ID + ".prompt_delete_conditional_breakpoint"; //$NON-NLS-1$
271271

272+
/**
273+
* Boolean preference controlling whether debugger should suspend for statement-level instructions.
274+
*/
275+
public static final String PREF_STATEMENT_LEVEL_STEPPING = IJavaDebugUIConstants.PLUGIN_ID + ".skip_intermediate_instructions"; //$NON-NLS-1$
276+
272277
}

org.eclipse.jdt.debug.ui/ui/org/eclipse/jdt/internal/debug/ui/JDIDebugUIPreferenceInitializer.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2004, 2024 IBM Corporation and others.
2+
* Copyright (c) 2004, 2026 IBM Corporation and others.
33
*
44
* This program and the accompanying materials
55
* are made available under the terms of the Eclipse Public License 2.0
@@ -38,6 +38,7 @@ public void initializeDefaultPreferences() {
3838
store.setDefault(IJDIPreferencesConstants.PREF_ALERT_UNABLE_TO_INSTALL_BREAKPOINT, true);
3939
store.setDefault(IJDIPreferencesConstants.PREF_PROMPT_BEFORE_MODIFYING_FINAL_FIELDS, true);
4040
store.setDefault(IJDIPreferencesConstants.PREF_PROMPT_DELETE_CONDITIONAL_BREAKPOINT, true);
41+
store.setDefault(IJDIPreferencesConstants.PREF_STATEMENT_LEVEL_STEPPING, false);
4142

4243
store.setDefault(IJDIPreferencesConstants.PREF_SHOW_QUALIFIED_NAMES, false);
4344

0 commit comments

Comments
 (0)