Java Code Examples for org.eclipse.xtext.nodemodel.ILeafNode#getTotalEndOffset()

The following examples show how to use org.eclipse.xtext.nodemodel.ILeafNode#getTotalEndOffset() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: TokenSequencePreservingPartialParsingHelper.java    From xtext-extras with Eclipse Public License 2.0 6 votes vote down vote up
protected PartialParsingPointers calculatePartialParsingPointers(ICompositeNode oldRoot, ILeafNode left, ILeafNode right) {
	ICompositeNode result = right.getParent();
	while(result.getTotalOffset() > left.getTotalOffset()) {
		result = result.getParent();
	}
	List<ICompositeNode> nodesEnclosingRegion = getAllParents(result);
	Range range = new Range(left.getTotalOffset(), right.getTotalEndOffset());
	List<ICompositeNode> validReplaceRootNodes = internalFindValidReplaceRootNodeForChangeRegion(nodesEnclosingRegion);

	filterInvalidRootNodes(validReplaceRootNodes);

	if (validReplaceRootNodes.isEmpty()) {
		validReplaceRootNodes = Collections.singletonList(oldRoot);
	}
	return new PartialParsingPointers(oldRoot, range.getOffset(), range.getLength(), validReplaceRootNodes, nodesEnclosingRegion);
}
 
Example 2
Source File: AstSelectionProvider.java    From xtext-eclipse with Eclipse Public License 2.0 6 votes vote down vote up
protected ITextRegion getTextRegion(EObject eObject) {
	if (eObject == null)
		return null;
	IParseResult parseResult = ((XtextResource)eObject.eResource()).getParseResult();
	if (parseResult == null)
		return null;
	ICompositeNode rootNode = parseResult.getRootNode();
	Map<ILeafNode, EObject> comments = commentAssociater.associateCommentsWithSemanticEObjects(eObject, singleton(rootNode));
	final ITextRegion result = locationProvider.getFullTextRegion(eObject);
	int start = result.getOffset();
	int end = result.getOffset() + result.getLength();
	for (Entry<ILeafNode, EObject> entry : comments.entrySet()) {
		if (entry.getValue() == eObject) {
			ILeafNode node = entry.getKey();
			if (node.getTotalOffset() < start) {
				start = node.getTotalOffset();
			}
			if (node.getTotalEndOffset() > end) {
				end = node.getTotalEndOffset();
			}
		}
	}
	return new TextRegion(start, end-start);
}
 
Example 3
Source File: EntryPointFinder.java    From xtext-core with Eclipse Public License 2.0 6 votes vote down vote up
protected boolean shouldUseParent(ICompositeNode result, int offset, ILeafNode leaf) {
	if (leaf.getTotalEndOffset() == offset) {
		return true;
	}
	if (result.getGrammarElement() instanceof RuleCall) {
		RuleCall rc = (RuleCall) result.getGrammarElement();
		if (!rc.getArguments().isEmpty()) {
			return true;
		}
		Assignment assignment = GrammarUtil.containingAssignment(rc);
		if (assignment != null
				&& (GrammarUtil.isMultipleCardinality(assignment) || (assignment.eContainer() instanceof AbstractElement && GrammarUtil
						.isMultipleCardinality((AbstractElement) assignment.eContainer())))) {
			return true;
		}
	}
	return false;
}
 
Example 4
Source File: FormatterXpectMethod.java    From n4js with Eclipse Public License 1.0 5 votes vote down vote up
private ITextSegment findRegion(int lines, XpectInvocation inv, TargetSyntaxSupport syntax, ITextRegionAccess reg) {
	XtextResource resource = ((XtextTargetSyntaxSupport) syntax).getResource();

	IStatementRelatedRegion region2 = inv.getExtendedRegion();
	int end = region2.getOffset() + region2.getLength();
	ILeafNode node = NodeModelUtils.findLeafNodeAtOffset(resource.getParseResult().getRootNode(), end);

	int offset = node.getTotalEndOffset();
	ITextSegment region = getRegionForLines(reg, offset, lines);
	return region;
}
 
Example 5
Source File: ParamAwareEntryPointFinder.java    From n4js with Eclipse Public License 1.0 5 votes vote down vote up
@Override
protected boolean shouldUseParent(ICompositeNode result, int offset, ILeafNode leaf) {
	if (leaf.getTotalEndOffset() >= offset) {
		return true;
	}
	if (result.getGrammarElement() instanceof RuleCall) {
		RuleCall rc = (RuleCall) result.getGrammarElement();
		if (isMultipleCardinality(rc)) {
			return true;
		}
	}
	return false;
}
 
Example 6
Source File: NodeModelTokenSource.java    From n4js with Eclipse Public License 1.0 5 votes vote down vote up
/**
 * Implementation of the {@link TokenSource} interface. Return new tokens as long as there are some, afterwards
 * return {@link Token#EOF_TOKEN}.
 */
