diff options
-rw-r--r-- | plugins/org.eclipse.xtend.ui/src/org/eclipse/xtend/ui/debug/ExpressionPluginAdapter.java | 291 |
1 files changed, 168 insertions, 123 deletions
diff --git a/plugins/org.eclipse.xtend.ui/src/org/eclipse/xtend/ui/debug/ExpressionPluginAdapter.java b/plugins/org.eclipse.xtend.ui/src/org/eclipse/xtend/ui/debug/ExpressionPluginAdapter.java index 7d06f592..075d1b60 100644 --- a/plugins/org.eclipse.xtend.ui/src/org/eclipse/xtend/ui/debug/ExpressionPluginAdapter.java +++ b/plugins/org.eclipse.xtend.ui/src/org/eclipse/xtend/ui/debug/ExpressionPluginAdapter.java @@ -15,9 +15,11 @@ import static org.eclipse.internal.xtend.expression.debug.ExpressionElementAdapt import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; +import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Set; +import java.util.Stack; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; @@ -34,6 +36,7 @@ import org.eclipse.internal.xtend.expression.ast.BooleanOperation; import org.eclipse.internal.xtend.expression.ast.Case; import org.eclipse.internal.xtend.expression.ast.Cast; import org.eclipse.internal.xtend.expression.ast.ChainExpression; +import org.eclipse.internal.xtend.expression.ast.CollectionExpression; import org.eclipse.internal.xtend.expression.ast.Expression; import org.eclipse.internal.xtend.expression.ast.FeatureCall; import org.eclipse.internal.xtend.expression.ast.ISyntaxElement; @@ -120,6 +123,8 @@ public class ExpressionPluginAdapter implements PluginAdapter { public IBreakpoint checkBreakpoints(IBreakpoint[] bps, IResource resource, int start, int end, int line) throws CoreException { ISyntaxElement element = findElementForPosition(resource, start, line); + if(element == null) return null; + for (IBreakpoint bp1 : bps) { MWEBreakpoint bp = (MWEBreakpoint) bp1; if (bp.getResource().equals(resource.getFullPath().toString()) @@ -145,158 +150,196 @@ public class ExpressionPluginAdapter implements PluginAdapter { } else if (body instanceof LetExpression) { return getContainingElementOfLetExpression((LetExpression) body, position); + } else if (body instanceof IfExpression) { + return getContainingElementOfIfExpression((IfExpression) body, position); } else - return body; + return getContainingElement((SyntaxElement)body,position); } - private boolean contains(final ISyntaxElement elem, final int position) { - return elem.getStart() <= position && elem.getEnd() >= position; + private boolean containsPosition(final ISyntaxElement elem, final int position) { + return elem.getStart() <= position && elem.getEnd() > position; + } + + /** + * @since 2.2 + */ + protected int shiftPositionIfInside(final int currentPosition, + final SyntaxElement lowerBound, final SyntaxElement upperBound) { + return currentPosition >= lowerBound.getStart() + && currentPosition <= upperBound.getStart() ? upperBound + .getStart() : currentPosition; } - private ISyntaxElement getContainingElement(final SyntaxElement se, final int position) { - if (se instanceof ChainExpression) + /** + * @since 2.2 + */ + protected ISyntaxElement getContainingElement(final SyntaxElement se, final int position) { + if (!containsPosition(se, position)) return null; + + if ( se instanceof ChainExpression ) return getContainingElementOfChainExpression((ChainExpression) se, position); - else if (se instanceof LetExpression) { + else if ( se instanceof LetExpression ) { return getContainingElementOfLetExpression((LetExpression) se, position); - } else if (se instanceof SwitchExpression) { + } else if ( se instanceof SwitchExpression ) { return getContainingElementOfSwitchExpression((SwitchExpression) se, position); - } else if (se instanceof ListLiteral) { + } else if ( se instanceof ListLiteral ) { return getContainingElementOfListLiteral((ListLiteral) se, position); - } else if (se instanceof IfExpression) { - return getContainingElementOfIfExpression((IfExpression) se, position); + } else if ( se instanceof IfExpression ) { + return getContainingElementOfIfExpression((IfExpression) se, position ); + } else if ( se instanceof CollectionExpression ) { + return getContainingElementOfCollectionExpression((CollectionExpression)se, position); + } else if ( se instanceof BooleanOperation ) { + return getContainingElementOfBooleanOperation( (BooleanOperation)se, position ); + } else if ( se instanceof FeatureCall ) { + return getContainingElementOfFeatureCall( (FeatureCall)se, position ); } - if (contains(se, position)) - return se; - return null; } - - private ISyntaxElement getContainingElementOfLetExpression(final LetExpression le, int position) { + + /** + * @since 2.2 + */ + protected ISyntaxElement getContainingChild(final SyntaxElement parent, final Collection<SyntaxElement> children, int position) { + if(!containsPosition(parent, position)) return null; + ISyntaxElement result = null; - - // if bp is in "let varname = "varexpr ... we have to shift start and - // end. - position = shiftPositionIfInside(position, le, le.getVarExpression()); - - result = getContainingElement(le.getVarExpression(), position); - if (result != null) - return result; - - result = getContainingElement(le.getTargetExpression(), position); - if (result != null) - return result; - - return null; + int newPosition = position; + SyntaxElement lastElem = parent; + for( SyntaxElement child : children) { + if( child == null ) continue; + fixBoundaries(child); + if( child.getEnd()==0 ) { + System.out.println(child.getClass().getSimpleName() + " " + child.toString()); + } + + newPosition = shiftPositionIfInside(newPosition, lastElem, child); + + result = getContainingElement(child, newPosition); + if(result != null) return result; + lastElem = child; + } + + return parent; + } + + private ISyntaxElement getContainingElementOfLetExpression(final LetExpression le, int position) { + List<SyntaxElement> children = new ArrayList<SyntaxElement>(); + children.add(le.getVarExpression()); + children.add(le.getTargetExpression()); + return getContainingChild(le, children, position); } private ISyntaxElement getContainingElementOfIfExpression(final IfExpression ie, int position) { - ISyntaxElement result = null; - - // if bp is in "if( expr ) "... we have to shift start and end. - position = shiftPositionIfInside(position, ie, ie.getCondition()); - - result = getContainingElement(ie.getCondition(), position); - if (result != null) - return result; - - result = getContainingElement(ie.getThenPart(), position); - if (result != null) - return result; - - if (ie.getElsePart() != null) { - result = getContainingElement(ie.getElsePart(), position); - if (result != null) - return result; + List<SyntaxElement> children = new ArrayList<SyntaxElement>(); + children.add(ie.getCondition()); + children.add(ie.getThenPart()); + children.add(ie.getElsePart()); + return getContainingChild(ie, children, position); + } + + private ISyntaxElement getContainingElementOfCollectionExpression(final CollectionExpression ce, int position ) { + List<SyntaxElement> children = new ArrayList<SyntaxElement>(); + children.add(ce.getClosure()); + return getContainingChild(ce, children, position); + } + + private SyntaxElement fixBoundaries(SyntaxElement e) { + if( !( e.getStart() == 0 && e.getEnd() == 0) ) + return e; + + if( e instanceof BooleanOperation ) { + BooleanOperation be = (BooleanOperation)e; + SyntaxElement l = fixBoundaries(be.getLeft()); + SyntaxElement r = fixBoundaries(be.getRight()); + be.setLine(l.getLine()); + be.setStart(l.getStart()); + be.setEnd(r.getEnd()); } - - return null; + + return e; } - - private int shiftPositionIfInside(final int currentPosition, - final SyntaxElement lowerBound, final SyntaxElement upperBound) { - return lowerBound.getLine() == upperBound.getLine() - && currentPosition >= lowerBound.getStart() - && currentPosition <= upperBound.getStart() ? upperBound - .getStart() : currentPosition; + + private ISyntaxElement getContainingElementOfBooleanOperation( final BooleanOperation be, int position ) { + fixBoundaries(be); + + List<SyntaxElement> children = new ArrayList<SyntaxElement>(); + children.add(be.getLeft()); + children.add(be.getRight()); + return getContainingChild(be, children, position); } - - private ISyntaxElement getContainingElementOfListLiteral(final ListLiteral ll, int position) { - - List<Expression> list = ll.getElementsAsList(); - - // if bp is in "{ "... we have to shift start and end. - if (list.size() > 0) { - Expression firstElem = list.get(0); - if (ll.getStart() <= position && firstElem.getStart() > position) { - position = firstElem.getStart(); + + private ISyntaxElement getContainingElementOfFeatureCall( final FeatureCall fe, int position ) { + if(!containsPosition(fe,position)) + return null; + + Stack<FeatureCall> fcStack = new Stack<FeatureCall>(); + Expression e = fe; + do { + FeatureCall fc = (FeatureCall)e; + fcStack.push(fc); + e = fc.getTarget(); + } while( e instanceof FeatureCall ); + + FeatureCall fallback = fcStack.peek(); + + while( !fcStack.isEmpty() ) { + FeatureCall fc = fcStack.pop(); + if(fc instanceof OperationCall) { + ISyntaxElement result = getContainingElementOfOperationCall((OperationCall)fc, position); + if(result != null) + return result; + } else if( fc instanceof CollectionExpression) { + if(containsPosition(fc, position) ) return getContainingElement(((CollectionExpression)fc).getClosure(),position); } } - - for (Expression item : list) { - ISyntaxElement result = getContainingElement(item, position); - if (result != null) - return result; + + return fallback; + } + + private ISyntaxElement getContainingElementOfOperationCall( final OperationCall oe, int position ) { + if(isFunctionCall(oe)) return oe; + List<SyntaxElement> children = new ArrayList<SyntaxElement>(oe.getParamsAsList()); + return getContainingChild(oe, children, position); + } + + private boolean isFunctionCall(OperationCall op) { + char[] name = op.getName().toString().toCharArray(); + + if( name.length == 0 ) return false; + + for( int i=0; i<name.length; i++ ) { + if(i==0) { + if(!Character.isJavaIdentifierStart(name[i])) return false; + } else{ + if(!Character.isJavaIdentifierPart(name[i])) return false; + } } + + return true; + } - return null; + private ISyntaxElement getContainingElementOfListLiteral(final ListLiteral ll, int position) { + List<SyntaxElement> children = new ArrayList<SyntaxElement>(ll.getElementsAsList()); + return getContainingChild(ll, children, position); } private ISyntaxElement getContainingElementOfSwitchExpression(final SwitchExpression se, int position) { - ISyntaxElement result = null; - - Expression firstCaseExpression; - // if bp is in "switch(expr) { case expr: "... we have to shift start - // and end. - if (se.getCases().size() > 0) - firstCaseExpression = se.getCases().get(0).getThenPart(); - else - firstCaseExpression = se.getDefaultExpr(); - - position = shiftPositionIfInside(position, se, firstCaseExpression); - + List<SyntaxElement> children = new ArrayList<SyntaxElement>(); + children.add(se.getSwitchExpr()); for (Case caze : se.getCases()) { - result = getContainingElement(caze.getThenPart(), position); - if (result != null) - return result; + children.add(caze.getCondition()); + children.add(caze.getThenPart()); } - result = getContainingElement(se.getDefaultExpr(), position); - if (result != null) - return result; - - return null; + children.add(se.getDefaultExpr()); + return getContainingChild(se, children, position); } private ISyntaxElement getContainingElementOfChainExpression(final ChainExpression ce, final int position) { - - ISyntaxElement result = null; - result = getRootOperationCall(getContainingElement(ce.getFirst(), position)); - if (result != null) - return result; - - result = getRootOperationCall(getContainingElement(ce.getNext(), position)); - if (result != null) - return result; - - return null; - } - - /** - * returns the first operationcall of a call chain ie: for fn3 of - * a.b.fn1().fn2().fn3() this will return fn1(). - */ - private ISyntaxElement getRootOperationCall(final ISyntaxElement element) { - ISyntaxElement result = element; - - if (element instanceof OperationCall) { - Expression target = ((OperationCall) element).getTarget(); - while (target != null && target instanceof OperationCall) { - result = target; - target = ((OperationCall) target).getTarget(); - } - } - - return result; + List<SyntaxElement> children = new ArrayList<SyntaxElement>(); + children.add(ce.getFirst()); + children.add(ce.getNext()); + return getContainingChild(ce, children, position); } /** @@ -307,7 +350,7 @@ public class ExpressionPluginAdapter implements PluginAdapter { IXtendXpandResource file = getXtendXpandResource(resource); List<ISyntaxElement> elems = collectFirstLevelElements(file); for (ISyntaxElement elem : elems) - if (contains(elem, position)) + if (containsPosition(elem, position)) return elem; return null; @@ -348,8 +391,10 @@ public class ExpressionPluginAdapter implements PluginAdapter { return result; } - - private ISyntaxElement getBodyOfRootElement(final ISyntaxElement elem) { + /** + * @since 2.2 + */ + protected ISyntaxElement getBodyOfRootElement(final ISyntaxElement elem) { if (elem instanceof ExpressionExtensionStatement) return ((ExpressionExtensionStatement) elem).getExpression(); else if (elem instanceof CreateExtensionStatement) |