Java Code Examples for org.eclipse.xtext.nodemodel.ILeafNode

The following examples show how to use org.eclipse.xtext.nodemodel.ILeafNode. These examples are extracted from open source projects. 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 Project: n4js   Source File: SemanticChangeProvider.java    License: Eclipse Public License 1.0 6 votes vote down vote up
/**
 * Returns the offset to place the @Internal annotation in the same line
 */
private int internalAnnotationOffset(ModifiableElement element) {
	if (!(element instanceof AnnotableElement)) {
		throw new IllegalArgumentException("Can't compute @Internal offset for non-annotable element");
	}

	// If element is exported put the @Internal annotation in front of the export keyword
	// Otherwise place it in front of the modifiers

	EObject containerExportDeclaration = element.eContainer();
	if (containerExportDeclaration instanceof ExportDeclaration) {
		ILeafNode node = nodeModelAccess.nodeForKeyword(containerExportDeclaration,
				N4JSLanguageConstants.EXPORT_KEYWORD);
		if (node != null) {
			return node.getOffset();
		} else {
			throw new NullPointerException("Failed to retrieve node for export keyword");
		}
	} else {
		return modifierOffset(element);
	}
}
 
Example 2
@Override
protected void handleLastCompleteNodeIsAtEndOfDatatypeNode() throws BadLocationException {
	String prefix = getPrefix(lastCompleteNode);
	INode previousNode = getLastCompleteNodeByOffset(rootNode, lastCompleteNode.getOffset());
	EObject previousModel = previousNode.getSemanticElement();
	INode currentDatatypeNode = getContainingDatatypeRuleNode(currentNode);
	Collection<FollowElement> followElements = parseFollowElements(lastCompleteNode.getOffset(), false);
	int prevSize = contextBuilders.size();
	doCreateContexts(previousNode, currentDatatypeNode, prefix, previousModel, followElements);

	if (lastCompleteNode instanceof ILeafNode && lastCompleteNode.getGrammarElement() == null
			&& contextBuilders.size() != prevSize) {
		handleLastCompleteNodeHasNoGrammarElement(contextBuilders.subList(prevSize, contextBuilders.size()),
				previousModel);
	}
}
 
Example 3
Source Project: n4js   Source File: N4JSSyntaxValidator.java    License: Eclipse Public License 1.0 6 votes vote down vote up
/**
 * Check that not more than one access modifier is given. Access modifiers are those for which
 * {@link ModifierUtils#isAccessModifier(N4Modifier)} returns <code>true</code>.
 */
private boolean holdsNotMoreThanOneAccessModifier(ModifiableElement elem) {
	boolean hasIssue = false;
	boolean hasAccessModifier = false;
	for (int idx = 0; idx < elem.getDeclaredModifiers().size(); idx++) {
		final N4Modifier mod = elem.getDeclaredModifiers().get(idx);
		final boolean isAccessModifier = ModifierUtils.isAccessModifier(mod);
		if (hasAccessModifier && isAccessModifier) {
			final ILeafNode node = ModifierUtils.getNodeForModifier(elem, idx);
			addIssue(IssueCodes.getMessageForSYN_MODIFIER_ACCESS_SEVERAL(),
					elem, node.getOffset(), node.getLength(),
					IssueCodes.SYN_MODIFIER_ACCESS_SEVERAL);
			hasIssue = true;
		}
		hasAccessModifier |= isAccessModifier;
	}
	return !hasIssue;
}
 
Example 4
Source Project: xtext-core   Source File: HiddenTokenSequencer.java    License: Eclipse Public License 2.0 6 votes vote down vote up
protected void emitHiddenTokens(List<INode> hiddens /* Set<INode> comments, */) {
	if (hiddens == null)
		return;
	boolean lastNonWhitespace = true;
	for (INode node : hiddens) {
		if (tokenUtil.isCommentNode(node)) {
			if (lastNonWhitespace)
				delegate.acceptWhitespace(hiddenTokenHelper.getWhitespaceRuleFor(null, ""), "", null);
			lastNonWhitespace = true;
			//				comments.remove(node);
			delegate.acceptComment((AbstractRule) node.getGrammarElement(), node.getText(), (ILeafNode) node);
		} else {
			delegate.acceptWhitespace((AbstractRule) node.getGrammarElement(), node.getText(), (ILeafNode) node);
			lastNonWhitespace = false;
		}
		lastEmittedNode = node;
	}
	if (lastNonWhitespace)// FIXME: determine the whitespace rule correctly 
		delegate.acceptWhitespace(hiddenTokenHelper.getWhitespaceRuleFor(null, ""), "", null);
}
 
