예제 #1
0
        protected SyntaxNodeOrToken M(SyntaxKind kind)
        {
            Assert.True(treeEnumerator.MoveNext());
            SyntaxNodeOrToken current = this.treeEnumerator.Current;

            Assert.Equal(kind, current.CSharpKind());
            Assert.True(current.IsMissing);
            return(current);
        }
예제 #2
0
            private bool CanReuse(SyntaxNodeOrToken nodeOrToken)
            {
                // Zero width nodes and tokens always indicate that the parser had to do
                // something tricky, so don't reuse them.
                // NOTE: this is slightly different from IsMissing because of omitted type arguments
                // and array size expressions.
                if (nodeOrToken.FullWidth == 0)
                {
                    return(false);
                }

                // As of 2013/03/14, the compiler never attempts to incrementally parse a tree containing
                // annotations.  Our goal in instituting this restriction is to prevent API clients from
                // taking a depedency on the survival of annotations.
                if (nodeOrToken.ContainsAnnotations)
                {
                    return(false);
                }

                // We can't reuse a node or token if it intersects a changed text range.
                if (this.IntersectsNextChange(nodeOrToken))
                {
                    return(false);
                }

                // don't reuse nodes or tokens with skipped text or diagnostics attached to them
                if (nodeOrToken.ContainsDiagnostics ||
                    (nodeOrToken.IsToken && ((CSharpSyntaxNode)nodeOrToken.AsToken().Node).ContainsSkippedText && nodeOrToken.Parent.ContainsDiagnostics))
                {
                    return(false);
                }

                // fabricated tokens did not come from the lexer (likely from parser)
                if (IsFabricatedToken(nodeOrToken.CSharpKind()))
                {
                    return(false);
                }

                // don't reuse nodes that are incomplete. this helps cases were an incomplete node
                // completes differently after a change with far look-ahead.
                //
                // NOTE(cyrusn): It is very unfortunate that we even need this check given that we
                // have already checked for ContainsDiagnostics above.  However, there is a case where we
                // can have a node with a missing token *and* there are no diagnostics.
                // Specifically, this happens in the REPL when you have the last statement without a
                // trailing semicolon.  We treat this as an ExpressionStatement with a missing
                // semicolon, but we do not report errors.  It would be preferable to fix that so
                // that the semicolon can be optional rather than abusing the system.
                if ((nodeOrToken.IsToken && nodeOrToken.AsToken().IsMissing) ||
                    (nodeOrToken.IsNode && IsIncomplete((CSharp.CSharpSyntaxNode)nodeOrToken.AsNode())))
                {
                    return(false);
                }


                return(true);
            }
예제 #3
0
        private void AssertNodesAreEquivalent(SyntaxNodeOrToken expectedNode, SyntaxNodeOrToken actualNode)
        {
            Assert.Equal(expectedNode.CSharpKind(), actualNode.CSharpKind());
            Assert.Equal(expectedNode.FullSpan, actualNode.FullSpan);
            Assert.Equal(expectedNode.ChildNodesAndTokens().Count, actualNode.ChildNodesAndTokens().Count);

            for (var i = 0; i < expectedNode.ChildNodesAndTokens().Count; i++)
            {
                AssertNodesAreEquivalent(expectedNode.ChildNodesAndTokens()[i],
                                         actualNode.ChildNodesAndTokens()[i]);
            }
        }
예제 #4
0
        private static bool TryFindNodeOrToken(SyntaxNodeOrToken node, SyntaxKind kind, ref int occurrence, ref SyntaxNodeOrToken foundNode)
        {
            if (node.CSharpKind() == kind)
            {
                occurrence--;
                if (occurrence == 0)
                {
                    foundNode = node;
                    return(true);
                }
            }

            // we should probably did into trivia if this is a Token, but we won't

            foreach (var child in node.ChildNodesAndTokens())
            {
                if (TryFindNodeOrToken(child, kind, ref occurrence, ref foundNode))
                {
                    return(true);
                }
            }

            return(false);
        }
예제 #5
0
        private static void CompareTreeEquivalence(SyntaxNodeOrToken parsedTreeNode, SyntaxNodeOrToken incrementalTreeNode)
        {
            Assert.Equal(parsedTreeNode.CSharpKind(), incrementalTreeNode.CSharpKind());

            Assert.Equal(parsedTreeNode.ChildNodesAndTokens().Count, incrementalTreeNode.ChildNodesAndTokens().Count);

            for (int i = 0; i < parsedTreeNode.ChildNodesAndTokens().Count; i++)
            {
                CompareTreeEquivalence(parsedTreeNode.ChildNodesAndTokens()[i], incrementalTreeNode.ChildNodesAndTokens()[i]);
            }
        }
