Search in sources :

Example 1 with SyntheticCompositeNode

use of org.eclipse.xtext.nodemodel.impl.SyntheticCompositeNode in project xtext-core by eclipse.

the class NodeModelUtilsTest method testFindLeafNodeAtOffset_1.

@Test
public void testFindLeafNodeAtOffset_1() throws Exception {
    String grammarText = "grammar foo.Bar with org.eclipse.xtext.common.Terminals generate foo 'bar' Model : (name=ID value=ID);";
    Grammar grammar = (Grammar) getModel(grammarText);
    int equalsSign = grammarText.indexOf('=');
    ICompositeNode grammarNode = NodeModelUtils.getNode(grammar);
    ILeafNode leafNodeAtOffset = NodeModelUtils.findLeafNodeAtOffset(grammarNode, equalsSign);
    assertEquals("=", leafNodeAtOffset.getText());
    boolean syntheticNodeSeen = false;
    INode parent = leafNodeAtOffset.getParent();
    while (parent != null) {
        // walk up the tree to make sure we call #findLeafNodeAtOffset with synthetic nodes, too
        ILeafNode otherLeafNode = NodeModelUtils.findLeafNodeAtOffset(parent, equalsSign);
        assertSame(leafNodeAtOffset, otherLeafNode);
        if (parent instanceof SyntheticCompositeNode)
            syntheticNodeSeen = true;
        parent = parent.getParent();
    }
    assertTrue(syntheticNodeSeen);
}
Also used : SyntheticCompositeNode(org.eclipse.xtext.nodemodel.impl.SyntheticCompositeNode) INode(org.eclipse.xtext.nodemodel.INode) ILeafNode(org.eclipse.xtext.nodemodel.ILeafNode) ICompositeNode(org.eclipse.xtext.nodemodel.ICompositeNode) Grammar(org.eclipse.xtext.Grammar) Test(org.junit.Test)

Example 2 with SyntheticCompositeNode

use of org.eclipse.xtext.nodemodel.impl.SyntheticCompositeNode in project xtext-core by eclipse.

the class TreeIteratorTest method testTreeIteratorForSyntheticNodes_Forward.

@Test
public void testTreeIteratorForSyntheticNodes_Forward() throws Exception {
    EObject object = getModel("(d - e) / e * d // fasdf s");
    ICompositeNode root = NodeModelUtils.getNode(object).getRootNode();
    INode firstChild = root.getFirstChild();
    INode firstGrandChild = ((ICompositeNode) firstChild).getFirstChild();
    INode firstGrandGrandChild = ((ICompositeNode) firstGrandChild).getFirstChild();
    INode firstGrandGrandGrandChild = ((ICompositeNode) firstGrandGrandChild).getFirstChild();
    INode synthetic = ((ICompositeNode) firstGrandGrandGrandChild).getFirstChild();
    assertTrue(synthetic instanceof SyntheticCompositeNode);
    INode expectedLastChild = ((ICompositeNode) synthetic).getLastChild();
    while (expectedLastChild instanceof ICompositeNode) expectedLastChild = ((ICompositeNode) expectedLastChild).getLastChild();
    INode lastChild = null;
    for (INode child : synthetic.getAsTreeIterable()) lastChild = child;
    assertEquals(expectedLastChild, lastChild);
}
Also used : SyntheticCompositeNode(org.eclipse.xtext.nodemodel.impl.SyntheticCompositeNode) EObject(org.eclipse.emf.ecore.EObject) Test(org.junit.Test)

Example 3 with SyntheticCompositeNode

use of org.eclipse.xtext.nodemodel.impl.SyntheticCompositeNode in project xtext-core by eclipse.

the class TreeIteratorTest method testTreeIteratorForSyntheticNodes_Backwards.

