public IEnumerable <TNodeOrToken> QueryAll(TNodeOrToken current, SyntaxQuery query) { switch (query.Axis) { case SyntaxQueryAxis.Self: return(QuerySelf(current, query)); case SyntaxQueryAxis.Child: return(QueryAllChildrenOrDescendants(current, query, descendants: false)); case SyntaxQueryAxis.Descendant: return(QueryAllChildrenOrDescendants(current, query, descendants: true)); case SyntaxQueryAxis.Parent: var parent = ToNodeOrToken(GetParent(current)); if (MatchesIgnoringAxis(parent, query)) { return(Enumerable.Repeat(parent, 1)); } return(Enumerable.Empty <TNodeOrToken>()); default: throw new ArgumentException($"Unsupported query axis: {query.Axis}.", nameof(query)); } }
private bool MatchesIgnoringAxis(TNodeOrToken node, SyntaxQuery query) { if (IsExpressionStatement(node, out var expression)) { return(MatchesIgnoringAxis(ToNodeOrToken(expression), query)); } if (IsSwitchSection(node, out var labels)) { foreach (var label in labels) { if (MatchesNodeTypeAndFilter(node, ToNodeOrToken(label), query)) { return(true); } } } if (IsPredefinedType(node, out var keyword)) { return(MatchesNodeTypeAndFilter(node, keyword, query)); } if (HasOtherNodeTypeDefiningChildNode(node, out var nodeTypeChild)) { return(MatchesNodeTypeAndFilter(node, nodeTypeChild, query)); } return(MatchesNodeTypeAndFilter(node, node, query)); }
private IEnumerable <TNodeOrToken> QuerySelf(TNodeOrToken nodeOrToken, SyntaxQuery query) { var node = AsNode(nodeOrToken); if (node != null && ShouldJumpOver(node)) { foreach (var child in GetChildren(nodeOrToken, noFirstJump: true)) { if (MatchesIgnoringAxis(child, query)) { yield return(child); } } yield break; } if (MatchesIgnoringAxis(nodeOrToken, query)) { yield return(nodeOrToken); } }
private IEnumerable <TNodeOrToken> QueryAllChildrenOrDescendants(TNodeOrToken node, SyntaxQuery query, bool descendants) { foreach (var child in GetChildren(node)) { if (MatchesIgnoringAxis(child, query)) { yield return(child); continue; } if (descendants) { foreach (var descendant in QueryAllChildrenOrDescendants(child, query, descendants: true)) { yield return(descendant); } } } }
protected abstract bool MatchesNodeType(TNodeOrToken node, SyntaxQuery query);
private bool MatchesNodeTypeAndFilter(TNodeOrToken node, TNodeOrToken typeFromNode, SyntaxQuery query) { return(MatchesNodeType(typeFromNode, query) && MatchesFilter(node, query.Filter)); }