예제 #6
0
 private static bool IsNonZeroWidthOrIsEndOfFile(SyntaxNodeOrToken token)
 {
     return(token.CSharpKind() == SyntaxKind.EndOfFileToken || token.FullWidth != 0);
 }
예제 #7
0
 private static void Print(SyntaxNodeOrToken node)
 {
     Debug.WriteLine("{0}(SyntaxKind.{1});", node.IsMissing ? "M" : "N", node.CSharpKind());
 }
예제 #8
0
            private bool CanReuse(SyntaxNodeOrToken nodeOrToken)
            {
                // Zero width nodes and tokens always indicate that the parser had to do
                // something tricky, so don't reuse them.
                // NOTE: this is slightly different from IsMissing because of omitted type arguments
                // and array size expressions.
                if (nodeOrToken.FullWidth == 0)
                {
                    return false;
                }

                // As of 2013/03/14, the compiler never attempts to incrementally parse a tree containing
                // annotations.  Our goal in instituting this restriction is to prevent API clients from
                // taking a depedency on the survival of annotations.
                if (nodeOrToken.ContainsAnnotations)
                {
                    return false;
                }

                // We can't reuse a node or token if it intersects a changed text range.
                if (this.IntersectsNextChange(nodeOrToken))
                {
                    return false;
                }

                // don't reuse nodes or tokens with skipped text or diagnostics attached to them
                if (nodeOrToken.ContainsDiagnostics ||
                    (nodeOrToken.IsToken && ((CSharpSyntaxNode)nodeOrToken.AsToken().Node).ContainsSkippedText && nodeOrToken.Parent.ContainsDiagnostics))
                {
                    return false;
                }

                // fabricated tokens did not come from the lexer (likely from parser)
                if (IsFabricatedToken(nodeOrToken.CSharpKind()))
                {
                    return false;
                }

                // don't reuse nodes that are incomplete. this helps cases were an incomplete node
                // completes differently after a change with far look-ahead.
                //
                // NOTE(cyrusn): It is very unfortunate that we even need this check given that we
                // have already checked for ContainsDiagnostics above.  However, there is a case where we
                // can have a node with a missing token *and* there are no diagnostics.
                // Specifically, this happens in the REPL when you have the last statement without a
                // trailing semicolon.  We treat this as an ExpressionStatement with a missing
                // semicolon, but we do not report errors.  It would be preferable to fix that so
                // that the semicolon can be optional rather than abusing the system.
                if ((nodeOrToken.IsToken && nodeOrToken.AsToken().IsMissing) ||
                    (nodeOrToken.IsNode && IsIncomplete((CSharp.CSharpSyntaxNode)nodeOrToken.AsNode())))
                {
                    return false;
                }

                if (!nodeOrToken.ContainsDirectives)
                {
                    return true;
                }

                return this.newDirectives.IncrementallyEquivalent(this.oldDirectives);
            }
 private static bool IsNonZeroWidthOrIsEndOfFile(SyntaxNodeOrToken token)
 {
     return token.CSharpKind() == SyntaxKind.EndOfFileToken || token.FullWidth != 0;
 }
예제 #10
0
 private static void Print(SyntaxNodeOrToken node)
 {
     Debug.WriteLine("{0}(SyntaxKind.{1});", node.IsMissing ? "M" : "N", node.CSharpKind());
 }
예제 #11
0
        private void AssertNodesAreEquivalent(SyntaxNodeOrToken expectedNode, SyntaxNodeOrToken actualNode)
        {
            Assert.Equal(expectedNode.CSharpKind(), actualNode.CSharpKind());
            Assert.Equal(expectedNode.FullSpan, actualNode.FullSpan);
            Assert.Equal(expectedNode.ChildNodesAndTokens().Count, actualNode.ChildNodesAndTokens().Count);

            for (var i = 0; i < expectedNode.ChildNodesAndTokens().Count; i++)
            {
                AssertNodesAreEquivalent(expectedNode.ChildNodesAndTokens()[i], 
                    actualNode.ChildNodesAndTokens()[i]);
            }
        }