@Override
public Token nextToken() {
	if (next != null) {
		Token result = next;
		next = null;
		return result;
	}
	if (!leafNodes.hasNext()) {
		return Token.EOF_TOKEN;
	}
	ILeafNode leaf = leafNodes.next();
	if (leaf.getTotalOffset() >= endOffset) {
		leafNodes = Collections.emptyIterator();
		return Token.EOF_TOKEN;
	}
	if (leaf.getTotalEndOffset() <= startOffset) {
		return nextToken();
	}
	if (leaf.getTotalEndOffset() > endOffset) {
		return toPrefixToken(leaf);
	}
	SyntaxErrorMessage syntaxErrorMessage = leaf.getSyntaxErrorMessage();
	if (syntaxErrorMessage != null && SEMICOLON_INSERTED.equals(syntaxErrorMessage.getIssueCode())) {
		return toASIToken(leaf);
	}
	if (leaf.isHidden()) {
		return processHiddenToken(leaf);
	}
	int tokenType = tokenTypeMapper.getInternalTokenType(leaf);
	return new CommonToken(tokenType, leaf.getText());
}
 
Example 7
Source File: TokenSequencePreservingPartialParsingHelper.java    From xtext-extras with Eclipse Public License 2.0 5 votes vote down vote up
protected ILeafNode getLeftNode(Iterator<ILeafNode> leafNodes, int offset) {
	while(leafNodes.hasNext()) {
		ILeafNode leaf = leafNodes.next();
		if (leaf.getTotalEndOffset() >= offset) {
			if (leaf.getSyntaxErrorMessage() != null) {
				return null;
			}
			return leaf;
		}
	}
	return null;
}
 
Example 8
Source File: TokenSequencePreservingPartialParsingHelper.java    From xtext-extras with Eclipse Public License 2.0 5 votes vote down vote up
protected ILeafNode getRightNode(Iterator<ILeafNode> leafNodes, int offset) {
	while(leafNodes.hasNext()) {
		ILeafNode leaf = leafNodes.next();
		if (leaf.getSyntaxErrorMessage() != null) {
			return null;
		}
		if (leaf.getTotalEndOffset() > offset) {
			return leaf;
		}
	}
	return null;
}
 
Example 9
Source File: NodeModelTokenSource.java    From n4js with Eclipse Public License 1.0 4 votes vote down vote up
/**
 * Filter the nodes from the iterator that do not have any impact on the parse result.
 *
 * For now we filter mostly regions that do have lookahead 1 and are closed before the requested region starts.
 */
private Iterator<INode> filterIterator(TreeIterator<AbstractNode> iterator) {
	return new AbstractIterator<>() {
		@Override
		protected INode computeNext() {
			if (iterator.hasNext()) {
				INode result = iterator.next();
				if (result instanceof ICompositeNode) {
					ICompositeNode casted = (ICompositeNode) result;
					if (casted.getTotalEndOffset() < endOffset - 1) {
						if (casted.hasChildren() && casted.getLookAhead() == 1) {
							AbstractElement grammarElement = (AbstractElement) casted.getGrammarElement();
							// Filter script elements and member declarations to the left of the cursor position.
							if (grammarElement == scriptElementCall || grammarElement == memberDeclarationCall) {
								INode sibling = casted.getNextSibling();
								while (sibling instanceof ILeafNode) {
									ILeafNode siblingLeaf = (ILeafNode) sibling;
									if (siblingLeaf.isHidden()) {
										if (siblingLeaf.getTotalEndOffset() >= endOffset) {
											return result;
										}
									} else {
										break;
									}
									sibling = siblingLeaf.getNextSibling();
								}
								iterator.prune();

								// filter statements that are completed before the cursor position and are not
								// part of the lookahead
							} else if (grammarElement == statementsCall) {
								// check if this is in the parents lookAhead to disambiguate block from object
								// literal
								ICompositeNode parent = casted.getParent();
								if (parent.getLookAhead() > 1) {
									ILeafNode firstLeaf = Iterables.get(casted.getLeafNodes(), 0);
									int remainingLA = parent.getLookAhead();
									Iterator<ILeafNode> parentLeafs = parent.getLeafNodes().iterator();
									while (parentLeafs.hasNext() && remainingLA > 0) {
										ILeafNode leafNode = parentLeafs.next();
										if (leafNode == firstLeaf) {
											break;
										}
										if (!leafNode.isHidden()) {
											remainingLA--;
											if (remainingLA == 0) {
												iterator.prune();
											}
										}
									}
								}

								// Reduce the size of object literals.
							} else if (grammarElement == propertyAssignmentCall1
									|| grammarElement == propertyAssignmentCall2) {
								iterator.prune();
								Iterator<ILeafNode> localLeafs = casted.getLeafNodes().iterator();
								while (localLeafs.hasNext()) {
									ILeafNode leaf = localLeafs.next();
									if (!leaf.isHidden()) {
										return leaf;
									}
								}
							}
						}
					}
				}
				return result;
			}
			return endOfData();
		}
	};

}
 
