public bool ChildSiblingSpan(SyntaxNode nonTerminal, SyntaxTree tree, ref string errorText) { var retVal = true; var curStart = -1; var prvEnd = -1; foreach (var child in nonTerminal.ChildNodesAndTokens()) { curStart = child.SpanStart; if (prvEnd == -1) { prvEnd = curStart; } if (curStart < prvEnd) { retVal = false; errorText = "Start Span of a child of this non-terminal is less than the end Span of this child's preceding sibling"; continue; } prvEnd = child.Span.End; } if (retVal) { curStart = -1; prvEnd = -1; foreach (var child in nonTerminal.ChildNodesAndTokens()) { curStart = child.FullSpan.Start; if (prvEnd == -1) { prvEnd = curStart; } if (curStart != prvEnd) { retVal = false; errorText = "FullSpan of a child of this non-terminal is not adjacent to the FullSpan of this child's preceding sibling"; continue; } prvEnd = child.FullSpan.End; } } return(retVal); }
protected override void Recurse( SyntaxTreeAnalysisContext context, Dictionary <int, int> preferredOrder, DiagnosticDescriptor descriptor, SyntaxNode root) { foreach (var child in root.ChildNodesAndTokens()) { if (child.IsNode) { var node = child.AsNode(); if (node is MemberDeclarationSyntax memberDeclaration) { CheckModifiers(context, preferredOrder, descriptor, memberDeclaration); // Recurse and check children. Note: we only do this if we're on an actual // member declaration. Once we hit something that isn't, we don't need to // keep recursing. This prevents us from actually entering things like method // bodies. Recurse(context, preferredOrder, descriptor, node); } else if (node is AccessorListSyntax accessorList) { foreach (var accessor in accessorList.Accessors) { CheckModifiers(context, preferredOrder, descriptor, accessor); } } } } }
private void append(TreeViewItem _rootItem, SyntaxNode _node) { if (__treeView.Items.Count == 0) { __treeView.Items.Add(_rootItem); } ChildSyntaxList _children = _node.ChildNodesAndTokens(); ChildSyntaxList.Enumerator _enumerator = _children.GetEnumerator(); while (_enumerator.MoveNext()) { SyntaxNodeOrToken _syntaxElement = _enumerator.Current; if (_syntaxElement.IsNode) { SyntaxNode _childNode = _syntaxElement.AsNode(); TreeViewItem _childNodeItem = syntaxNodeItem(_childNode); _rootItem.Items.Add(_childNodeItem); append(_childNodeItem, _childNode); } else if (_syntaxElement.IsToken) { SyntaxToken _token = _syntaxElement.AsToken(); _rootItem.Items.Add(syntaxTokenItem(_token)); } } }
private void HighlightRelatedKeywords(SyntaxNode node, List <TextSpan> spans) { switch (node) { case YieldStatementSyntax statement: spans.Add( TextSpan.FromBounds( statement.YieldKeyword.SpanStart, statement.ReturnOrBreakKeyword.Span.End)); spans.Add(EmptySpan(statement.SemicolonToken.Span.End)); break; default: foreach (var child in node.ChildNodesAndTokens()) { if (child.IsToken) { continue; } // Only recurse if we have anything to do if (!child.AsNode().IsReturnableConstruct()) { HighlightRelatedKeywords(child.AsNode(), spans); } } break; } }
public static async Task <IEnumerable <Token> > GetTokensAsync(this PlaygroundWorkspace workspace) { SemanticModel semantics = await workspace.EditingDocument.GetSemanticModelAsync(); SyntaxNode root = await semantics.SyntaxTree.GetRootAsync(); var allNodes = root.ChildNodesAndTokens(); var tokens = new List <Token>(); for (int index = 0; index < allNodes.Count; index++) { if (allNodes[index].IsToken) { var converted = ConvertToken(allNodes[index].AsToken()); tokens.Add(converted); } else if (allNodes[index].IsNode) { var converted = allNodes[index].AsNode(); var processedChildren = ProcessNodeChildren(converted); tokens.AddRange(processedChildren); } } return(tokens); }
private void Recurse( SourceText text, SyntaxNode node, TextSpan textSpan, ArrayBuilder <StringIndentationRegion> result, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); if (!node.Span.IntersectsWith(textSpan)) { return; } if (node.IsKind(SyntaxKind.InterpolatedStringExpression, out InterpolatedStringExpressionSyntax? interpolatedString) && interpolatedString.StringStartToken.IsKind(SyntaxKind.InterpolatedMultiLineRawStringStartToken)) { ProcessInterpolatedStringExpression(text, interpolatedString, result, cancellationToken); } foreach (var child in node.ChildNodesAndTokens()) { if (child.IsNode) { Recurse(text, child.AsNode() !, textSpan, result, cancellationToken); } else if (child.IsKind(SyntaxKind.MultiLineRawStringLiteralToken)) { ProcessMultiLineRawStringLiteralToken(text, child.AsToken(), result, cancellationToken); } } }
static Cs2JsonNode DoConvert2CsJsonNode(SyntaxNode node, ConvertOption opts, Dictionary <SyntaxKind, int> syntaxCount) { syntaxCount = syntaxCount ?? new Dictionary <SyntaxKind, int>(); var csNode = new Cs2JsonNode() { Name = node.Kind().ToString(), Contents = node.ToFullString(), IsToken = false, Children = new List <Cs2JsonNode>(), }; foreach (var child in node.ChildNodesAndTokens()) { if (child.IsNode) { csNode.Children.Add(DoConvert2CsJsonNode((SyntaxNode)child, opts, syntaxCount)); } else if (child.IsToken && opts.IsIncludeToken) { var token = (SyntaxToken)child; csNode.Children.Add(new Cs2JsonNode() { Name = token.Kind().ToString(), Contents = token.ValueText, IsToken = true, Children = new List <Cs2JsonNode>() }); } } return(csNode); }
protected override void DefaultVisit(SyntaxNode node) { if (node == null) { return; } foreach (var child in node.ChildNodesAndTokens()) { if (child.IsNode) { if (Depth >= SyntaxListenerDepth.Node) { Visit(child.AsNode()); } } else if (child.IsToken) { if (Depth >= SyntaxListenerDepth.Token) { VisitTokenImpl(child.AsToken()); } } } }
private void GetAllSymbols( SemanticModel model, SyntaxNode node, List <ISymbol> list, Func <SyntaxNode, bool> predicate) { if (predicate == null || predicate(node)) { var symbol = model.GetDeclaredSymbol(node); if (symbol != null) { list.Add(symbol); } symbol = model.GetSymbolInfo(node).GetAnySymbol(); if (symbol != null) { list.Add(symbol); } } foreach (var child in node.ChildNodesAndTokens()) { if (child.IsNode) { GetAllSymbols(model, child.AsNode(), list, predicate); } } }
public override void DefaultVisit(SyntaxNode node) { var childCnt = node.ChildNodesAndTokens().Count; int i = 0; do { var child = ChildSyntaxList.ItemInternal((CSharpSyntaxNode)node, i); i++; var asNode = child.AsNode(); if (asNode != null) { if (this.Depth >= SyntaxWalkerDepth.Node) { this.Visit(asNode); } } else { if (this.Depth >= SyntaxWalkerDepth.Token) { this.VisitToken(child.AsToken()); } } } while (i < childCnt); }
/// <summary> /// Returns child node or token that contains given position. /// </summary> /// <remarks> /// This is a copy of <see cref="SyntaxNode.ChildThatContainsPosition"/> that also returns the index of the child node. /// </remarks> internal static SyntaxNodeOrToken ChildThatContainsPosition(this SyntaxNode self, int position, out int childIndex) { var childList = self.ChildNodesAndTokens(); int left = 0; int right = childList.Count - 1; while (left <= right) { int middle = left + ((right - left) / 2); SyntaxNodeOrToken node = childList[middle]; var span = node.FullSpan; if (position < span.Start) { right = middle - 1; } else if (position >= span.End) { left = middle + 1; } else { childIndex = middle; return(node); } } // we could check up front that index is within FullSpan, // but we wan to optimize for the common case where position is valid. Debug.Assert(!self.FullSpan.Contains(position), "Position is valid. How could we not find a child?"); throw new ArgumentOutOfRangeException(nameof(position)); }
private List <ExpressionSyntax> GetExprSyntaxList( SyntaxNode node, List <ExpressionSyntax> exprSynList ) { if (exprSynList == null) { exprSynList = new List <ExpressionSyntax>(); } if (node is ExpressionSyntax) { exprSynList.Add(node as ExpressionSyntax); } foreach (var child in node.ChildNodesAndTokens()) { if (child.IsNode) { exprSynList = GetExprSyntaxList(child.AsNode(), exprSynList); } } return(exprSynList); }
public static SyntaxNode FindPartner(SyntaxNode leftRoot, SyntaxNode rightRoot, SyntaxNode leftNode) { // Finding a partner of a zero-width node is complicated and not supported atm: Debug.Assert(leftNode.FullSpan.Length > 0); Debug.Assert(leftNode.SyntaxTree == leftRoot.SyntaxTree); SyntaxNode originalLeftNode = leftNode; int leftPosition = leftNode.SpanStart; leftNode = leftRoot; SyntaxNode rightNode = rightRoot; while (leftNode != originalLeftNode) { Debug.Assert(leftNode.RawKind == rightNode.RawKind); int childIndex; var leftChild = leftNode.ChildThatContainsPosition(leftPosition, out childIndex); // Can only happen when searching for zero-width node. Debug.Assert(!leftChild.IsToken); rightNode = rightNode.ChildNodesAndTokens().ElementAt(childIndex).AsNode(); leftNode = leftChild.AsNode(); } return(rightNode); }
private void Recurse( SyntaxTreeAnalysisContext context, ReportDiagnostic severity, SyntaxNode node ) { context.CancellationToken.ThrowIfCancellationRequested(); // Don't bother analyzing nodes that have syntax errors in them. if (node.ContainsDiagnostics) { return; } // Report on the topmost statement that has an issue. No need to recurse further at that point. Note: the // fixer will fix up all statements, but we don't want to clutter things with lots of diagnostics on the // same line. if ( node is StatementSyntax statement && CheckStatementSyntax(context, severity, statement) ) { return; } foreach (var child in node.ChildNodesAndTokens()) { if (child.IsNode) { Recurse(context, severity, child.AsNode() !); } } }
private bool ImplicitMemberAccessWouldBeAffected(SyntaxNode node) { if (node != null) { foreach (var child in node.ChildNodesAndTokens()) { if (child.IsNode) { if (ImplicitMemberAccessWouldBeAffected(child.AsNode())) { return(true); } } } if (_syntaxFacts.IsSimpleMemberAccessExpression(node)) { var expression = _syntaxFacts.GetExpressionOfMemberAccessExpression( node, allowImplicitTarget: true); // If we're implicitly referencing some target that is before the // object creation expression, then our semantics will change. if (expression != null && expression.SpanStart < _objectCreationExpression.SpanStart) { return(true); } } } return(false); }
private void SerializeNode(SyntaxNode node, IFastJsonWriter writer, string specialParentPropertyName = null) { writer.WriteStartObject(); writer.WriteProperty("type", "node"); writer.WriteProperty("kind", RoslynSyntaxHelper.GetKindName(node.RawKind)); var parentPropertyName = specialParentPropertyName ?? RoslynSyntaxHelper.GetParentPropertyName(node); if (parentPropertyName != null) { writer.WriteProperty("property", parentPropertyName); } SerializeSpanProperty(node.FullSpan, writer); writer.WritePropertyStartArray("children"); foreach (var child in node.ChildNodesAndTokens()) { if (child.IsNode) { SerializeNode(child.AsNode(), writer); } else { SerializeToken(child.AsToken(), writer); } } writer.WriteEndArray(); writer.WriteEndObject(); }
private void Recurse( SyntaxTreeAnalysisContext context, SyntaxNode node, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); // Don't bother analyzing nodes that have syntax errors in them. if (node.ContainsDiagnostics) { return; } foreach (var child in node.ChildNodesAndTokens()) { if (child.IsNode) { Recurse(context, child.AsNode(), cancellationToken); } else if (child.IsToken) { CheckToken(context, child.AsToken()); } } }
public static void FindLeafNodeAndPartner(SyntaxNode leftRoot, int leftPosition, SyntaxNode rightRoot, out SyntaxNode leftNode, out SyntaxNode rightNodeOpt) { leftNode = leftRoot; rightNodeOpt = rightRoot; while (true) { if (rightNodeOpt != null && leftNode.RawKind != rightNodeOpt.RawKind) { rightNodeOpt = null; } var leftChild = leftNode.ChildThatContainsPosition(leftPosition, out var childIndex); if (leftChild.IsToken) { return; } if (rightNodeOpt != null) { var rightNodeChildNodesAndTokens = rightNodeOpt.ChildNodesAndTokens(); if (childIndex >= 0 && childIndex < rightNodeChildNodesAndTokens.Count) { rightNodeOpt = rightNodeChildNodesAndTokens[childIndex].AsNode(); } else { rightNodeOpt = null; } } leftNode = leftChild.AsNode(); } }
private void Recurse( SyntaxTreeAnalysisContext context, ReportDiagnostic severity, SyntaxNode node, CancellationToken cancellationToken ) { if ( node.ContainsDiagnostics && node.GetDiagnostics().Any(d => d.Severity == DiagnosticSeverity.Error) ) { return; } if (IsBlockLikeStatement(node)) { ProcessBlockLikeStatement(context, severity, node); } foreach (var child in node.ChildNodesAndTokens()) { if (child.IsNode) { Recurse(context, severity, child.AsNode() !, cancellationToken); } } }
public static ObservableList <object> GetChilNodesOrTokens(this SyntaxNode node) { ObservableList <object> tmp = new ObservableList <object> (); var childs = node.ChildNodesAndTokens().GetEnumerator(); while (childs.MoveNext()) { var c = childs.Current; if (c.IsNode) { tmp.Add(c.AsNode()); continue; } SyntaxToken tok = c.AsToken(); if (tok.HasLeadingTrivia) { foreach (var trivia in tok.LeadingTrivia) { tmp.Add(trivia); } } tmp.Add(tok); if (tok.HasTrailingTrivia) { foreach (var trivia in tok.TrailingTrivia) { tmp.Add(trivia); } } } return(tmp); }
private void Recurse( SyntaxTreeAnalysisContext context, ReportDiagnostic severity, SyntaxNode node ) { context.CancellationToken.ThrowIfCancellationRequested(); // Don't bother analyzing nodes that have syntax errors in them. if (node.ContainsDiagnostics) { return; } if (node is ConstructorInitializerSyntax initializer) { ProcessConstructorInitializer(context, severity, initializer); } foreach (var child in node.ChildNodesAndTokens()) { if (child.IsNode) { Recurse(context, severity, child.AsNode() !); } } }
private static bool AreSemanticallyEquivalentWorker( SemanticModel semanticModel1, SemanticModel semanticModel2, SyntaxNode node1, SyntaxNode node2, Func <SyntaxNode, bool> predicate ) { if (node1 == node2) { return(true); } if (predicate == null || predicate(node1)) { var info1 = semanticModel1.GetSymbolInfo(node1); var info2 = semanticModel2.GetSymbolInfo(node2); if (!AreEquals(semanticModel1, semanticModel2, info1, info2)) { return(false); } } var e1 = node1.ChildNodesAndTokens().GetEnumerator(); var e2 = node2.ChildNodesAndTokens().GetEnumerator(); while (true) { var b1 = e1.MoveNext(); var b2 = e2.MoveNext(); Contract.ThrowIfTrue(b1 != b2); if (b1 == false) { return(true); } var c1 = e1.Current; var c2 = e2.Current; if (c1.IsNode && c2.IsNode) { if ( !AreSemanticallyEquivalentWorker( semanticModel1, semanticModel2, c1.AsNode(), c2.AsNode(), predicate ) ) { return(false); } } } }
public static CSNode CreateNode(SyntaxNode parent) { var children = parent.ChildNodesAndTokens(); var node = new CSNode(); node.STInfo = ((ushort)parent.Kind()).ToString(); node.UseRoslynMatchToWrite = false; node.RoslynSpanStart = parent.Span.Start; node.RoslynSpanEnd = parent.Span.End; foreach (var child in children) { if (child.IsNode) { node.AddChild(CreateNode(child.AsNode())); } else if (child.IsToken) { var tokenNode = new CSNode(); if (child.AsToken().Kind() != SyntaxKind.IdentifierToken) { tokenNode.STInfo = ((ushort)child.AsToken() .Kind()) .ToString(); tokenNode.RoslynSpanStart = child.Span.Start; tokenNode.RoslynSpanEnd = child.Span.End; tokenNode.UseRoslynMatchToWrite = true; tokenNode.CanHaveType = false; tokenNode.IsTreeLeaf = true; } else { tokenNode.STInfo = child.AsToken() .Kind() .ToString(); tokenNode.UseRoslynMatchToWrite = false; tokenNode.CanHaveType = true; var leaf = new CSNode(); leaf.STInfo = child.AsToken().ValueText; leaf.UseRoslynMatchToWrite = false; leaf.CanHaveType = false; leaf.IsTreeLeaf = true; tokenNode.AddChild(leaf); } node.AddChild(tokenNode); } } return(node); }
public static XElement ToXml( this SyntaxNode node, SyntaxTree syntaxTree, XmlOptions options = null ) { if (options == null) { options = new XmlOptions(); } XElement xml = null; if (node != null) { xml = new XElement( "Node", new XAttribute("IsToken", false), new XAttribute("IsTrivia", true), new XAttribute("Kind", node.GetKind()), new XAttribute("IsMissing", node.IsMissing) ); if (options.Spans) { xml.Add( @"<Span Start=<%= node.SpanStart %> End=<%= node.Span.End %> Length=<%= node.Span.Length %>/>" ); xml.Add( @"<FullSpan Start=<%= node.FullSpan.Start %> End=<%= node.FullSpan.End %> Length=<%= node.FullSpan.Length %>/>" ); } if (options.ReflectionInfo) { AddInfo(node, xml, options); } if (options.Errors) { if (syntaxTree.GetDiagnostics(node).Any()) { AddErrors(xml, syntaxTree.GetDiagnostics(node), options); } } foreach (var c in node.ChildNodesAndTokens()) { xml.Add(c.ToXml(syntaxTree, options)); } } return(xml); }
public static SimpleSyntaxNode FromSyntax(SyntaxNode node) { var children = node .ChildNodesAndTokens() .Select(nodeOrToken => nodeOrToken.IsNode ? FromSyntax(nodeOrToken.AsNode()) : FromSyntax(nodeOrToken.AsToken())) .ToList(); return(new SimpleSyntaxNode(SyntaxNodeType.Node, node.Kind(), children)); }
private IEnumerable<SyntaxNode> EnumerateChildren(SyntaxNode node) { foreach (var child in node.ChildNodesAndTokens()) { var childNode = child.AsNode(); if (childNode != null && GetLabel(childNode) != IgnoredNode) { yield return childNode; } } }
void AddNode(TreeNavigator treeNavigator, SyntaxNode syntaxNode) { var leadingTrivia = syntaxNode.GetLeadingTrivia(); var trailingTrivia = syntaxNode.GetTrailingTrivia(); AddLeadingTrivia(leadingTrivia); SetNodeText(treeNavigator, syntaxNode.GetType().Name, syntaxNode.Span, Colors.DarkBlue); foreach (var child in syntaxNode.ChildNodesAndTokens()) { treeNavigator.AddChild(); if (child.IsNode) { AddNode(treeNavigator, child.AsNode()); } else { var token = child.AsToken(); if (token.LeadingTrivia != leadingTrivia) { AddLeadingTrivia(token.LeadingTrivia); } SetNodeText(treeNavigator, token.GetType().Name, token.Span, Colors.DarkGreen); if (token.TrailingTrivia != trailingTrivia) { AddTrailingTrivia(token.TrailingTrivia); } } treeNavigator.MoveToParent(); } AddTrailingTrivia(trailingTrivia); void AddLeadingTrivia(SyntaxTriviaList triviaList) { foreach (var trivia in triviaList) { AddTrivia(trivia); treeNavigator.InsertAfter(); } } void AddTrailingTrivia(SyntaxTriviaList triviaList) { foreach (var trivia in triviaList) { treeNavigator.InsertAfter(); AddTrivia(trivia); } } void AddTrivia(SyntaxTrivia trivia) => SetNodeText(treeNavigator, trivia.GetType().Name, trivia.Span, Colors.DarkRed); }
private IEnumerable <SyntaxNode> EnumerateChildren(SyntaxNode node) { foreach (var child in node.ChildNodesAndTokens()) { var childNode = child.AsNode(); if (childNode != null && GetLabel(childNode) != IgnoredNode) { yield return(childNode); } } }
private static bool AreSemanticallyEquivalentWorker( SemanticModel semanticModel1, SemanticModel semanticModel2, SyntaxNode node1, SyntaxNode node2, Func<SyntaxNode, bool> predicate) { if (node1 == node2) { return true; } if (predicate == null || predicate(node1)) { var info1 = semanticModel1.GetSymbolInfo(node1); var info2 = semanticModel2.GetSymbolInfo(node2); if (!AreEquals(semanticModel1, semanticModel2, info1, info2)) { return false; } } var e1 = node1.ChildNodesAndTokens().GetEnumerator(); var e2 = node2.ChildNodesAndTokens().GetEnumerator(); while (true) { var b1 = e1.MoveNext(); var b2 = e2.MoveNext(); if (b1 != b2) { Contract.Fail(); return false; } if (b1 == false) { return true; } var c1 = e1.Current; var c2 = e2.Current; if (c1.IsNode && c2.IsNode) { if (!AreSemanticallyEquivalentWorker(semanticModel1, semanticModel2, c1.AsNode(), c2.AsNode(), predicate)) { return false; } } } }
protected static void AppendTokens(SyntaxNode node, StringBuilder builder) { foreach (var child in node.ChildNodesAndTokens()) { if (child.IsToken) { builder.Append(child.AsToken().Text); } else { AppendTokens(child.AsNode(), builder); } } }
public void Recurse(SyntaxNode root, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); foreach (var child in root.ChildNodesAndTokens()) { if (child.IsNode) { Recurse(child.AsNode() !, cancellationToken); } else { ProcessToken(child.AsToken(), cancellationToken); } } }
private void HighlightRelatedKeywords(SyntaxNode node, List <TextSpan> spans, bool highlightBreaks, bool highlightGotos) { Debug.Assert(highlightBreaks || highlightGotos); if (highlightBreaks && node is BreakStatementSyntax breakStatement) { spans.Add(breakStatement.BreakKeyword.Span); spans.Add(EmptySpan(breakStatement.SemicolonToken.Span.End)); } else if (highlightGotos && node is GotoStatementSyntax gotoStatement) { // We only want to highlight 'goto case' and 'goto default', not plain old goto statements, // but if the label is missing, we do highlight 'goto' assuming it's more likely that // the user is in the middle of typing 'goto case' or 'goto default'. if (gotoStatement.IsKind(SyntaxKind.GotoCaseStatement, SyntaxKind.GotoDefaultStatement) || gotoStatement.Expression.IsMissing) { var start = gotoStatement.GotoKeyword.SpanStart; var end = !gotoStatement.CaseOrDefaultKeyword.IsKind(SyntaxKind.None) ? gotoStatement.CaseOrDefaultKeyword.Span.End : gotoStatement.GotoKeyword.Span.End; spans.Add(TextSpan.FromBounds(start, end)); spans.Add(EmptySpan(gotoStatement.SemicolonToken.Span.End)); } } else { foreach (var childNodeOrToken in node.ChildNodesAndTokens()) { if (childNodeOrToken.IsToken) { continue; } var child = childNodeOrToken.AsNode(); var highlightBreaksForChild = highlightBreaks && !child.IsBreakableConstruct(); var highlightGotosForChild = highlightGotos && !child.IsKind(SyntaxKind.SwitchStatement); // Only recurse if we have anything to do if (highlightBreaksForChild || highlightGotosForChild) { HighlightRelatedKeywords(child, spans, highlightBreaksForChild, highlightGotosForChild); } } } }
public bool FirstChildSpan(SyntaxNode nonTerminal, SyntaxTree tree, ref string errorText) { var retVal = true; var firstChild = nonTerminal.ChildNodesAndTokens().First(); if (nonTerminal.SpanStart != firstChild.SpanStart) { retVal = false; errorText = "Start Span of first child of this non-terminal does not coincide with start Span of this non-terminal"; } else if (nonTerminal.FullSpan.Start != firstChild.FullSpan.Start) { retVal = false; errorText = "Start FullSpan of first child of this non-terminal does not coincide with start FullSpan of this non-terminal"; } return retVal; }
public static void FindLeafNodeAndPartner(SyntaxNode leftRoot, int leftPosition, SyntaxNode rightRoot, out SyntaxNode leftNode, out SyntaxNode rightNode) { leftNode = leftRoot; rightNode = rightRoot; while (true) { Debug.Assert(leftNode.RawKind == rightNode.RawKind); var leftChild = leftNode.ChildThatContainsPosition(leftPosition, out var childIndex); if (leftChild.IsToken) { return; } rightNode = rightNode.ChildNodesAndTokens()[childIndex].AsNode(); leftNode = leftChild.AsNode(); } }
public bool LastChildSpan(SyntaxNode nonTerminal, SyntaxTree tree, ref string errorText) { var retVal = true; var lastChild = nonTerminal.ChildNodesAndTokens().Last(); if (nonTerminal.Span.End != lastChild.Span.End) { retVal = false; errorText = "End Span of last child of this non-terminal does not coincide with end Span of this non-terminal"; } else if (nonTerminal.FullSpan.End != lastChild.FullSpan.End) { retVal = false; errorText = "End FullSpan of last child of this non-terminal does not coincide with end FullSpan of this non-terminal"; } return retVal; }
private IEnumerable<SyntaxNode> EnumerateChildren(SyntaxNode node) { foreach (var child in node.ChildNodesAndTokens()) { var childNode = child.AsNode(); if (childNode != null) { if (GetLabel(childNode) != IgnoredNode) { yield return childNode; } else { foreach (var descendant in childNode.DescendantNodesAndTokens(SyntaxUtilities.IsNotLambda)) { if (EnumerateExpressionDescendant(descendant.Kind())) { yield return descendant.AsNode(); } } } } } }
protected List<SyntaxNode> GetSyntaxNodeList(SyntaxNode node, List<SyntaxNode> synList) { if (synList == null) synList = new List<SyntaxNode>(); synList.Add(node); foreach (var child in node.ChildNodesAndTokens()) { if (child.IsNode) synList = GetSyntaxNodeList(child.AsNode(), synList); } return synList; }
public bool ZeroWidthOrMissingNonTerminals(SyntaxNode nonTerminal, SyntaxTree tree, ref string errorText) { var retVal = true; if (nonTerminal.ContainsDiagnostics || tree.GetDiagnostics().Any()) { if (nonTerminal.IsMissing) { if (nonTerminal.Span.Length == 0) { foreach (var child in nonTerminal.ChildNodesAndTokens()) { if (child.IsNode && !child.AsNode().IsMissing) { retVal = false; errorText = "This missing non-terminal has a non-missing child non-terminal"; continue; } else if (child.IsToken && !child.AsToken().IsMissing) { retVal = false; errorText = "This missing non-terminal has a non-missing child token"; continue; } } } else { retVal = false; errorText = "Missing non-terminals should have 0 Span width"; } } else if (nonTerminal.Span.Length == 0) { var kind = nonTerminal.GetKind(); if (!(kind == "OmittedArgument" || kind.Contains("Bad") || (kind == "CompilationUnit" && nonTerminal.ChildNodesAndTokens().Count == 1 && nonTerminal.ChildNodesAndTokens().First().GetKind() == "EndOfFileToken"))) { //Ignore BadStatement and BadDirective (these can only be present if tree has errors). //Ignore case where code file is empty or file only includes trivia - in this case //root node will have a single child ('EndOfFileToken') which has 0 width. retVal = false; errorText = "Non-terminals with 0 Span width should have IsMissing set to 'True'"; } } } else { if (nonTerminal.IsMissing) { retVal = false; errorText = "A tree with 0 errors should not contain missing non-terminals"; } else if (nonTerminal.Span.Length == 0) { var kind = nonTerminal.GetKind(); if (!(kind == "OmittedArgument" || (kind == "CompilationUnit" && nonTerminal.ChildNodesAndTokens().Count == 1 && nonTerminal.ChildNodesAndTokens().First().GetKind() == "EndOfFileToken"))) { //Ignore case where code file is empty or file only includes trivia - in this case //root node will have a single child ('EndOfFileToken') which has 0 width. retVal = false; errorText = "A tree with 0 errors should not contain non-terminals with 0 width"; } } } return retVal; }
public bool ChildSpanWidth(SyntaxNode nonTerminal, SyntaxTree tree, ref string errorText) { var retVal = true; var total = 0; foreach (var child in nonTerminal.ChildNodesAndTokens()) { total = child.FullSpan.Length; } if (nonTerminal.FullSpan.Length != total) { retVal = false; errorText = "FullSpan width of this non-terminal (" + nonTerminal.FullSpan.Length + ") does not match sum of FullSpan widths of its children (" + total + ")"; } return retVal; }
private static TextSpan GetHintSpan(SyntaxNode node, int endPos) { // Don't include attributes in the BlockSpan for a node. When the user // hovers over the indent-guide we don't want to show them the line with // the attributes, we want to show them the line with the start of the // actual structure. foreach (var child in node.ChildNodesAndTokens()) { if (child.Kind() != SyntaxKind.AttributeList) { return TextSpan.FromBounds(child.SpanStart, endPos); } } return TextSpan.FromBounds(node.SpanStart, endPos); }
private static void GetExpressionSyntax(SyntaxNode node, List<ExpressionSyntax> exprSynList) { if (node is ExpressionSyntax) exprSynList.Add(node as ExpressionSyntax); foreach (var child in node.ChildNodesAndTokens()) if (child.IsNode) GetExpressionSyntax(child.AsNode(), exprSynList); }
private ITypeSymbol InferTypeForFirstParameterOfLambda( string parameterName, SyntaxNode node) { if (node.IsKind(SyntaxKind.IdentifierName)) { var identifierName = (IdentifierNameSyntax)node; if (identifierName.Identifier.ValueText.Equals(parameterName) && SemanticModel.GetSymbolInfo(identifierName.Identifier).Symbol?.Kind == SymbolKind.Parameter) { return InferTypes(identifierName).FirstOrDefault().InferredType; } } else { foreach (var child in node.ChildNodesAndTokens()) { if (child.IsNode) { var type = InferTypeForFirstParameterOfLambda(parameterName, child.AsNode()); if (type != null) { return type; } } } } return null; }
public bool SpanAndFullSpanForNonTerminal(SyntaxNode nonTerminal, SyntaxTree tree, ref string errorText) { var retVal = true; if (nonTerminal.ChildNodesAndTokens().Any()) { if (nonTerminal.FullSpan.Start > nonTerminal.SpanStart || nonTerminal.Span.End > nonTerminal.FullSpan.End) { retVal = false; errorText = "FullSpan of this non-terminal does not enclose its Span"; } } else { retVal = false; errorText = "A non-terminal must have at least one child"; } return retVal; }
public bool ParentAndChildrenForNonTerminal(SyntaxNode nonTerminal, SyntaxTree tree, ref string errorText) { var retVal = true; foreach (var child in nonTerminal.ChildNodesAndTokens()) { if (child.Parent != nonTerminal) { retVal = false; errorText = "A child of this non-terminal does not have this non-terminal set as its parent"; continue; } } return retVal; }
private bool ValidateNonTerminal(SyntaxNode nonTerminal, SyntaxTree tree, string filename = "", List<Failure> failures = null) { var retVal = true; if (!string.IsNullOrEmpty(filename)) { filename = Path.GetFullPath(filename); } else if (filename == null) { filename = string.Empty; } if (nonTerminal != null) { foreach (var child in nonTerminal.ChildNodesAndTokens()) { retVal = retVal & ValidateNodeOrToken(child, tree, filename, failures); } bool pass = false; foreach (var rule in m_NonTerminalRules.Values) { var errorText = string.Empty; pass = rule.Test(nonTerminal, tree, ref errorText); if (!pass) { if (failures != null) { failures.Add(new Failure(filename, rule, nonTerminal.GetKind(), errorText, new FailureLocation(nonTerminal.Span, tree))); } ValidationFailed(errorText, rule); } retVal = retVal & pass; } } return retVal; }
private static DgmlNode ProcessNode(SyntaxNode node, int indent = 0) { var dgmlNode = DgmlNode.Create(node); PrintNode(dgmlNode, indent); foreach (var childNodeOrToken in node.ChildNodesAndTokens()) { if (childNodeOrToken.IsNode) dgmlNode.AddChild(ProcessNode((SyntaxNode)childNodeOrToken, indent + 1)); else if (childNodeOrToken.IsToken) dgmlNode.AddChild(ProcessToken((SyntaxToken)childNodeOrToken, indent + 1)); } return dgmlNode; }
public bool ChildSiblingSpan(SyntaxNode nonTerminal, SyntaxTree tree, ref string errorText) { var retVal = true; var curStart = -1; var prvEnd = -1; foreach (var child in nonTerminal.ChildNodesAndTokens()) { curStart = child.SpanStart; if (prvEnd == -1) { prvEnd = curStart; } if (curStart < prvEnd) { retVal = false; errorText = "Start Span of a child of this non-terminal is less than the end Span of this child's preceding sibling"; continue; } prvEnd = child.Span.End; } if (retVal) { curStart = -1; prvEnd = -1; foreach (var child in nonTerminal.ChildNodesAndTokens()) { curStart = child.FullSpan.Start; if (prvEnd == -1) { prvEnd = curStart; } if (curStart != prvEnd) { retVal = false; errorText = "FullSpan of a child of this non-terminal is not adjacent to the FullSpan of this child's preceding sibling"; continue; } prvEnd = child.FullSpan.End; } } return retVal; }
private List<ExpressionSyntax> GetExprSyntaxList(SyntaxNode node, List<ExpressionSyntax> exprSynList) { if (exprSynList == null) exprSynList = new List<ExpressionSyntax>(); if (node is ExpressionSyntax) { exprSynList.Add(node as ExpressionSyntax); } foreach (var child in node.ChildNodesAndTokens()) { if (child.IsNode) exprSynList = GetExprSyntaxList(child.AsNode(), exprSynList); } return exprSynList; }