@Test
public void testTreeIteratorForSyntheticNodes_Backwards() throws Exception {
    EObject object = getModel("d - e / e * d");
    ICompositeNode root = NodeModelUtils.getNode(object).getRootNode();
    INode firstChild = root.getFirstChild();
    INode firstGrandChild = ((ICompositeNode) firstChild).getFirstChild();
    INode sibling = firstGrandChild.getNextSibling().getNextSibling().getNextSibling();
    INode siblingChild = ((ICompositeNode) sibling).getFirstChild();
    INode siblingGrandChild = ((ICompositeNode) siblingChild).getFirstChild();
    INode synthetic = ((ICompositeNode) siblingGrandChild).getFirstChild();
    assertTrue(synthetic instanceof SyntheticCompositeNode);
    INode expectedFirstChild = ((ICompositeNode) synthetic).getFirstChild();
    while (expectedFirstChild instanceof ICompositeNode) expectedFirstChild = ((ICompositeNode) expectedFirstChild).getFirstChild();
    INode actualFirstChild = null;
    for (INode child : synthetic.getAsTreeIterable().reverse()) actualFirstChild = child;
    assertEquals(expectedFirstChild, actualFirstChild);
}
Also used : SyntheticCompositeNode(org.eclipse.xtext.nodemodel.impl.SyntheticCompositeNode) EObject(org.eclipse.emf.ecore.EObject) Test(org.junit.Test)

Example 4 with SyntheticCompositeNode

use of org.eclipse.xtext.nodemodel.impl.SyntheticCompositeNode in project n4js by eclipse.

the class OutlineXpectMethod method skipNodesInBetween.

private void skipNodesInBetween(Script script) throws Exception {
    if (script != null) {
        XtextResource resource = (XtextResource) script.eResource();
        ICompositeNode rootNode = resource.getParseResult().getRootNode();
        ReplaceRegion region = null;
        for (INode node : rootNode.getAsTreeIterable()) {
            if (node instanceof ICompositeNode && !(node instanceof SyntheticCompositeNode)) {
                ICompositeNode casted = (ICompositeNode) node;
                int offset = node.getTotalOffset();
                int length = node.getTotalLength();
                if (length != 0) {
                    if (casted.getFirstChild().equals(casted.getLastChild())) {
                        if (region == null || region.getOffset() != offset || region.getLength() != length) {
                            region = new ReplaceRegion(offset, length, "");
                            StringBuilder builder = new StringBuilder(rootNode.getText());
                            region.applyTo(builder);
                            processFile(builder.toString(), "skipNodesInBetween");
                        }
                    }
                }
            }
        }
    }
}
Also used : SyntheticCompositeNode(org.eclipse.xtext.nodemodel.impl.SyntheticCompositeNode) INode(org.eclipse.xtext.nodemodel.INode) ReplaceRegion(org.eclipse.xtext.util.ReplaceRegion) ICompositeNode(org.eclipse.xtext.nodemodel.ICompositeNode) XtextResource(org.eclipse.xtext.resource.XtextResource)

Example 5 with SyntheticCompositeNode

use of org.eclipse.xtext.nodemodel.impl.SyntheticCompositeNode in project xtext-core by eclipse.

the class PartialParsingHelper method reparse.

