private static IEnumerable <SyntaxNode> VisitTerminalsRecursive(this SyntaxNode node, TextSpan span) { if (node.SlotCount == 0) { if (node.FullSpan.OverlapsWith(span)) { yield return(node); } } else { for (int i = 0; i < node.SlotCount; i++) { var child = node.GetSlot(i); if (child != null) { if (child.Start > span.End) { break; } else if (child.FullSpan.End < span.Start) { continue; } else { foreach (var terminal in child.VisitTerminalsRecursive(span)) { yield return(terminal); } } } } } }
private static int VisitChildren( SyntaxNode syntaxNode, int windowStart, int windowLength, Action <int, int, SyntaxNode, XmlClassificationTypes> resultCollector, int start, XmlClassificationTypes[] childTypes) { int visitedCount = 0; int windowEnd = windowStart + windowLength; var targetOffset = windowStart - start; int offset; int index; syntaxNode.GetIndexAndOffset(targetOffset, out index, out offset); start += offset; for (int i = index; i < syntaxNode.SlotCount; i++) { if (start > windowEnd) { break; } var child = syntaxNode.GetSlot(i); visitedCount++; if (child == null) { continue; } var currentStart = Math.Max(start, windowStart); var currentLength = Math.Min(windowEnd, start + child.FullWidth) - currentStart; if (currentLength >= 0) { var childType = childTypes == null ? XmlClassificationTypes.None : childTypes[i]; if (childType == XmlClassificationTypes.None) { if (child.Kind == SyntaxKind.XmlTextLiteralToken) { childType = XmlClassificationTypes.XmlText; } else if (child.Kind == SyntaxKind.XmlEntityLiteralToken) { childType = XmlClassificationTypes.XmlEntityReference; } } if (childType == XmlClassificationTypes.None) { visitedCount += Visit(child, windowStart, windowLength, resultCollector, start); } else { if (currentLength > 0) { resultCollector(currentStart, currentLength, child, childType); } } } start += child.FullWidth; } return(visitedCount); }
private static int VisitChildren( SyntaxNode syntaxNode, int windowStart, int windowLength, Action<int, int, SyntaxNode, XmlClassificationTypes> resultCollector, int start, XmlClassificationTypes[] childTypes) { int visitedCount = 0; int windowEnd = windowStart + windowLength; var targetOffset = windowStart - start; int offset; int index; syntaxNode.GetIndexAndOffset(targetOffset, out index, out offset); start += offset; for (int i = index; i < syntaxNode.SlotCount; i++) { if (start > windowEnd) { break; } var child = syntaxNode.GetSlot(i); visitedCount++; if (child == null) { continue; } var currentStart = Math.Max(start, windowStart); var currentLength = Math.Min(windowEnd, start + child.FullWidth) - currentStart; if (currentLength >= 0) { var childType = childTypes == null ? XmlClassificationTypes.None : childTypes[i]; if (childType == XmlClassificationTypes.None) { if (child.Kind == SyntaxKind.XmlTextLiteralToken) { childType = XmlClassificationTypes.XmlText; } else if (child.Kind == SyntaxKind.XmlEntityLiteralToken) { childType = XmlClassificationTypes.XmlEntityReference; } } if (childType == XmlClassificationTypes.None) { visitedCount += Visit(child, windowStart, windowLength, resultCollector, start); } else { if (currentLength > 0) { resultCollector(currentStart, currentLength, child, childType); } } } start += child.FullWidth; } return visitedCount; }
public override SyntaxNode Visit(SyntaxNode node) { if (node == null) { return(null); } // node is not interesting until skip count is 0 if (_skipCnt != 0) { _skipCnt -= 1; return(node); } // not interested in trivia if (!node.IsToken) { var allChildrenCnt = 0; for (int i = 0; i < node.SlotCount; i++) { var child = node.GetSlot(i); if (child == null) { continue; } if (child.IsList) { allChildrenCnt += child.SlotCount; } else { allChildrenCnt += 1; } } // no children if (allChildrenCnt == 0) { return(node); } var prevIdx = _skipCnt; _skipCnt = allChildrenCnt - 1; SyntaxNode result; if (node.IsList) { result = VisitList <SyntaxNode>(node).Node; } else { result = base.Visit(node); } _skipCnt = prevIdx; return(result); } else { return(base.Visit(node)); } }