Example 10
Source File: TokenSequencePreservingPartialParsingHelper.java    From xtext-extras with Eclipse Public License 2.0 4 votes vote down vote up
@Override
public IParseResult reparse(IParser parser, IParseResult previousParseResult, ReplaceRegion changedRegion) {
	if (isBrokenPreviousState(previousParseResult, changedRegion.getOffset())) {
		return fullyReparse(parser, previousParseResult, changedRegion);
	}
	ICompositeNode oldRootNode = previousParseResult.getRootNode();
	Iterator<ILeafNode> leafNodes = oldRootNode.getLeafNodes().iterator();
	ILeafNode leftNode = getLeftNode(leafNodes, changedRegion.getOffset());
	if (leftNode == null) {
		return fullyReparse(parser, previousParseResult, changedRegion);
	}
	ILeafNode rightNode = getRightNode(leafNodes, changedRegion.getEndOffset());
	if (rightNode == null) {
		return fullyReparse(parser, previousParseResult, changedRegion);
	}
	while(leafNodes.hasNext()) {
		if (leafNodes.next().getSyntaxErrorMessage() != null) {
			return fullyReparse(parser, previousParseResult, changedRegion);
		}
	}
	String originalText = oldRootNode.getText().substring(leftNode.getTotalOffset());
	StringBuilder newTextBuilder = new StringBuilder(originalText);
	changedRegion.shiftBy(-leftNode.getTotalOffset()).applyTo(newTextBuilder);
	String newText = newTextBuilder.toString();
	if (originalText.equals(newText)) {
		// nothing to do
		return previousParseResult;
	}
	int originalLength = rightNode.getTotalEndOffset() - leftNode.getTotalOffset();
	int expectedLength = originalLength - changedRegion.getLength() + changedRegion.getText().length();
	if (!isSameTokenSequence(originalText.substring(0, originalLength), newText, expectedLength)) {
		// different token sequence, cannot perform a partial parse run
		return fullyReparse(parser, previousParseResult, changedRegion);
	}
	
	PartialParsingPointers parsingPointers = calculatePartialParsingPointers(oldRootNode, leftNode, rightNode);
	ICompositeNode replaceMe = getReplacedNode(parsingPointers);
	if (replaceMe == null || replaceMe == oldRootNode || replaceMe.getOffset() == 0 && replaceMe.getEndOffset() == oldRootNode.getLength()) {
		return fullyReparse(parser, previousParseResult, changedRegion);
	}
	String reparseRegion = insertChangeIntoReplaceRegion(replaceMe, changedRegion);
	
	EObject oldSemanticElement = getOldSemanticElement(replaceMe, parsingPointers);
	if (oldSemanticElement == null)
		return fullyReparse(parser, previousParseResult, changedRegion);
	if (oldSemanticElement == replaceMe.getParent().getSemanticElement()) {
		throw new IllegalStateException("oldParent == oldElement");
	}
	
	IParseResult newParseResult = doParseRegion(parser, parsingPointers, replaceMe, reparseRegion);
	if (newParseResult == null) {
		throw new IllegalStateException("Could not perform a partial parse operation");
	}
	
	replaceOldSemanticElement(oldSemanticElement, previousParseResult, newParseResult);
	nodeModelBuilder.replaceAndTransferLookAhead(replaceMe, newParseResult.getRootNode());
	((ParseResult) newParseResult).setRootNode(oldRootNode);
	StringBuilder builder = new StringBuilder(oldRootNode.getText());
	changedRegion.applyTo(builder);
	nodeModelBuilder.setCompleteContent(oldRootNode, builder.toString());
	return newParseResult;
}
 
Example 11
Source File: PartialParsingHelper.java    From xtext-core with Eclipse Public License 2.0 4 votes vote down vote up
/**
 * Investigates the composite nodes containing the changed region and collects a list of nodes which could possibly
 * replaced by a partial parse. Such a node has a parent that consumes all his current lookahead tokens and all of
 * these tokens are located before the changed region.
 */
