示例#1
0
        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);
        }
示例#2
0
        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);
                        }
                    }
                }
            }
        }
示例#3
0
        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));
                }
            }
        }
示例#4
0
        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);
                }
            }
        }
示例#7
0
        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);
        }
示例#8
0
        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());
                    }
                }
            }
        }
示例#9
0
        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);
                }
            }
        }
示例#10
0
        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);
        }
示例#11
0
        /// <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));
        }
示例#12
0
        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);
        }
示例#13
0
        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);
        }
示例#14
0
        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();
        }
示例#17
0
        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);
        }
        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());
                }
            }
        }
示例#19
0
        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();
            }
        }
示例#20
0
        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);
                }
            }
        }
示例#21
0
        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);
        }
示例#22
0
        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() !);
                }
            }
        }
示例#23
0
        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);
                    }
                }
            }
        }
示例#24
0
        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);
        }
示例#25
0
        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);
        }
示例#26
0
        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));
        }
示例#27
0
 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;
         }
     }
 }
示例#28
0
        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);
        }
示例#29
0
 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;
                    }
                }
            }
        }
示例#31
0
 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;
        }
示例#35
0
        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;
        }
示例#41
0
        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);
        }
示例#42
0
        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;
        }
示例#47
0
        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;
        }