@Override
@SuppressWarnings({ "unchecked", "rawtypes" })
public IParseResult reparse(IParser parser, IParseResult previousParseResult, ReplaceRegion changedRegion) {
    if (parser == null)
        throw new NullPointerException("parser may not be null");
    if (previousParseResult == null) {
        throw new NullPointerException("previousParseResult and previousParseResult.rootNode may not be null");
    }
    ICompositeNode oldRootNode = previousParseResult.getRootNode();
    if (changedRegion.getEndOffset() > oldRootNode.getTotalLength()) {
        log.error("Invalid " + changedRegion + " originalLength=" + oldRootNode.getTotalLength());
        return fullyReparse(parser, previousParseResult, changedRegion);
    }
    if (changedRegion.getOffset() >= oldRootNode.getTotalLength() && changedRegion.getText().trim().length() == 0) {
        return fullyReparse(parser, previousParseResult, changedRegion);
    }
    ReplaceRegion replaceRegion;
    if (tokenRegionProvider != null) {
        replaceRegion = tokenRegionProvider.getTokenReplaceRegion(insertChangeIntoReplaceRegion(oldRootNode, changedRegion), changedRegion);
    } else {
        replaceRegion = changedRegion;
    }
    if (isNullEdit(oldRootNode, replaceRegion)) {
        return previousParseResult;
    }
    PartialParsingPointers parsingPointers = calculatePartialParsingPointers(previousParseResult, replaceRegion.getOffset(), replaceRegion.getLength());
    List<ICompositeNode> validReplaceRootNodes = parsingPointers.getValidReplaceRootNodes();
    ICompositeNode oldCompositeNode = null;
    String reparseRegion = "";
    for (int i = validReplaceRootNodes.size() - 1; i >= 0; --i) {
        oldCompositeNode = validReplaceRootNodes.get(i);
        if (!(oldCompositeNode instanceof SyntheticCompositeNode) && !isRangePartOfExceedingLookAhead((CompositeNode) oldCompositeNode, replaceRegion)) {
            boolean replaceAtEnd = oldCompositeNode.getTotalEndOffset() == replaceRegion.getEndOffset();
            reparseRegion = insertChangeIntoReplaceRegion(oldCompositeNode, replaceRegion);
            if (!"".equals(reparseRegion)) {
                if (!replaceAtEnd || !Character.isWhitespace(reparseRegion.charAt(reparseRegion.length() - 1))) {
                    if (log.isDebugEnabled()) {
                        log.debug("replace region: [" + oldCompositeNode.getTotalOffset() + " / length: " + oldCompositeNode.getTotalLength() + " of [" + oldRootNode.getTotalOffset() + " / lenght: " + oldRootNode.getTotalLength() + "]");
                    }
                    break;
                }
            }
        }
    }
    if (oldCompositeNode == null || reparseRegion.equals("") || oldCompositeNode == oldRootNode) {
        return fullyReparse(parser, previousParseResult, replaceRegion);
    }
    EObject entryRuleOrRuleCall = parsingPointers.findEntryRuleOrRuleCall(oldCompositeNode);
    IParseResult newParseResult = null;
    try {
        if (entryRuleOrRuleCall instanceof RuleCall)
            newParseResult = parser.parse((RuleCall) entryRuleOrRuleCall, new StringReader(reparseRegion), oldCompositeNode.getLookAhead());
        else
            newParseResult = parser.parse((ParserRule) entryRuleOrRuleCall, new StringReader(reparseRegion));
    } catch (ParseException exc) {
    }
    if (newParseResult == null || newParseResult.hasSyntaxErrors()) {
        // on error fully reparse
        return fullyReparse(parser, previousParseResult, replaceRegion);
    }
    if (oldRootNode.equals(oldCompositeNode)) {
        unloadSemanticObject(previousParseResult.getRootASTElement());
        return newParseResult;
    }
    EObject oldSemanticParentElement = oldCompositeNode.getParent().getSemanticElement();
    EObject oldSemanticElement = null;
    if (oldCompositeNode.hasDirectSemanticElement()) {
        oldSemanticElement = oldCompositeNode.getSemanticElement();
    } else {
        List<ICompositeNode> nodesEnclosingRegion = parsingPointers.getNodesEnclosingRegion();
        for (int i = nodesEnclosingRegion.size() - 1; i >= 0; --i) {
            ICompositeNode enclosingNode = nodesEnclosingRegion.get(i);
            if (enclosingNode == oldCompositeNode) {
                break;
            }
            if (enclosingNode.hasDirectSemanticElement())
                oldSemanticElement = enclosingNode.getSemanticElement();
        }
        if (oldSemanticElement == null)
            return fullyReparse(parser, previousParseResult, replaceRegion);
    }
    if (oldSemanticElement == oldSemanticParentElement) {
        throw new IllegalStateException("oldParent == oldElement");
    }
    if (oldSemanticParentElement != null) {
        EStructuralFeature feature = oldSemanticElement.eContainingFeature();
        if (feature == null)
            return fullyReparse(parser, previousParseResult, replaceRegion);
        oldSemanticParentElement = oldSemanticElement.eContainer();
        if (feature.isMany()) {
            List featureValueList = (List) oldSemanticParentElement.eGet(feature);
            int index = featureValueList.indexOf(oldSemanticElement);
            unloadSemanticObject(oldSemanticElement);
            EObject newSemanticObject = newParseResult.getRootASTElement();
            if (newSemanticObject != null) {
                featureValueList.set(index, newParseResult.getRootASTElement());
            } else {
                featureValueList.remove(index);
            }
        } else {
            unloadSemanticObject(oldSemanticElement);
            oldSemanticParentElement.eSet(feature, newParseResult.getRootASTElement());
        }
        ((ParseResult) newParseResult).setRootASTElement(previousParseResult.getRootASTElement());
    } else {
        unloadSemanticObject(oldSemanticElement);
    }
    if (oldCompositeNode != oldRootNode) {
        nodeModelBuilder.replaceAndTransferLookAhead(oldCompositeNode, newParseResult.getRootNode());
        ((ParseResult) newParseResult).setRootNode(oldRootNode);
        StringBuilder builder = new StringBuilder(oldRootNode.getText());
        replaceRegion.applyTo(builder);
        nodeModelBuilder.setCompleteContent(oldRootNode, builder.toString());
    }
    return newParseResult;
}
Also used : SyntheticCompositeNode(org.eclipse.xtext.nodemodel.impl.SyntheticCompositeNode) ParseResult(org.eclipse.xtext.parser.ParseResult) IParseResult(org.eclipse.xtext.parser.IParseResult) EStructuralFeature(org.eclipse.emf.ecore.EStructuralFeature) RuleCall(org.eclipse.xtext.RuleCall) ReplaceRegion(org.eclipse.xtext.util.ReplaceRegion) EObject(org.eclipse.emf.ecore.EObject) StringReader(java.io.StringReader) ICompositeNode(org.eclipse.xtext.nodemodel.ICompositeNode) ArrayList(java.util.ArrayList) List(java.util.List) IParseResult(org.eclipse.xtext.parser.IParseResult) ParseException(org.eclipse.xtext.parser.ParseException)

