Skip to content

Commit 3eed15a

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, with enough javadocs
1 parent ff239f3 commit 3eed15a

File tree

18 files changed

+587
-45
lines changed

18 files changed

+587
-45
lines changed

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: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2242,6 +2242,14 @@
22422242
style="toggle"
22432243
menubarPath="org.eclipse.jdt.debug.ui.LaunchView.javaSubmenu/javaPart"
22442244
id="org.eclipse.jdt.debug.ui.launchViewActions.ShowMonitorThreadInfo"/>
2245+
<action
2246+
helpContextId="collapse_stack_frames_action_context"
2247+
label="%collapseStackFrames.label"
2248+
tooltip="%collapseStackFrames.tooltip"
2249+
class="org.eclipse.jdt.internal.debug.ui.actions.CollapseStackFramesAction"
2250+
style="toggle"
2251+
menubarPath="org.eclipse.jdt.debug.ui.LaunchView.javaSubmenu/javaPart"
2252+
id="org.eclipse.jdt.debug.ui.launchViewActions.CollapseStackFrames"/>
22452253
<menu
22462254
id="org.eclipse.jdt.debug.ui.LaunchView.javaSubmenu"
22472255
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: 8 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
@@ -20,6 +20,7 @@
2020
import org.eclipse.jdt.debug.ui.IJavaDebugUIConstants;
2121
import org.eclipse.jface.preference.IPreferenceStore;
2222
import org.eclipse.jface.util.PropertyChangeEvent;
23+
import org.eclipse.jface.util.Util;
2324

