/** * Determines if the damage region affects a particular tree node, looking only at those tokens * that actually belong to the node and not to its children. */ protected boolean isDamageTreeNode(ISimpleTerm tree, boolean isOriginalTree, int skippedChars) { IToken current = findLeftMostLayoutToken(getLeftToken(tree)); IToken last = findRightMostLayoutToken(getRightToken(tree)); if (current != null && last != null) { if (!isDamagedRange( current.getStartOffset(), last.getEndOffset(), isOriginalTree, skippedChars)) return false; Iterator<ISimpleTerm> iterator = tryGetListIterator(tree); for (int i = 0, max = tree.getSubtermCount(); i < max; i++) { ISimpleTerm child = iterator == null ? tree.getSubterm(i) : iterator.next(); IToken childLeft = findLeftMostLayoutToken(getLeftToken(child)); IToken childRight = findRightMostLayoutToken(getRightToken(child)); if (childLeft != null && childRight != null) { if (childLeft.getIndex() > current.getIndex() && isDamagedRange( current.getEndOffset() + 1, childLeft.getStartOffset() - 1, isOriginalTree, skippedChars)) { return true; } current = childRight; } } return isDamagedRange( current.getEndOffset() + 1, last.getEndOffset(), isOriginalTree, skippedChars); } else { return false; } }
/** * Gets all non-list tree nodes from a tree that are in the damage region according to {@link * #isDamageTreeNode}. Tries to take the innermost {@link #incrementalSorts} tree node where * possible instead of taking an inner non-incremental tree node. * * @param tree Current tree node * @param results Found tree nodes * @param isOriginalTree Whether the tree is the input tree of the incremental parser * @param skippedChars See {@link IncrementalInputBuilder#getLastSkippedCharsBeforeDamage()}. * @param outerIncrementalNode The innermost ancestor of the current tree that is in {@link * #incrementalSorts}. * @return the last ancestral tree node added to the list */ private ISimpleTerm getDamageRegionTreeNodes( ISimpleTerm tree, List<ISimpleTerm> results, boolean isOriginalTree, int skippedChars, ISimpleTerm outerIncrementalNode) { if (incrementalSorts.isIncrementalNode(tree)) outerIncrementalNode = tree; if (!tree.isList() // prefer adding list children && isDamageTreeNode(tree, isOriginalTree, skippedChars)) return addDamageRegionTreeNode(tree, results, outerIncrementalNode); // Recurse boolean addedChild = false; Iterator<ISimpleTerm> iterator = tryGetListIterator(tree); for (int i = 0, max = tree.getSubtermCount(); i < max; i++) { ISimpleTerm child = iterator == null ? tree.getSubterm(i) : iterator.next(); ISimpleTerm addedAncestor = getDamageRegionTreeNodes( child, results, isOriginalTree, skippedChars, outerIncrementalNode); if (addedAncestor != null && addedAncestor == outerIncrementalNode) return addedAncestor; addedChild = true; } if (!addedChild && tree.isList() // add list (outerIncrementalNode), if we must && isDamageTreeNode(tree, isOriginalTree, skippedChars)) return addDamageRegionTreeNode(tree, results, outerIncrementalNode); return null; }
private void bindAstNode(ISimpleTerm node, int tokenIndex, int endTokenIndex) { assert getTokenizer(node) == this; int tokenCount = getTokenCount(); // Set ast node for spaces between children and recursively for children Iterator<ISimpleTerm> iterator = SimpleTermVisitor.tryGetListIterator(node); for (int i = 0, max = node.getSubtermCount(); i < max; i++) { ISimpleTerm child = iterator == null ? node.getSubterm(i) : iterator.next(); int childStart = getLeftToken(child).getIndex(); int childEnd = getRightToken(child).getIndex(); while (tokenIndex < childStart && tokenIndex < tokenCount) { Token token = getTokenAt(tokenIndex++); token.setAstNode(node); } bindAstNode(child, childStart, childEnd); tokenIndex = childEnd + 1; } // Set ast node for tokens after children while (tokenIndex <= endTokenIndex && tokenIndex < tokenCount) { Token token = getTokenAt(tokenIndex++); token.setAstNode(node); } }