Aggregations

SyntheticCompositeNode (org.eclipse.xtext.nodemodel.impl.SyntheticCompositeNode)8 ICompositeNode (org.eclipse.xtext.nodemodel.ICompositeNode)6 EObject (org.eclipse.emf.ecore.EObject)4 INode (org.eclipse.xtext.nodemodel.INode)4 ReplaceRegion (org.eclipse.xtext.util.ReplaceRegion)4 RuleCall (org.eclipse.xtext.RuleCall)3 Test (org.junit.Test)3 StringReader (java.io.StringReader)2 ArrayList (java.util.ArrayList)2 List (java.util.List)2 EStructuralFeature (org.eclipse.emf.ecore.EStructuralFeature)2 ParserRule (org.eclipse.xtext.ParserRule)2 IParseResult (org.eclipse.xtext.parser.IParseResult)2 ParseException (org.eclipse.xtext.parser.ParseException)2 ParseResult (org.eclipse.xtext.parser.ParseResult)2 XtextResource (org.eclipse.xtext.resource.XtextResource)2 Script (org.eclipse.n4js.n4JS.Script)1 AbstractRule (org.eclipse.xtext.AbstractRule)1 Action (org.eclipse.xtext.Action)1 Grammar (org.eclipse.xtext.Grammar)1