2425
public class JDIDebugUIPreferenceInitializer extends AbstractPreferenceInitializer {
2526

@@ -46,6 +47,12 @@ public void initializeDefaultPreferences() {
4647
store.setDefault(IJDIPreferencesConstants.PREF_INACTIVE_FILTERS_LIST, "com.ibm.*,com.sun.*,java.*,javax.*,jdk.*,jrockit.*,org.omg.*,sun.*,sunw.*"); //$NON-NLS-1$
4748
store.setDefault(IJDIPreferencesConstants.PREF_STEP_THRU_FILTERS, true);
4849

50+
store.setDefault(IJDIPreferencesConstants.PREF_ACTIVE_PLATFORM_FRAME_FILTER_LIST, "java.*,javax.*,jdk.*,sun.*,sunw.*,org.junit.*,org.eclipse.jdt.internal.*"); //$NON-NLS-1$
51+
store.setDefault(IJDIPreferencesConstants.PREF_INACTIVE_PLATFORM_FRAME_FILTER_LIST, Util.ZERO_LENGTH_STRING);
52+
store.setDefault(IJDIPreferencesConstants.PREF_ACTIVE_CUSTOM_FRAME_FILTER_LIST, Util.ZERO_LENGTH_STRING);
53+
store.setDefault(IJDIPreferencesConstants.PREF_INACTIVE_CUSTOM_FRAME_FILTER_LIST, Util.ZERO_LENGTH_STRING);
54+
store.setDefault(IJDIPreferencesConstants.PREF_COLLAPSE_STACK_FRAMES, true);
55+
4956
store.setDefault(IDebugUIConstants.ID_VARIABLE_VIEW + "." + IJDIPreferencesConstants.PREF_SHOW_CONSTANTS, false); //$NON-NLS-1$
5057
store.setDefault(IDebugUIConstants.ID_EXPRESSION_VIEW + "." + IJDIPreferencesConstants.PREF_SHOW_CONSTANTS, false); //$NON-NLS-1$
5158
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: 48 additions & 13 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;
@@ -151,6 +152,8 @@ public class JDIModelPresentation extends LabelProvider implements IDebugModelPr
151152

152153
private JavaElementLabelProvider fJavaLabelProvider;
153154

155+
private StackFramePresentationProvider fStackFrameProvider;
156+
154157
public JDIModelPresentation() {
155158
super();
156159
}
@@ -165,6 +168,9 @@ public void dispose() {
165168
fJavaLabelProvider.dispose();
166169
}
167170
fAttributes.clear();
171+
if (fStackFrameProvider != null) {
172+
fStackFrameProvider.close();
173+
}
168174
}
169175

170176
/**
@@ -244,6 +250,8 @@ public String getText(Object item) {
244250
return getJavaOwningTreadText((JavaOwningThread)item);
245251
} else if (item instanceof JavaWaitingThread) {
246252
return getJavaWaitingTreadText((JavaWaitingThread)item);
253+
} else if (item instanceof GroupedStackFrame groupping) {
254+
return getFormattedString(DebugUIMessages.JDIModelPresentation_collapsed_frames, String.valueOf(groupping.getFrameCount()));
247255
} else if (item instanceof NoMonitorInformationElement) {
248256
return DebugUIMessages.JDIModelPresentation_5;
249257
} else {
@@ -737,7 +745,10 @@ public Image getImage(Object item) {
737745
return DebugUITools.getImage(IDebugUIConstants.IMG_OBJS_THREAD_RUNNING);
738746
}
739747
}
740-
if (item instanceof IJavaStackFrame || item instanceof IJavaThread || item instanceof IJavaDebugTarget) {
748+
if (item instanceof IJavaStackFrame) {
749+
return getStackFrameImage((IJavaStackFrame) item);
750+
}
751+
if (item instanceof IJavaThread || item instanceof IJavaDebugTarget) {
741752
return getDebugElementImage(item);
742753
}
743754
if (item instanceof IJavaValue) {
@@ -937,6 +948,30 @@ protected Image getDebugElementImage(Object element) {
937948
return getDebugImage(image, flags);
938949
}
939950

951+
/**
952+
* Returns the image associated with the given {@link IJavaStackFrame}, decorated with overlays, if the stack frame is out of sync
953+
* ({@link IJavaStackFrame#isOutOfSynch()} or synchronized ({@link IJavaStackFrame#isSynchronized()}). The base image is acquired from the
954+
* {@link StackFramePresentationProvider}.
955+
*/
956+
private Image getStackFrameImage(IJavaStackFrame stackFrame) {
957+
var image = getStackFrameProvider().getStackFrameImage(stackFrame);
958+
if (image == null) {
959+
image = DebugUITools.getDefaultImageDescriptor(stackFrame);
960+
}
961+
962+
int flags = 0;
963+
try {
964+
if (stackFrame.isOutOfSynch()) {
965+
flags = JDIImageDescriptor.IS_OUT_OF_SYNCH;
966+
} else if (!stackFrame.isObsolete() && stackFrame.isSynchronized()) {
967+
flags = JDIImageDescriptor.SYNCHRONIZED;
968+
}
969+
} catch (DebugException e) {
970+
// no need to log errors - elements may no longer exist by the time we render them
971+
}
972+
973+
return getDebugImage(image, flags);
974+
}
940975
/**
941976
* Returns the image associated with the given element or <code>null</code>
942977
* if none is defined.
@@ -959,21 +994,11 @@ protected Image getExpressionImage(Object expression) {
959994
}
960995

961996
/**
962-
* Returns the adornment flags for the given element.
963-
* These flags are used to render appropriate overlay
964-
* icons for the element.
997+
* Returns the adornment flags for the given element. These flags are used to render appropriate overlay icons for the element. It only supports
998+
* {@link IJavaThread} and {@link IJavaDebugTarget}, for other types it always returns 0.
965999
*/
9661000
private int computeJDIAdornmentFlags(Object element) {
9671001
try {
968-
if (element instanceof IJavaStackFrame) {
969-
IJavaStackFrame javaStackFrame = ((IJavaStackFrame)element);
970-
if (javaStackFrame.isOutOfSynch()) {
971-
return JDIImageDescriptor.IS_OUT_OF_SYNCH;
972-
}
973-
if (!javaStackFrame.isObsolete() && javaStackFrame.isSynchronized()) {
974-
return JDIImageDescriptor.SYNCHRONIZED;
975-
}
976-
}
9771002
if (element instanceof IJavaThread) {
9781003
int flag= 0;
9791004
IJavaThread javaThread = ((IJavaThread)element);
@@ -2049,6 +2074,16 @@ protected JavaElementLabelProvider getJavaLabelProvider() {
20492074
return fJavaLabelProvider;
20502075
}
20512076

2077+
/**
2078+
* @return a {@link StackFramePresentationProvider} which responsible to classify stack frames into categories and could provide category specific
2079+
* visual representations.
2080+
*/
2081+
private StackFramePresentationProvider getStackFrameProvider() {
2082+
if (fStackFrameProvider == null) {
2083+
fStackFrameProvider = new StackFramePresentationProvider();
2084+
}
2085+
return fStackFrameProvider;
2086+
}
20522087
/**
20532088
* Returns whether the given field variable has the same name as any variables
20542089
*/

0 commit comments

Comments
 (0)