Example 5
Source Project: xtext-core   Source File: PartialParsingHelper.java    License: Eclipse Public License 2.0 6 votes vote down vote up
private boolean isRangePartOfExceedingLookAhead(CompositeNode node, ReplaceRegion replaceRegion) {
	TreeIterator<AbstractNode> iterator = node.basicIterator();
	int lookAhead = node.getLookAhead();
	if (lookAhead == 0) {
		return false;
	}
	while(iterator.hasNext()) {
		AbstractNode child = iterator.next();
		if (child instanceof CompositeNode) {
			if (child.getTotalOffset() < replaceRegion.getEndOffset())
				lookAhead = Math.max(((CompositeNode) child).getLookAhead(), lookAhead);
		} else if (!((ILeafNode) child).isHidden()) {
			lookAhead--;
			if (lookAhead == 0) {
				if (child.getTotalOffset() >= replaceRegion.getEndOffset())
					return false;
			}
		}
	}
	return lookAhead > 0;
}
 
Example 6
Source Project: xtext-core   Source File: LazyURIEncoderTest.java    License: Eclipse Public License 2.0 6 votes vote down vote up
@Test public void testNodePath() throws Exception {
	NodeModelBuilder builder = new NodeModelBuilder();
	ICompositeNode n = new CompositeNode();
	ICompositeNode n1 = new CompositeNode();
	builder.addChild(n, (AbstractNode) n1);
	ICompositeNode n2 = new CompositeNode();
	builder.addChild(n, (AbstractNode) n2);
	ILeafNode l1 = new LeafNode();
	builder.addChild(n2, (AbstractNode) l1);
	ILeafNode l2 = new LeafNode();
	builder.addChild(n2, (AbstractNode) l2);
	
	assertEquals(n, find(n,n));
	assertEquals(n1, find(n,n1));
	assertEquals(n2, find(n,n2));
	assertEquals(l1, find(n,l1));
	assertEquals(l2, find(n,l2));
}
 
Example 7
Source Project: xtext-core   Source File: SyntacticSequencerTest.java    License: Eclipse Public License 2.0 6 votes vote down vote up
@SuppressWarnings("deprecation")
private List<String> getNodeSequence(EObject model) {
	List<String> result = Lists.newArrayList();
	GrammarElementTitleSwitch titleSwitch = new GrammarElementTitleSwitch().showAssignments();
	org.eclipse.xtext.serializer.sequencer.EmitterNodeIterator ni = 
			new org.eclipse.xtext.serializer.sequencer.EmitterNodeIterator(NodeModelUtils.findActualNodeFor(model));
	while (ni.hasNext()) {
		INode next = ni.next();
		EObject ele = next.getGrammarElement() instanceof CrossReference ? ((CrossReference) next
				.getGrammarElement()).getTerminal() : next.getGrammarElement();
		if (next instanceof ILeafNode || GrammarUtil.isDatatypeRuleCall(ele))
			result.add(titleSwitch.doSwitch(ele) + " -> " + next.getText().trim());
		else if (next instanceof ICompositeNode)
			result.add(titleSwitch.doSwitch(ele));
	}
	return result;
}
 
Example 8
Source Project: xtext-core   Source File: ValueSerializer.java    License: Eclipse Public License 2.0 6 votes vote down vote up
protected String serialize(INode node) {
	if (node instanceof ILeafNode)
		return ((ILeafNode) node).getText();
	else {
		StringBuilder builder = new StringBuilder(node.getLength());
		boolean hiddenSeen = false;
		for(ILeafNode leaf: node.getLeafNodes()) {
			if (!leaf.isHidden()) {
				if (hiddenSeen && builder.length() > 0)
					builder.append(' ');
				builder.append(leaf.getText());
				hiddenSeen = false;
			} else {
				hiddenSeen = true;
			}
		}
		return builder.toString();
	}
}
 
