Skip to content

Commit a1db2c3

Browse files
committed
Implement grouping of the stack frames
The rules how the frames are categorized are not editable as of now, just a single action is visible to switch on-off the behaviour
1 parent 8a20637 commit a1db2c3

18 files changed

Lines changed: 509 additions & 38 deletions

File tree

org.eclipse.jdt.debug.ui/plugin.properties

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,9 @@ showMonitorThreadInfo.tooltip=Show the Thread & Monitor Information
178178
showNullEntriesAction.label=Show &Null Array Entries
179179
showNullEntriesAction.tooltip=Show Null Array Entries
180180

181+
collapseStackFrames.label=Collapse Stack Frames
182+
collapseStackFrames.tooltip=Hide less relevant stack frames
183+
181184
stepIntoSelectionHyperlinkDetector.label=Step Into Selection
182185
stepIntoSelectionHyperlinkDetector.description=Performs the step into selection command on demand via a hyperlink
183186

org.eclipse.jdt.debug.ui/plugin.xml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2208,6 +2208,15 @@
22082208
style="toggle"
22092209
menubarPath="org.eclipse.jdt.debug.ui.LaunchView.javaSubmenu/javaPart"
22102210
id="org.eclipse.jdt.debug.ui.launchViewActions.ShowMonitorThreadInfo"/>
2211+
<action
2212+
helpContextId="collapse_stack_frames_action_context"
2213+
label="%collapseStackFrames.label"
2214+
tooltip="%collapseStackFrames.tooltip"
2215+
class="org.eclipse.jdt.internal.debug.ui.actions.CollapseStackFramesAction"
2216+
style="toggle"
2217+
menubarPath="org.eclipse.jdt.debug.ui.LaunchView.javaSubmenu/javaPart"
2218+
id="org.eclipse.jdt.debug.ui.launchViewActions.CollapseStackFrames"/>
2219+
22112220
<menu
22122221
id="org.eclipse.jdt.debug.ui.LaunchView.javaSubmenu"
22132222
label="%LaunchViewJavaSubmenu.label"

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ public class DebugUIMessages extends NLS {
154154
public static String JDIModelPresentation__garbage_collected_object__6;
155155
public static String JDIModelPresentation__obsolete_method_in__1;
156156
public static String JDIModelPresentation__terminated__2;
157+
public static String JDIModelPresentation_collapsed_frames;
157158

158159
public static String JDIModelPresentation_117;
159160

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
@@ -116,6 +116,7 @@ JDIModelPresentation_modification_72=\ [modification]
116116
JDIModelPresentation_native_method=[native method]
117117
JDIModelPresentation_not_available=not available
118118
JDIModelPresentation_Suspend_VM=[Suspend VM]
119+
JDIModelPresentation_collapsed_frames={0} collapsed frames
119120

120121
###############################################################################
121122
# Thread label keys are built programmatically

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

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,34 @@ public interface IJDIPreferencesConstants {
7979
*/
8080
public static final String PREF_STEP_THRU_FILTERS = IJavaDebugUIConstants.PLUGIN_ID + ".step_thru_filters"; //$NON-NLS-1$
8181

82+
public static final String PREF_COLLAPSE_STACK_FRAMES = IJavaDebugUIConstants.PLUGIN_ID + ".collapse_stack_frames"; //$NON-NLS-1$
83+
8284
/**
83-
* List of active step filters. A String containing a comma
84-
* separated list of fully qualified type names/patterns.
85+
* List of active filters for custom stack frame categorization. A String containing a comma separated list of fully qualified type
86+
* names/patterns.
87+
*/
88+
public static final String PREF_ACTIVE_CUSTOM_FRAME_FILTER_LIST = IJavaDebugUIConstants.PLUGIN_ID + ".active_custom_frames_filters"; //$NON-NLS-1$
89+
90+
/**
91+
* List of inactive filters for custom stack frame categorization. A String containing a comma separated list of fully qualified type
92+
* names/patterns.
93+
*/
94+
public static final String PREF_INACTIVE_CUSTOM_FRAME_FILTER_LIST = IJavaDebugUIConstants.PLUGIN_ID + ".inactive_custom_frames_filters"; //$NON-NLS-1$
95+
96+
/**
97+
* List of active filters for custom stack frame categorization. A String containing a comma separated list of fully qualified type
98+
* names/patterns.
99+
*/
100+
public static final String PREF_ACTIVE_PLATFORM_FRAME_FILTER_LIST = IJavaDebugUIConstants.PLUGIN_ID + ".active_platform_frames_filters"; //$NON-NLS-1$
101+
102+
/**
103+
* List of inactive filters for custom stack frame categorization. A String containing a comma separated list of fully qualified type
104+
* names/patterns.
105+
*/
106+
public static final String PREF_INACTIVE_PLATFORM_FRAME_FILTER_LIST = IJavaDebugUIConstants.PLUGIN_ID + ".inactive_platform_frames_filters"; //$NON-NLS-1$
107+
108+
/**
109+
* List of active step filters. A String containing a comma separated list of fully qualified type names/patterns.
85110
*/
86111
public static final String PREF_ACTIVE_FILTERS_LIST = IJavaDebugUIConstants.PLUGIN_ID + ".active_filters"; //$NON-NLS-1$
87112

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2000, 2022 IBM Corporation and others.
2+
* Copyright (c) 2000, 2024 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
@@ -57,6 +57,7 @@
5757
import org.eclipse.jdt.debug.core.IJavaVariable;
5858
import org.eclipse.jdt.debug.core.JDIDebugModel;
5959
import org.eclipse.jdt.debug.ui.IJavaDebugUIConstants;
60+
import org.eclipse.jdt.internal.debug.core.model.GroupedStackFrame;
6061
import org.eclipse.jdt.internal.debug.ui.breakpoints.ExceptionInspector;
6162
import org.eclipse.jdt.internal.debug.ui.breakpoints.JavaBreakpointTypeAdapterFactory;
6263
import org.eclipse.jdt.internal.debug.ui.classpath.ClasspathEntryAdapterFactory;
@@ -382,6 +383,7 @@ public void start(BundleContext context) throws Exception {
382383
manager.registerAdapters(monitorFactory, JavaOwningThread.class);
383384
manager.registerAdapters(monitorFactory, JavaWaitingThread.class);
384385
manager.registerAdapters(monitorFactory, IJavaStackFrame.class);
386+
manager.registerAdapters(monitorFactory, GroupedStackFrame.class);
385387

386388
IAdapterFactory targetFactory = new TargetAdapterFactory();
387389
manager.registerAdapters(targetFactory, IJavaDebugTarget.class);
@@ -391,6 +393,7 @@ public void start(BundleContext context) throws Exception {
391393

392394
IAdapterFactory showInFactory = new JavaDebugShowInAdapterFactory();
393395
manager.registerAdapters(showInFactory, IJavaStackFrame.class);
396+
manager.registerAdapters(showInFactory, GroupedStackFrame.class);
394397

395398
IAdapterFactory columnFactory = new ColumnPresentationAdapterFactory();
396399
manager.registerAdapters(columnFactory, IJavaVariable.class);

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2004, 2020 IBM Corporation and others.
2+
* Copyright (c) 2004, 2024 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
@@ -46,6 +46,12 @@ public void initializeDefaultPreferences() {
4646
store.setDefault(IJDIPreferencesConstants.PREF_INACTIVE_FILTERS_LIST, "com.ibm.*,com.sun.*,java.*,javax.*,jdk.*,jrockit.*,org.omg.*,sun.*,sunw.*"); //$NON-NLS-1$
4747
store.setDefault(IJDIPreferencesConstants.PREF_STEP_THRU_FILTERS, true);
4848

49+
store.setDefault(IJDIPreferencesConstants.PREF_ACTIVE_PLATFORM_FRAME_FILTER_LIST, "java.*,javax.*,jdk.*,sun.*,sunw.*,org.junit.*,org.eclipse.jdt.internal.*"); //$NON-NLS-1$
50+
store.setDefault(IJDIPreferencesConstants.PREF_INACTIVE_PLATFORM_FRAME_FILTER_LIST, ""); //$NON-NLS-1$
51+
store.setDefault(IJDIPreferencesConstants.PREF_ACTIVE_CUSTOM_FRAME_FILTER_LIST, ""); //$NON-NLS-1$
52+
store.setDefault(IJDIPreferencesConstants.PREF_INACTIVE_CUSTOM_FRAME_FILTER_LIST, ""); //$NON-NLS-1$
53+
store.setDefault(IJDIPreferencesConstants.PREF_COLLAPSE_STACK_FRAMES, true);
54+
4955
store.setDefault(IDebugUIConstants.ID_VARIABLE_VIEW + "." + IJDIPreferencesConstants.PREF_SHOW_CONSTANTS, false); //$NON-NLS-1$
5056
store.setDefault(IDebugUIConstants.ID_EXPRESSION_VIEW + "." + IJDIPreferencesConstants.PREF_SHOW_CONSTANTS, false); //$NON-NLS-1$
5157
store.setDefault(IDebugUIConstants.ID_VARIABLE_VIEW + "." + IJDIPreferencesConstants.PREF_SHOW_STATIC_VARIABLES, false); //$NON-NLS-1$

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

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@
7272
import org.eclipse.jdt.internal.debug.core.breakpoints.JavaExceptionBreakpoint;
7373
import org.eclipse.jdt.internal.debug.core.logicalstructures.JDIAllInstancesValue;
7474
import org.eclipse.jdt.internal.debug.core.logicalstructures.JDIReturnValueVariable;
75+
import org.eclipse.jdt.internal.debug.core.model.GroupedStackFrame;
7576
import org.eclipse.jdt.internal.debug.core.model.JDIDebugModelMessages;
7677
import org.eclipse.jdt.internal.debug.core.model.JDIReferenceListEntryVariable;
7778
import org.eclipse.jdt.internal.debug.core.model.JDIReferenceListValue;
@@ -150,6 +151,8 @@ public class JDIModelPresentation extends LabelProvider implements IDebugModelPr
150151

151152
private JavaElementLabelProvider fJavaLabelProvider;
152153

154+
private StackFramePresentationProvider fStackFrameProvider;
155+
153156
public JDIModelPresentation() {
154157
super();
155158
}
@@ -164,6 +167,9 @@ public void dispose() {
164167
fJavaLabelProvider.dispose();
165168
}
166169
fAttributes.clear();
170+
if (fStackFrameProvider != null) {
171+
fStackFrameProvider.close();
172+
}
167173
}
168174

169175
/**
@@ -243,6 +249,8 @@ public String getText(Object item) {
243249
return getJavaOwningTreadText((JavaOwningThread)item);
244250
} else if (item instanceof JavaWaitingThread) {
245251
return getJavaWaitingTreadText((JavaWaitingThread)item);
252+
} else if (item instanceof GroupedStackFrame groupping) {
253+
return getFormattedString(DebugUIMessages.JDIModelPresentation_collapsed_frames, String.valueOf(groupping.getFrameCount()));
246254
} else if (item instanceof NoMonitorInformationElement) {
247255
return DebugUIMessages.JDIModelPresentation_5;
248256
} else {
@@ -736,7 +744,10 @@ public Image getImage(Object item) {
736744
return DebugUITools.getImage(IDebugUIConstants.IMG_OBJS_THREAD_RUNNING);
737745
}
738746
}
739-
if (item instanceof IJavaStackFrame || item instanceof IJavaThread || item instanceof IJavaDebugTarget) {
747+
if (item instanceof IJavaStackFrame) {
748+
return getStackFrameImage((IJavaStackFrame) item);
749+
}
750+
if (item instanceof IJavaThread || item instanceof IJavaDebugTarget) {
740751
return getDebugElementImage(item);
741752
}
742753
if (item instanceof IJavaValue) {
@@ -936,6 +947,25 @@ protected Image getDebugElementImage(Object element) {
936947
return getDebugImage(image, flags);
937948
}
938949

950+
private Image getStackFrameImage(IJavaStackFrame stackFrame) {
951+
var image = getStackFrameProvider().getStackFrameImage(stackFrame);
952+
if (image == null) {
953+
image = DebugUITools.getDefaultImageDescriptor(stackFrame);
954+
}
955+
956+
int flags = 0;
957+
try {
958+
if (stackFrame.isOutOfSynch()) {
959+
flags = JDIImageDescriptor.IS_OUT_OF_SYNCH;
960+
} else if (!stackFrame.isObsolete() && stackFrame.isSynchronized()) {
961+
flags = JDIImageDescriptor.SYNCHRONIZED;
962+
}
963+
} catch (DebugException e) {
964+
// no need to log errors - elements may no longer exist by the time we render them
965+
}
966+
967+
return getDebugImage(image, flags);
968+
}
939969
/**
940970
* Returns the image associated with the given element or <code>null</code>
941971
* if none is defined.
@@ -964,15 +994,6 @@ protected Image getExpressionImage(Object expression) {
964994
*/
965995
private int computeJDIAdornmentFlags(Object element) {
966996
try {
967-
if (element instanceof IJavaStackFrame) {
968-
IJavaStackFrame javaStackFrame = ((IJavaStackFrame)element);
969-
if (javaStackFrame.isOutOfSynch()) {
970-
return JDIImageDescriptor.IS_OUT_OF_SYNCH;
971-
}
972-
if (!javaStackFrame.isObsolete() && javaStackFrame.isSynchronized()) {
973-
return JDIImageDescriptor.SYNCHRONIZED;
974-
}
975-
}
976997
if (element instanceof IJavaThread) {
977998
int flag= 0;
978999
IJavaThread javaThread = ((IJavaThread)element);
@@ -2048,6 +2069,12 @@ protected JavaElementLabelProvider getJavaLabelProvider() {
20482069
return fJavaLabelProvider;
20492070
}
20502071

2072+
private StackFramePresentationProvider getStackFrameProvider() {
2073+
if (fStackFrameProvider == null) {
2074+
fStackFrameProvider = new StackFramePresentationProvider();
2075+
}
2076+
return fStackFrameProvider;
2077+
}
20512078
/**
20522079
* Returns whether the given field variable has the same name as any variables
20532080
*/

0 commit comments

Comments
 (0)