Bug 540325: [R-Debug] Improve support for breakpoints in nested functions
Change-Id: I3b490a0158db574ef49be2bc32b6704ab58dc4df
diff --git a/r/org.eclipse.statet.r.core/src/org/eclipse/statet/r/core/rsource/ast/RAst.java b/r/org.eclipse.statet.r.core/src/org/eclipse/statet/r/core/rsource/ast/RAst.java
index 91599d2..574de23 100644
--- a/r/org.eclipse.statet.r.core/src/org/eclipse/statet/r/core/rsource/ast/RAst.java
+++ b/r/org.eclipse.statet.r.core/src/org/eclipse/statet/r/core/rsource/ast/RAst.java
@@ -17,6 +17,7 @@
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.List;
import org.eclipse.core.runtime.OperationCanceledException;
@@ -707,23 +708,23 @@
// part of parent element
case SUB_INDEXED_ARGS:
if (parent == baseNode) {
- break;
+ continue;
}
topdown.add(parent.getChildIndex(node) + 3);
- node= parent.getRParent();
- break;
+ node= parent.getRParent();
+ continue;
case C_IN:
case F_CALL_ARGS:
if (parent == baseNode) {
- break;
+ continue;
}
topdown.add(parent.getChildIndex(node) + 2);
- node= parent.getRParent();
- break;
+ node= parent.getRParent();
+ continue;
- case SUB_INDEXED_ARG:
- case F_DEF_ARG:
- case F_CALL_ARG:
+ case SUB_INDEXED_ARG: // -> ARGS
+ case F_DEF_ARG: // -> ARGS
+ case F_CALL_ARG: // -> ARGS
node= parent;
continue;
@@ -744,6 +745,75 @@
return path;
}
+ public static List<RAstNode> computeRExpressionNodes(RAstNode node, final RAstNode baseNode) {
+ final List<RAstNode> nodes= new ArrayList<>();
+ while (node != baseNode) {
+ switch (node.getNodeType()) {
+
+ // list
+ case SOURCELINES:
+ // [[1]]= name
+ case F_CALL:
+ case BLOCK:
+ case GROUP:
+ case SUB_INDEXED_S:
+ case SUB_INDEXED_D:
+ case NS_GET:
+ case NS_GET_INT:
+ case SUB_NAMED_PART:
+ case SUB_NAMED_SLOT:
+ case POWER:
+ case SIGN:
+ case SEQ:
+ case SPECIAL:
+ case MULT:
+ case ADD:
+ case RELATIONAL:
+ case NOT:
+ case AND:
+ case OR:
+ case MODEL:
+ case A_LEFT:
+ case A_RIGHT:
+ case A_EQUALS:
+ case A_COLON:
+ case HELP:
+ case C_IF:
+ case C_FOR:
+ case C_WHILE:
+ case C_REPEAT:
+ case F_DEF:
+ case F_DEF_ARGS:
+ nodes.add(node);
+ node= node.getRParent();
+ continue;
+
+ // part of parent element
+ case SUB_INDEXED_ARGS:
+ case C_IN:
+ case F_CALL_ARGS:
+
+ case SUB_INDEXED_ARG: // -> ARGS
+ case F_DEF_ARG: // -> ARGS
+ case F_CALL_ARG: // -> ARGS
+ node= node.getRParent();
+ continue;
+
+ case ERROR:
+ case ERROR_TERM:
+ case DUMMY:
+ return null;
+
+ default:
+ throw new IllegalStateException("Unexpected parent");
+ }
+ }
+ if (nodes.size() > 1) {
+ Collections.reverse(nodes);
+ }
+ return nodes;
+ }
+
public static RAstNode getRRootNode(RAstNode node, final IRegion region) {
if (region == null) {
return node.getRRoot();
diff --git a/r/org.eclipse.statet.r.debug.core/src/org/eclipse/statet/internal/r/debug/core/breakpoints/RControllerBreakpointAdapter.java b/r/org.eclipse.statet.r.debug.core/src/org/eclipse/statet/internal/r/debug/core/breakpoints/RControllerBreakpointAdapter.java
index eca23cb..c56409c 100644
--- a/r/org.eclipse.statet.r.debug.core/src/org/eclipse/statet/internal/r/debug/core/breakpoints/RControllerBreakpointAdapter.java
+++ b/r/org.eclipse.statet.r.debug.core/src/org/eclipse/statet/internal/r/debug/core/breakpoints/RControllerBreakpointAdapter.java
@@ -91,6 +91,7 @@
import org.eclipse.statet.r.nico.AbstractRDbgController.IRControllerTracepointAdapter;
import org.eclipse.statet.r.nico.IRModelSrcref;
import org.eclipse.statet.r.nico.IRSrcref;
+import org.eclipse.statet.r.nico.RSrcref;
import org.eclipse.statet.rj.data.REnvironment;
import org.eclipse.statet.rj.server.dbg.DbgEnablement;
import org.eclipse.statet.rj.server.dbg.ElementTracepointInstallationRequest;
@@ -117,14 +118,10 @@
public Position(final int type, final long id, final int[] exprIndex,
final IRLineBreakpoint breakpoint) {
- super(type, id, exprIndex, null);
+ super(type, id, exprIndex);
this.breakpoint= breakpoint;
}
- void setExprSrcref(final int @Nullable [] srcref) {
- this.exprSrcref= srcref;
- }
-
public IRLineBreakpoint getBreakpoint() {
return this.breakpoint;
}
@@ -1298,10 +1295,16 @@
if (!elementPositions.getPositions().contains(position)) {
{ final int[] elementSrcref= elementPositions.getElementSrcref();
if (elementSrcref != null) {
- final IRSrcref rExpressionSrcref= validator.computeRExpressionSrcref();
- if (rExpressionSrcref != null) {
- position.setExprSrcref(Srcref.diff(elementSrcref,
- RDbg.createRJSrcref(rExpressionSrcref) ));
+ final RSrcref[] rExpressionSrcrefs= validator.computeRExpressionSrcrefs();
+ if (rExpressionSrcrefs != null) {
+ final int [] @Nullable [] srcrefs= position.getSrcrefs();
+ for (int i= 0; i < rExpressionSrcrefs.length; i++) {
+ if (rExpressionSrcrefs[i] != null) {
+ srcrefs[i]= Srcref.substract(
+ RDbg.createRJSrcref(rExpressionSrcrefs[i]),
+ elementSrcref );
+ }
+ }
}
}
}
diff --git a/r/org.eclipse.statet.r.debug.core/src/org/eclipse/statet/r/debug/core/breakpoints/RLineBreakpointValidator.java b/r/org.eclipse.statet.r.debug.core/src/org/eclipse/statet/r/debug/core/breakpoints/RLineBreakpointValidator.java
index 6005882..7391919 100644
--- a/r/org.eclipse.statet.r.debug.core/src/org/eclipse/statet/r/debug/core/breakpoints/RLineBreakpointValidator.java
+++ b/r/org.eclipse.statet.r.debug.core/src/org/eclipse/statet/r/debug/core/breakpoints/RLineBreakpointValidator.java
@@ -15,6 +15,7 @@
package org.eclipse.statet.r.debug.core.breakpoints;
import java.lang.reflect.InvocationTargetException;
+import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
import org.eclipse.core.resources.IMarker;
@@ -597,13 +598,21 @@
}
}
- public IRSrcref computeRExpressionSrcref() throws CoreException {
+ public RSrcref @Nullable [] computeRExpressionSrcrefs() throws CoreException {
if (this.type == null) {
throw invalid();
}
if (this.astNode != null && this.baseExpressionRootNode != null) {
+ final List<RAstNode> nodes= RAst.computeRExpressionNodes(this.astNode, this.baseExpressionRootNode);
try {
- return new RSrcref(this.document, this.astNode);
+ final RSrcref[] srcrefs= new RSrcref[nodes.size()];
+ for (int i= 0; i < srcrefs.length; i++) {
+ final RAstNode node= nodes.get(i);
+ if (i == srcrefs.length - 1 || node.getNodeType() == NodeType.BLOCK) {
+ srcrefs[i]= new RSrcref(this.document, node);
+ }
+ }
+ return srcrefs;
}
catch (final BadLocationException e) {
throw failedComputing(e);