private List<ICompositeNode> internalFindValidReplaceRootNodeForChangeRegion(
		List<ICompositeNode> nodesEnclosingRegion, Range range) {
	List<ICompositeNode> result = new ArrayList<ICompositeNode>();
	boolean mustSkipNext = false;
	ICompositeNode previous = null;
	/*
	 * set to 'true' as soon as the lookahead of an enclosing
	 * exceeds the given range
	 */
	boolean done = false;  
	for (int i = 0; i < nodesEnclosingRegion.size() && !done; i++) {
		ICompositeNode node = nodesEnclosingRegion.get(i);
		if (node.getGrammarElement() != null) {
			if (!mustSkipNext) {
				boolean process = true;
				if (previous != null && !node.hasNextSibling()) {
					if (previous.getLookAhead() == node.getLookAhead() && previous.getLookAhead() == 0) {
						process = false;
					}
				}
				EObject semanticElement = NodeModelUtils.findActualSemanticObjectFor(node);
				if (semanticElement != null) {
					ICompositeNode actualNode = NodeModelUtils.findActualNodeFor(semanticElement);
					if (actualNode != null && (actualNode.getTotalOffset() < node.getTotalOffset() || actualNode.getTotalEndOffset() > node.getTotalEndOffset()))
						process = false;
				}
				if (process) {
					int remainingLookAhead = node.getLookAhead();
					if (remainingLookAhead != 0) {
						Iterator<ILeafNode> iterator = node.getLeafNodes().iterator();
						while(iterator.hasNext() && remainingLookAhead > 0) {
							ILeafNode leaf = iterator.next();
							if (!leaf.isHidden()) {
								if (remainingLookAhead > 0)
									remainingLookAhead--;
								if (remainingLookAhead == 0) {
									if (leaf.getTotalEndOffset() <= range.getOffset()) {
										result.add(node);
										previous = node;
										if (isActionNode(node)) {
											mustSkipNext = true;
										}
										break;
									} else {
										// lookahead ends left of the range, don't dive into child nodes
										done = true;
									}
								}
							}
						}
						if (remainingLookAhead != 0) {
							done = true;
						}
					} else {
						result.add(node);
						previous = node;
						if (isActionNode(node)) {
							mustSkipNext = true;
						}
					}
				}
			} else { // !mustSkipNext
				mustSkipNext = isActionNode(node);
			}
		}
	}
	return result;
}
 
Example 12
Source File: FixedPartialParsingHelper.java    From dsl-devkit with Eclipse Public License 1.0 4 votes vote down vote up
/**
 * Investigates the composite nodes containing the changed region and collects a list of nodes which could possibly
 * replaced by a partial parse. Such a node has a parent that consumes all his current lookahead tokens and all of
 * these tokens are located before the changed region.
 */
private List<ICompositeNode> internalFindValidReplaceRootNodeForChangeRegion(final List<ICompositeNode> nodesEnclosingRegion, final Range range) {
  List<ICompositeNode> result = new ArrayList<ICompositeNode>();
  boolean mustSkipNext = false;
  ICompositeNode previous = null;
  /*
   * set to 'true' as soon as the lookahead of an enclosing
   * exceeds the given range
   */
  boolean done = false;
  for (int i = 0; i < nodesEnclosingRegion.size() && !done; i++) {
    ICompositeNode node = nodesEnclosingRegion.get(i);
    if (node.getGrammarElement() != null) {
      if (!mustSkipNext) {
        boolean process = true;
        if (previous != null && !node.hasNextSibling()) {
          if (previous.getLookAhead() == node.getLookAhead() && previous.getLookAhead() == 0) {
            process = false;
          }
        }
        EObject semanticElement = NodeModelUtils.findActualSemanticObjectFor(node);
        if (semanticElement != null) {
          ICompositeNode actualNode = NodeModelUtils.findActualNodeFor(semanticElement);
          if (actualNode != null && (actualNode.getTotalOffset() < node.getTotalOffset() || actualNode.getTotalEndOffset() > node.getTotalEndOffset())) {
            mustSkipNext = isActionNode(node);
            process = false;
          }
        }
        if (process) {
          int remainingLookAhead = node.getLookAhead();
          if (remainingLookAhead != 0) {
            Iterator<ILeafNode> iterator = node.getLeafNodes().iterator();
            while (iterator.hasNext() && remainingLookAhead > 0) {
              ILeafNode leaf = iterator.next();
              if (!leaf.isHidden()) {
                if (remainingLookAhead > 0) {
                  remainingLookAhead--;
                }
                if (remainingLookAhead == 0) {
                  if (leaf.getTotalEndOffset() <= range.getOffset()) {
                    result.add(node);
                    previous = node;
                    if (isActionNode(node)) {
                      mustSkipNext = true;
                    }
                    break;
                  } else {
                    // lookahead ends left of the range, don't dive into child nodes
                    done = true;
                  }
                }
              }
            }
            if (remainingLookAhead != 0) {
              done = true;
            }
          } else {
            result.add(node);
            previous = node;
            if (isActionNode(node)) {
              mustSkipNext = true;
            }
          }
        }
      } else { // !mustSkipNext
        mustSkipNext = isActionNode(node);
      }
    }
  }
  return result;
}