Example 9
@Override
public String getLegacyImportSyntax(XImportDeclaration importDeclaration) {
	List<INode> list = NodeModelUtils.findNodesForFeature(importDeclaration, XtypePackage.Literals.XIMPORT_DECLARATION__IMPORTED_TYPE);
	if (list.isEmpty()) {
		return null;
	}
	INode singleNode = list.get(0);
	if (singleNode.getText().indexOf('$') < 0) {
		return null;
	}
	StringBuilder sb = new StringBuilder();
	for(ILeafNode node: singleNode.getLeafNodes()) {
		if (!node.isHidden()) {
			sb.append(node.getText().replace("^", ""));
		}
	}
	return sb.toString();
}
 
Example 10
Source Project: xtext-core   Source File: PartialParserTest.java    License: Eclipse Public License 2.0 6 votes vote down vote up
@Test public void testPartialParseConcreteRuleInnermostToken_02() throws Exception {
	with(PartialParserTestLanguageStandaloneSetup.class);
	String model = 
			"container c1 {\n" +
			"  children {\n" +
			"    -> C ( ch1 )\n" +
			"  }" +
			"}";
	XtextResource resource = getResourceFromString(model);
	assertTrue(resource.getErrors().isEmpty());
	ICompositeNode root = resource.getParseResult().getRootNode();
	ILeafNode childrenLeaf = findLeafNodeByText(root, model, "children");
	ILeafNode ch1Leaf = findLeafNodeByText(root, model, "ch1");
	// change the model and undo the change
	resource.update(model.indexOf("ch1") + 1, 1, "x");
	resource.update(model.indexOf("ch1") + 1, 1, "h");
	assertSame(root, resource.getParseResult().getRootNode());
	assertSame(childrenLeaf, findLeafNodeByText(root, model, "children"));
	assertNotSame(ch1Leaf, findLeafNodeByText(root, model, "ch1"));
}
 
Example 11
Source Project: xtext-core   Source File: TokenUtil.java    License: Eclipse Public License 2.0 6 votes vote down vote up
public String serializeNode(INode node) {
	if (node instanceof ILeafNode)
		return ((ILeafNode) node).getText();
	List<ILeafNode> leafNodes = Lists.newArrayList(node.getLeafNodes());
	int begin = 0, end = leafNodes.size() - 1;
	while (begin <= end && isWhitespaceOrCommentNode(leafNodes.get(begin)))
		begin++;
	while (begin <= end && isWhitespaceOrCommentNode(leafNodes.get(end)))
		end--;
	if (begin == end)
		return isWhitespaceOrCommentNode(leafNodes.get(begin)) ? "" : leafNodes.get(begin).getText();
	StringBuilder b = new StringBuilder();
	for (int i = begin; i <= end; i++)
		b.append(leafNodes.get(i).getText());
	return b.toString();
}
 
Example 12
public String getNodeTextUpToCompletionOffset(INode currentNode) {
	int startOffset = currentNode.getOffset();
	int length = completionOffset - startOffset;
	String nodeText = ((ILeafNode) currentNode).getText();
	String trimmedNodeText = length > nodeText.length() ? nodeText : nodeText.substring(0, length);
	if (viewer.getDocument() != null /* testing */ && length >= 0) {
		try {
			String text = viewer.getDocument().get(startOffset, trimmedNodeText.length());
			if (trimmedNodeText.equals(text))
				return text;
			return viewer.getDocument().get(startOffset, length);
		} catch (BadLocationException e) {
			log.error(e.getMessage(), e);
		}
	}
	return trimmedNodeText;
}
 
Example 13
private PeekingIterator<ILeafNode> createReversedLeafIterator(INode root, INode candidate, LinkedList<ILeafNode> sameGrammarElement) {
	EObject grammarElement = null;
	PeekingIterator<ILeafNode> iterator = Iterators.peekingIterator(Iterators.filter(root.getAsTreeIterable().reverse().iterator(), ILeafNode.class));
	// traverse until we find the current candidate
	while(iterator.hasNext()) {
		ILeafNode next = iterator.next();
		if (candidate.equals(next)) {
			break;
		} else if (next.getTotalLength() == 0) {
			EObject otherGrammarElement = tryGetGrammarElementAsRule(next);
			if (grammarElement == null) {
				grammarElement = otherGrammarElement;
			}
			if (otherGrammarElement.equals(grammarElement)) {
				sameGrammarElement.add(next);
			} else {
				sameGrammarElement.removeLast();
			}
		}
	}
	return iterator;
}
 
