Skip to content

Commit 93fb2ba

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 4d9d68a commit 93fb2ba

File tree

2 files changed

+102
-21
lines changed

2 files changed

+102
-21
lines changed

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

Lines changed: 52 additions & 10 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, 2026 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,10 +10,12 @@
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+
import java.util.ArrayList;
18+
import java.util.List;
1719

1820
import org.eclipse.core.commands.AbstractHandler;
1921
import org.eclipse.core.commands.ExecutionEvent;
@@ -33,6 +35,8 @@
3335
import org.eclipse.debug.ui.actions.IWatchExpressionFactoryAdapter2;
3436
import org.eclipse.jface.viewers.ISelection;
3537
import org.eclipse.jface.viewers.IStructuredSelection;
38+
import org.eclipse.jface.viewers.TreePath;
39+
import org.eclipse.jface.viewers.TreeSelection;
3640
import org.eclipse.ui.IViewPart;
3741
import org.eclipse.ui.IWorkbenchPage;
3842
import org.eclipse.ui.PartInitException;
@@ -49,12 +53,39 @@ public class WatchHandler extends AbstractHandler {
4953
@Override
5054
public Object execute(ExecutionEvent event) throws ExecutionException {
5155
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);
56+
if (selection instanceof IStructuredSelection structuredSelection) {
57+
if (structuredSelection instanceof TreeSelection treeSelection) {
58+
for (TreePath path : treeSelection.getPaths()) {
59+
List<IVariable> variables = new ArrayList<>();
60+
if (path.getSegmentCount() > 1) {
61+
for (int e = 0; e < path.getSegmentCount(); e++) {
62+
IVariable variable = (IVariable) path.getSegment(e);
63+
variables.add(variable);
64+
}
65+
IWatchExpressionFactoryAdapter2 factory = getFactory2(variables);
66+
if (factory != null) {
67+
boolean canCreate = factory.canCreateWatchExpression(variables);
68+
if (canCreate) {
69+
try {
70+
String expression = factory.createWatchExpression(variables);
71+
createWatchExpression(expression);
72+
} catch (CoreException e) {
73+
DebugPlugin.log(e);
74+
break;
75+
}
76+
}
77+
}
78+
} else {
79+
Object element = path.getFirstSegment();
80+
createExpression(element);
81+
}
82+
}
83+
} else {
84+
for (Object element : structuredSelection.toArray()) {
85+
createExpression(element);
86+
}
5787
}
88+
showExpressionsView();
5889
}
5990
return null;
6091
}
@@ -96,9 +127,12 @@ private void createExpression(Object element) {
96127
DebugUIPlugin.errorDialog(DebugUIPlugin.getShell(), ActionMessages.WatchAction_0, ActionMessages.WatchAction_1, e); //
97128
return;
98129
}
130+
createWatchExpression(expressionString);
131+
}
99132

133+
private void createWatchExpression(String expressionString) {
100134
IWatchExpression expression;
101-
expression = DebugPlugin.getDefault().getExpressionManager().newWatchExpression(expressionString);
135+
expression = DebugPlugin.getDefault().getExpressionManager().newWatchExpression(expressionString);
102136
DebugPlugin.getDefault().getExpressionManager().addExpression(expression);
103137
IAdaptable object = DebugUITools.getDebugContext();
104138
IDebugElement context = null;
@@ -108,10 +142,8 @@ private void createExpression(Object element) {
108142
context = ((ILaunch) object).getDebugTarget();
109143
}
110144
expression.setExpressionContext(context);
111-
showExpressionsView();
112145
}
113146

114-
115147
/**
116148
* Returns the factory adapter for the given variable or <code>null</code> if none.
117149
*
@@ -132,6 +164,16 @@ static IWatchExpressionFactoryAdapter2 getFactory2(Object element) {
132164
if (element instanceof IAdaptable) {
133165
return ((IAdaptable)element).getAdapter(IWatchExpressionFactoryAdapter2.class);
134166
}
167+
if (element instanceof List<?> ExpressionList) {
168+
for (Object obj : ExpressionList) {
169+
if (!(obj instanceof IAdaptable)) {
170+
return null;
171+
}
172+
}
173+
if (ExpressionList.getFirst() instanceof IVariable variable) {
174+
return variable.getAdapter(IWatchExpressionFactoryAdapter2.class);
175+
}
176+
}
135177
return null;
136178
}
137179

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

Lines changed: 50 additions & 11 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, 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
@@ -40,6 +40,8 @@
4040
import org.eclipse.debug.ui.actions.IWatchExpressionFactoryAdapterExtension;
4141
import org.eclipse.jface.util.LocalSelectionTransfer;
4242
import org.eclipse.jface.viewers.IStructuredSelection;
43+
import org.eclipse.jface.viewers.ITreeSelection;
44+
import org.eclipse.jface.viewers.TreePath;
4345
import org.eclipse.jface.viewers.ViewerDropAdapter;
4446
import org.eclipse.swt.dnd.DND;
4547
import org.eclipse.swt.dnd.DropTargetEvent;
@@ -373,19 +375,46 @@ private boolean performExpressionDrop(IStructuredSelection selection) {
373375
*/
374376
private boolean performVariableOrWatchAdaptableDrop(IStructuredSelection selection) {
375377
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);
378+
IExpression expression;
379+
if (selection instanceof ITreeSelection treeSelection) {
380+
for (TreePath path : treeSelection.getPaths()) {
381+
List<IVariable> variables = new ArrayList<>();
382+
expression = null;
383+
if (path.getSegmentCount() > 1) {
384+
for (int e = 0; e < path.getSegmentCount(); e++) {
385+
IVariable variable = (IVariable) path.getSegment(e);
386+
variables.add(variable);
387+
}
388+
IWatchExpressionFactoryAdapter2 factory = getFactory2(variables);
389+
if (factory != null) {
390+
boolean canCreate = factory.canCreateWatchExpression(variables);
391+
if (canCreate) {
392+
try {
393+
String expressionText = factory.createWatchExpression(variables);
394+
expression = createExpression(expressionText);
395+
expressions.add(expression);
396+
} catch (CoreException e) {
397+
DebugPlugin.log(e);
398+
break;
399+
}
400+
}
401+
}
383402
} 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$
403+
Object element = path.getFirstSegment();
404+
String expressionText = createExpressionString(element);
405+
if (expressionText == null) {
406+
return false;
407+
}
408+
expressions.add(createExpression(expressionText));
409+
}
410+
}
411+
} else {
412+
for (Object element : selection) {
413+
String expressionText = createExpressionString(element);
414+
if (expressionText == null) {
385415
return false;
386416
}
387-
} else {
388-
return false;
417+
expressions.add(createExpression(expressionText));
389418
}
390419
}
391420
if (expressions.size() == selection.size()){
@@ -498,6 +527,16 @@ private IWatchExpressionFactoryAdapter2 getFactory2(Object element) {
498527
if (element instanceof IAdaptable) {
499528
return ((IAdaptable)element).getAdapter(IWatchExpressionFactoryAdapter2.class);
500529
}
530+
if (element instanceof List<?> ExpressionList) {
531+
for (Object obj : ExpressionList) {
532+
if (!(obj instanceof IAdaptable)) {
533+
return null;
534+
}
535+
}
536+
if (ExpressionList.getFirst() instanceof IVariable variable) {
537+
return variable.getAdapter(IWatchExpressionFactoryAdapter2.class);
538+
}
539+
}
501540
return null;
502541
}
503542

0 commit comments

Comments
 (0)