Skip to content

Commit 94c201a

Browse files
committed
Honor expression context when creating Watches
When selecting a field under an object, both the Watch command and Drag & Drop previously created a non-contextual expression using only the field name, which caused evaluation failures. This fix ensures that both Watch and Drag & Drop now generate proper context-aware expressions such as myobj.myfield instead of just the field name. Fixes : https://bugs.eclipse.org/bugs/show_bug.cgi?id=321289
1 parent abf063d commit 94c201a

File tree

2 files changed

+54
-24
lines changed

2 files changed

+54
-24
lines changed

debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/actions/expressions/WatchHandler.java

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2008, 2015 Wind River Systems and others.
2+
* Copyright (c) 2008, 2025 Wind River Systems and others.
33
*
44
* This program and the accompanying materials
55
* are made available under the terms of the Eclipse Public License 2.0
@@ -10,16 +10,16 @@
1010
*
1111
* Contributors:
1212
* Wind River Systems - initial API and implementation
13+
* IBM Corporation - Improved expression creation
1314
*******************************************************************************/
1415
package org.eclipse.debug.internal.ui.actions.expressions;
1516

16-
import java.util.Iterator;
17-
1817
import org.eclipse.core.commands.AbstractHandler;
1918
import org.eclipse.core.commands.ExecutionEvent;
2019
import org.eclipse.core.commands.ExecutionException;
2120
import org.eclipse.core.runtime.CoreException;
2221
import org.eclipse.core.runtime.IAdaptable;
22+
import org.eclipse.debug.core.DebugException;
2323
import org.eclipse.debug.core.DebugPlugin;
2424
import org.eclipse.debug.core.ILaunch;
2525
import org.eclipse.debug.core.model.IDebugElement;
@@ -32,7 +32,8 @@
3232
import org.eclipse.debug.ui.actions.IWatchExpressionFactoryAdapter;
3333
import org.eclipse.debug.ui.actions.IWatchExpressionFactoryAdapter2;
3434
import org.eclipse.jface.viewers.ISelection;
35-
import org.eclipse.jface.viewers.IStructuredSelection;
35+
import org.eclipse.jface.viewers.TreePath;
36+
import org.eclipse.jface.viewers.TreeSelection;
3637
import org.eclipse.ui.IViewPart;
3738
import org.eclipse.ui.IWorkbenchPage;
3839
import org.eclipse.ui.PartInitException;
@@ -49,11 +50,26 @@ public class WatchHandler extends AbstractHandler {
4950
@Override
5051
public Object execute(ExecutionEvent event) throws ExecutionException {
5152
ISelection selection = HandlerUtil.getCurrentSelection(event);
52-
if (selection instanceof IStructuredSelection) {
53-
Iterator<?> iter = ((IStructuredSelection)selection).iterator();
54-
while (iter.hasNext()) {
55-
Object element = iter.next();
56-
createExpression(element);
53+
if (selection instanceof TreeSelection treeSelection) {
54+
for (TreePath path : treeSelection.getPaths()) {
55+
if (path.getSegmentCount() > 1) {
56+
StringBuilder expressionString = new StringBuilder();
57+
for (int e = 0; e < path.getSegmentCount(); e++) {
58+
IVariable variable = (IVariable) path.getSegment(e);
59+
try {
60+
expressionString.append(variable.getName());
61+
expressionString.append("."); //$NON-NLS-1$
62+
} catch (DebugException e1) {
63+
DebugUIPlugin.log(e1);
64+
}
65+
}
66+
expressionString.deleteCharAt(expressionString.length() - 1);
67+
createWatchExpression(expressionString.toString());
68+
} else {
69+
Object element = path.getFirstSegment();
70+
createExpression(element);
71+
}
72+
showExpressionsView();
5773
}
5874
}
5975
return null;
@@ -96,9 +112,13 @@ private void createExpression(Object element) {
96112
DebugUIPlugin.errorDialog(DebugUIPlugin.getShell(), ActionMessages.WatchAction_0, ActionMessages.WatchAction_1, e); //
97113
return;
98114
}
115+
createWatchExpression(expressionString);
116+
showExpressionsView();
117+
}
99118

119+
private void createWatchExpression(String expressionString) {
100120
IWatchExpression expression;
101-
expression = DebugPlugin.getDefault().getExpressionManager().newWatchExpression(expressionString);
121+
expression = DebugPlugin.getDefault().getExpressionManager().newWatchExpression(expressionString);
102122
DebugPlugin.getDefault().getExpressionManager().addExpression(expression);
103123
IAdaptable object = DebugUITools.getDebugContext();
104124
IDebugElement context = null;
@@ -108,10 +128,8 @@ private void createExpression(Object element) {
108128
context = ((ILaunch) object).getDebugTarget();
109129
}
110130
expression.setExpressionContext(context);
111-
showExpressionsView();
112131
}
113132

114-
115133
/**
116134
* Returns the factory adapter for the given variable or <code>null</code> if none.
117135
*

debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/expression/ExpressionDropAdapter.java

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2007, 2013 IBM Corporation and others.
2+
* Copyright (c) 2007, 2025 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
@@ -23,6 +23,7 @@
2323
import org.eclipse.core.runtime.IAdaptable;
2424
import org.eclipse.core.runtime.IStatus;
2525
import org.eclipse.core.runtime.Status;
26+
import org.eclipse.debug.core.DebugException;
2627
import org.eclipse.debug.core.DebugPlugin;
2728
import org.eclipse.debug.core.IExpressionManager;
2829
import org.eclipse.debug.core.ILaunch;
@@ -40,6 +41,8 @@
4041
import org.eclipse.debug.ui.actions.IWatchExpressionFactoryAdapterExtension;
4142
import org.eclipse.jface.util.LocalSelectionTransfer;
4243
import org.eclipse.jface.viewers.IStructuredSelection;
44+
import org.eclipse.jface.viewers.TreePath;
45+
import org.eclipse.jface.viewers.TreeSelection;
4346
import org.eclipse.jface.viewers.ViewerDropAdapter;
4447
import org.eclipse.swt.dnd.DND;
4548
import org.eclipse.swt.dnd.DropTargetEvent;
@@ -373,19 +376,28 @@ private boolean performExpressionDrop(IStructuredSelection selection) {
373376
*/
374377
private boolean performVariableOrWatchAdaptableDrop(IStructuredSelection selection) {
375378
List<IExpression> expressions = new ArrayList<>(selection.size());
376-
for (Iterator<?> itr = selection.iterator(); itr.hasNext();) {
377-
Object element = itr.next();
378-
String expressionText = createExpressionString(element);
379-
if (expressionText != null){
380-
IExpression expression = createExpression(expressionText);
381-
if (expression != null){
382-
expressions.add(expression);
379+
IExpression expression;
380+
if (selection instanceof TreeSelection treeSelection) {
381+
for (TreePath path : treeSelection.getPaths()) {
382+
if (path.getSegmentCount() > 1) {
383+
StringBuilder expressionString = new StringBuilder();
384+
for (int e = 0; e < path.getSegmentCount(); e++) {
385+
IVariable variable = (IVariable) path.getSegment(e);
386+
try {
387+
expressionString.append(variable.getName());
388+
expressionString.append("."); //$NON-NLS-1$
389+
} catch (DebugException e1) {
390+
DebugUIPlugin.log(e1);
391+
}
392+
}
393+
expressionString.deleteCharAt(expressionString.length() - 1);
394+
expression = createExpression(expressionString.toString());
383395
} else {
384-
DebugUIPlugin.log(new Status(IStatus.ERROR,DebugUIPlugin.getUniqueIdentifier(),"Drop failed. Watch expression could not be created for the text " + expressionText)); //$NON-NLS-1$
385-
return false;
396+
Object element = path.getFirstSegment();
397+
String expressionText = createExpressionString(element);
398+
expression = createExpression(expressionText);
386399
}
387-
} else {
388-
return false;
400+
expressions.add(expression);
389401
}
390402
}
391403
if (expressions.size() == selection.size()){

0 commit comments

Comments
 (0)