Example 14
Source Project: xtext-core   Source File: XtextLinkingService.java    License: Eclipse Public License 2.0 6 votes vote down vote up
private List<EObject> getPackage(ReferencedMetamodel context, ILeafNode text) {
	String nsUri = getMetamodelNsURI(text);
	if (nsUri == null)
		return Collections.emptyList();
	Grammar grammar = GrammarUtil.getGrammar(context);
	Set<Grammar> visitedGrammars = new HashSet<Grammar>();
	for (Grammar usedGrammar: grammar.getUsedGrammars()) {
		List<EObject> result = getPackage(nsUri, usedGrammar, visitedGrammars);
		if (result != null)
			return result;
	}
	QualifiedName packageNsURI = QualifiedName.create(nsUri);
	EPackage pack = findPackageInScope(context, packageNsURI);
	if (pack == null) {
		pack = findPackageInAllDescriptions(context, packageNsURI);
		if (pack == null) {
			pack = loadEPackage(nsUri, context.eResource().getResourceSet());
		}
	}
	if (pack != null)
		return Collections.<EObject>singletonList(pack);
	return Collections.emptyList();
}
 
Example 15
Source Project: xtext-core   Source File: Bug250313Test.java    License: Eclipse Public License 2.0 5 votes vote down vote up
@Test public void testIDConversion_04() throws Exception {
	Model model = (Model) getModel("^str");
	assertEquals("str", model.getValue());
	assertEquals("org.eclipse.xtext.common.Terminals.ID", lexerRule);
	assertTrue(node instanceof ILeafNode);
	assertEquals("^str", string);
	assertEquals(1, convertCallCount);
}
 
Example 16
Source Project: n4js   Source File: ImportRewriter.java    License: Eclipse Public License 1.0 5 votes vote down vote up
/**
 * Returns with the length of the node including all hidden leaf nodes but the {@link LeafNodeWithSyntaxError} one,
 * that was created for the automatic semicolon insertion.
 */
private int getLengthWithoutAutomaticSemicolon(final INode node) {
	if (node instanceof ILeafNode) {
		return node.getLength();
	}

	int length = 0;
	for (final INode leafNode : ((ICompositeNode) node).getLeafNodes()) {
		if (!isIgnoredSyntaxErrorNode(leafNode, SEMICOLON_INSERTED)) {
			length += leafNode.getLength();
		}
	}

	return length;
}
 
Example 17
protected boolean include(INode node) {
	if (node instanceof ILeafNode) {
		return true;
	} else if (node instanceof ICompositeNode) {
		EObject element = node.getGrammarElement();
		return GrammarUtil.isDatatypeRuleCall(element) || element instanceof CrossReference
				|| GrammarUtil.isEnumRuleCall(element);
	}
	return false;
}
 
Example 18
Source Project: xtext-core   Source File: HiddenTokenSequencer.java    License: Eclipse Public License 2.0 5 votes vote down vote up
protected Set<INode> getTrailingCommentsIncludingWhitespace(ICompositeNode node) {
	for (INode child : node.getAsTreeIterable().reverse()) {
		if (child instanceof ILeafNode && !((ILeafNode) child).isHidden()) {
			return getTrailingCommentsIncludingWhitespace((ILeafNode) child);
		}
	}
	return Sets.newHashSet();
}
 
Example 19
@Override
public Map<ILeafNode, EObject> associateCommentsWithSemanticEObjects(EObject model, Set<ICompositeNode> roots) {
	Map<ILeafNode, EObject> mapping = new HashMap<ILeafNode, EObject>();
	for (ICompositeNode rootNode : roots)
		associateCommentsWithSemanticEObjects(mapping, rootNode);
	return mapping;
}
 
Example 20
Source Project: xtext-core   Source File: EnumLiteralSerializer.java    License: Eclipse Public License 2.0 5 votes vote down vote up
protected Keyword getLiteral(INode node) {
	if (node != null) {
		for (ILeafNode leaf : node.getLeafNodes()) {
			if (leaf.getGrammarElement() instanceof EnumLiteralDeclaration)
				return ((EnumLiteralDeclaration) leaf.getGrammarElement()).getLiteral();
		}
	}
	return null;
}
 
Example 21
public boolean doComputePrefix(ICompositeNode node, StringBuilder result) {
	List<ILeafNode> hiddens = Lists.newArrayListWithCapacity(2);
	for (INode child : node.getChildren()) {
		if (child instanceof ICompositeNode) {
			if (!doComputePrefix((ICompositeNode) child, result))
				return false;
		}
		else {
			ILeafNode leaf = (ILeafNode) child;
			ITextRegion leafRegion = leaf.getTextRegion();
			if (leafRegion.getOffset() > completionOffset)
				return false;
			if (leaf.isHidden()) {
				if (result.length() != 0)
					hiddens.add((ILeafNode) child);
			}
			else {
				Iterator<ILeafNode> iter = hiddens.iterator();
				while (iter.hasNext()) {
					result.append(iter.next().getText());
				}
				hiddens.clear();
				result.append(getNodeTextUpToCompletionOffset(leaf));
				if (leafRegion.getOffset() + leafRegion.getLength() > completionOffset)
					return false;
			}
		}
	}
	return true;
}
 
Example 22
Source Project: xtext-core   Source File: NodeModelStreamer.java    License: Eclipse Public License 2.0 5 votes vote down vote up
@Override
public ITextRegion feedTokenStream(ITokenStream out, ICompositeNode in, int offset, int length) throws IOException {
	List<INode> nodes = getLeafs(in, offset, offset + length);
	if (nodes.isEmpty())
		return new TextRegion(in.getOffset(), 0);
	if (out instanceof ITokenStreamExtension)
		((ITokenStreamExtension) out).init(findRootRuleForRegion(nodes.get(0)));
	boolean lastIsTokenOrComment = false;
	for (INode node : nodes) {
		boolean currentIsTokenOrComment = tokenUtil.isCommentNode(node) || tokenUtil.isToken(node);
		if (lastIsTokenOrComment && currentIsTokenOrComment)
			writeHiddenEmpty(out);
		lastIsTokenOrComment = currentIsTokenOrComment;
		if (node instanceof ILeafNode) {
			ILeafNode leaf = (ILeafNode) node;
			if (leaf.isHidden())
				writeHidden(out, leaf);
			else
				writeSemantic(out, leaf);
		} else if (node instanceof ICompositeNode)
			writeSemantic(out, (ICompositeNode) node);
	}
	out.flush();
	int rStart = nodes.get(0).getOffset();
	int rLength = nodes.get(nodes.size() - 1).getEndOffset() - rStart;
	return new TextRegion(rStart, rLength);
}
 
Example 23
Source Project: xtext-core   Source File: SequenceFeeder.java    License: Eclipse Public License 2.0 5 votes vote down vote up
public void accept(Keyword keyword, Object value, int index) {
	Assignment ass = getAssignment(keyword);
	EStructuralFeature feature = getFeature(ass.getFeature());
	assertIndex(feature, index);
	assertValue(feature, value);
	ILeafNode node = getLeafNode(feature, index, index, value);
	String token = getToken(keyword, value, node);
	acceptKeyword(ass, keyword, value, token, index, node);
}
 
Example 24
protected boolean appendTextToParse(ICompositeNode node, int offset, boolean skipOptional, StringBuilder result) {
	for (INode child : node.getChildren()) {
		if (child instanceof ILeafNode) {
			String text = child.getText();
			if (child.getTotalEndOffset() >= offset) {
				String sub = text.substring(0, offset - child.getTotalOffset());
				result.append(sub);
				return true;
			} else {
				result.append(text);
			}
		} else {
			if (!skipOptional) {
				if (appendTextToParse((ICompositeNode) child, offset, child.getTotalEndOffset() < offset, result)) {
					return true;
				}
			} else {
				String skippedAs = getReplacement((ICompositeNode) child);
				if (skippedAs != null) {
					result.append(skippedAs);
				} else {
					if (appendTextToParse((ICompositeNode) child, offset, true, result)) {
						return true;
					}
				}
			}
		}
	}
	return false;
}
 
Example 25
Source Project: xtext-core   Source File: EmitterNodeIterator.java    License: Eclipse Public License 2.0 5 votes vote down vote up
protected boolean include(INode node) {
	if (node instanceof ILeafNode) {
		ILeafNode leaf = (ILeafNode) node;
		if (!allowHidden && leaf.isHidden())
			return false;
		return true;
	} else if (node instanceof ICompositeNode) {
		return GrammarUtil.isDatatypeRuleCall(node.getGrammarElement())
				|| node.getGrammarElement() instanceof CrossReference;
	}
	return false;
}
 
Example 26
Source Project: xtext-core   Source File: AbstractNode.java    License: Eclipse Public License 2.0 5 votes vote down vote up
@Override
public int getLength() {
	BidiIterator<AbstractNode> iter = basicIterator();
	while(iter.hasPrevious()) {
		INode prev = iter.previous();
		if (prev instanceof ILeafNode && !((ILeafNode) prev).isHidden()) {
			int offset = getOffset();
			return prev.getTotalEndOffset() - offset;
		}
	}
	return getTotalLength();
}
 
Example 27
/**
 * Returns the leading comments of the given node.
 * First leaf node is considered to be an end point of the search.
 *
 * @param node
 *          element of the node model to find comments for, can be {@code null}
 * @return list of hidden tokens, can be empty if nothing found, never {@code null}
 */
private List<INode> getLeadingCommentsIncludingWhitespace(final INode node) {
  if (node instanceof ICompositeNode) {
    for (INode child : node.getAsTreeIterable()) {
      if (child instanceof ILeafNode && !((ILeafNode) child).isHidden()) {
        return getLeadingCommentsIncludingWhitespace((ILeafNode) child);
      }
    }
  } else if (node instanceof ILeafNode) {
    return getLeadingCommentsIncludingWhitespace((ILeafNode) node);
  }
  return Collections.emptyList();
}
 
Example 28
Source Project: xtext-core   Source File: ParseErrorHandlingTest.java    License: Eclipse Public License 2.0 5 votes vote down vote up
@Test public void testTrailingRecoverableError() throws Exception {
	with(TreeTestLanguageStandaloneSetup.class);
	String model = "parent ('Teststring') { \n" +
		"	child ('Teststring'){};\n" +
		"	child ('Teststring'){};\n" +
		"};\n" +
		"};\n" +
		"\n";
	Resource res = getResourceFromStringAndExpect(model, 1);
	assertEquals(res.getErrors().size(), 1, res.getErrors().size());
	Diagnostic diag = res.getErrors().get(0);
	assertNotNull(diag);
	assertEquals(5, diag.getLine());
	Model parsedModel = (Model) res.getContents().get(0);
	assertNotNull(parsedModel);
	ICompositeNode composite = NodeModelUtils.getNode(parsedModel);
	assertNotNull(composite);
	List<ILeafNode> leafs = Lists.newArrayList(composite.getLeafNodes());
	ILeafNode lastWs = leafs.get(leafs.size() - 1);
	assertTrue(lastWs.isHidden());
	assertNull(lastWs.getSyntaxErrorMessage());
	ILeafNode lastNode = leafs.get(leafs.size() - 2);
	assertFalse(lastNode.isHidden());
	assertNotNull(lastNode);
	assertEquals("};", lastNode.getText());
	assertNotNull(lastNode.getSyntaxErrorMessage());
}
 
Example 29
public String getPrefix(INode prefixNode) {
	if (prefixNode instanceof ILeafNode) {
		if (((ILeafNode) prefixNode).isHidden() && prefixNode.getGrammarElement() != null)
			return "";
		return getNodeTextUpToCompletionOffset(prefixNode);
	}
	StringBuilder result = new StringBuilder(prefixNode.getTotalLength());
	doComputePrefix((ICompositeNode) prefixNode, result);
	return result.toString();
}
 
Example 30
Source Project: xtext-extras   Source File: NodeModelAccess.java    License: Eclipse Public License 2.0 5 votes vote down vote up
public ILeafNode findNextLeaf(INode node, Function1<? super ILeafNode, ? extends Boolean> matches) {
	if (node != null) {
		if (node instanceof ILeafNode && matches.apply((ILeafNode) node)) {
			return (ILeafNode) node;
		}
		NodeIterator ni = new NodeIterator(node);
		while (ni.hasNext()) {
			INode next = ni.next();
			if (next instanceof ILeafNode && matches.apply((ILeafNode) next)) {
				return (ILeafNode) next;
			}
		}
	}
	return null;
}