示例#1
0
        internal static async Task <Document> AddAccessModifierAsync(
            Document document,
            SyntaxNode declaration,
            CancellationToken cancellationToken)
        {
            SyntaxNode oldRoot = await document.GetSyntaxRootAsync(cancellationToken);

            SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken);

            SyntaxKind  modifierKind  = GetModifierKind(declaration, semanticModel, cancellationToken);
            SyntaxToken modifierToken = SyntaxFactory.Token(modifierKind).WithTrailingSpace();

            SyntaxTokenList modifiers = declaration.GetDeclarationModifiers();

            SyntaxNode newDeclaration = declaration;

            if (modifiers.Count > 0)
            {
                modifiers = modifiers
                            .Replace(modifiers[0], modifiers[0].WithoutLeadingTrivia())
                            .Insert(0, modifierToken.WithLeadingTrivia(modifiers[0].LeadingTrivia));
            }
            else
            {
                SyntaxNodeOrToken nodeOrToken = GetNodeOrToken(declaration);

                if ((nodeOrToken.IsNode && nodeOrToken.AsNode() == null) ||
                    (nodeOrToken.IsToken && nodeOrToken.AsToken().IsKind(SyntaxKind.None)))
                {
                    Debug.Assert(false, "");
                    return(document);
                }

                modifiers = SyntaxFactory.TokenList(modifierToken.WithLeadingTrivia(nodeOrToken.GetLeadingTrivia()));

                if (nodeOrToken.IsNode)
                {
                    newDeclaration = declaration.ReplaceNode(
                        nodeOrToken.AsNode(),
                        nodeOrToken.AsNode().WithoutLeadingTrivia());
                }
                else
                {
                    newDeclaration = declaration.ReplaceToken(
                        nodeOrToken.AsToken(),
                        nodeOrToken.AsToken().WithoutLeadingTrivia());
                }
            }

            newDeclaration = GetNewDeclaration(newDeclaration, modifiers);

            SyntaxNode newRoot = oldRoot.ReplaceNode(declaration, newDeclaration);

            return(document.WithSyntaxRoot(newRoot));
        }
        private void NodeToJson(JsonWriter jw, SyntaxNodeOrToken node, Dictionary <SyntaxNodeOrToken, int> nodeToIdx)
        {
            jw.WriteStartObject();

            jw.WritePropertyName("id");
            jw.WriteValue(nodeToIdx[node]);

            jw.WritePropertyName("type");
            jw.WriteValue(node.Kind().ToString());

            if (node.IsKind(SyntaxKind.IdentifierName) || node.IsKind(SyntaxKind.PredefinedType) || RoslynUtils.IsSimpleLiteral(node) || node.IsToken || node.AsNode().ChildNodes().Count() == 0)
            {
                jw.WritePropertyName("value");
                jw.WriteValue(node.ToString());
            }
            else
            {
                jw.WritePropertyName("children");
                jw.WriteStartArray();
                foreach (var child in node.AsNode().ChildNodesAndTokens())
                {
                    if (!nodeToIdx.TryGetValue(child, out int idx))
                    {
                        idx = int.MaxValue;
                    }
                    jw.WriteValue(idx);
                }
                jw.WriteEndArray();
            }

            jw.WriteEndObject();
        }
示例#3
0
        public override Match Run(SyntaxNodeOrToken nodeOrToken)
        {
            if (nodeOrToken.Kind() != SyntaxKind.Argument)
                return Match.NoMatch;

            var argument = (ArgumentSyntax) nodeOrToken.AsNode();
            if (_variable.MinOccurrences == 1 && _variable.MaxOccurrences == 1)
                return Match.Success.WithSyntaxNodeOrToken(argument);

            var argumentList = argument.Parent as ArgumentListSyntax;
            if (argumentList == null)
                return Match.NoMatch;

            var currentIndex = argumentList.Arguments.IndexOf(argument);
            var availableCount = argumentList.Arguments.Count - currentIndex - _following;
            if (availableCount == 0)
                return Match.NoMatch;

            var captureCount = _variable.MaxOccurrences == null
                ? availableCount
                : Math.Min(availableCount, _variable.MaxOccurrences.Value);

            if (captureCount < _variable.MinOccurrences)
                return Match.NoMatch;

            var endIndex = currentIndex + captureCount - 1;
            var endArgument = argumentList.Arguments[endIndex];
            return Match.Success.AddCapture(_variable, argument, endArgument);
        }
示例#4
0
            public Cursor MoveToFirstChild()
            {
                Debug.Assert(this.CurrentNodeOrToken.IsNode);

                // Just try to get the first node directly.  This is faster than getting the list of
                // child nodes and tokens (which forces all children to be enumerated for the sake
                // of counting.  It should always be safe to index the 0th element of a node.  But
                // just to make sure that this is not a problem, we verify that the slotcount of the
                // node is greater than 0.
                var node = CurrentNodeOrToken.AsNode();

                if (node.SlotCount > 0)
                {
                    var child = Microsoft.CodeAnalysis.ChildSyntaxList.ItemInternal(node, 0);
                    if (IsNonZeroWidthOrIsEndOfFile(child))
                    {
                        return(new Cursor(child, 0));
                    }
                }

                // Fallback to enumerating all children.
                int index = 0;

                foreach (var child in this.CurrentNodeOrToken.ChildNodesAndTokens())
                {
                    if (IsNonZeroWidthOrIsEndOfFile(child))
                    {
                        return(new Cursor(child, index));
                    }

                    index++;
                }

                return(new Cursor());
            }
        public static void Dump(this SyntaxNodeOrToken nodeOrToken, TextWriter writer = null, int depth = 0)
        {
            const string indentString = "  ";

            if (nodeOrToken.IsMissing)
            {
                return;
            }

            writer = writer ?? Console.Out;

            for (int i = 0; i < depth; i++)
            {
                writer.Write(indentString);
            }

            if (nodeOrToken.IsNode)
            {
                var node = nodeOrToken.AsNode();
                writer.WriteLine("{0}: {1}", node.GetType().Name, node);
                foreach (var child in node.ChildNodesAndTokens())
                {
                    Dump(child, writer, depth + 1);
                }
            }
            else
            {
                var token = nodeOrToken.AsToken();
                writer.WriteLine("{0}: {1}", token.Kind(), token);
            }
        }
示例#6
0
    /// <summary>
    /// Recursive method that "quotes" a SyntaxNode, SyntaxToken, SyntaxTrivia or other objects.
    /// </summary>
    /// <returns>A description of Roslyn API calls necessary to recreate the input object.</returns>
    private ApiCall Quote(object treeElement, string name = null)
    {
        if (treeElement is SyntaxTrivia)
        {
            return(QuoteTrivia((SyntaxTrivia)treeElement));
        }

        if (treeElement is SyntaxToken)
        {
            return(QuoteToken((SyntaxToken)treeElement, name));
        }

        if (treeElement is SyntaxNodeOrToken)
        {
            SyntaxNodeOrToken syntaxNodeOrToken = (SyntaxNodeOrToken)treeElement;
            if (syntaxNodeOrToken.IsNode)
            {
                return(QuoteNode(syntaxNodeOrToken.AsNode(), name));
            }
            else
            {
                return(QuoteToken(syntaxNodeOrToken.AsToken(), name));
            }
        }

        return(QuoteNode((SyntaxNode)treeElement, name));
    }
        private bool MatchesIgnoringAxis(SyntaxNodeOrToken nodeOrToken, SyntaxQuery query)
        {
            var node = nodeOrToken.AsNode();

            if (node is ExpressionStatementSyntax statement && node.Kind() == ExpressionStatement)
            {
                return(MatchesIgnoringAxis(statement.Expression, query));
            }

            if (node is SwitchSectionSyntax switchSection)
            {
                foreach (var label in switchSection.Labels)
                {
                    if (MatchesSyntaxKindAndFilter(switchSection, label.Kind(), query))
                    {
                        return(true);
                    }
                }
            }

            if (node is PredefinedTypeSyntax predefinedType)
            {
                return(MatchesSyntaxKindAndFilter(predefinedType, predefinedType.Keyword.Kind(), query));
            }

            return(MatchesSyntaxKindAndFilter(nodeOrToken, nodeOrToken.Kind(), query));
        }
示例#8
0
        internal static double ComputeDistance(SyntaxNodeOrToken oldNodeOrToken, SyntaxNodeOrToken newNodeOrToken)
        {
            Debug.Assert(newNodeOrToken.IsToken == oldNodeOrToken.IsToken);

            double distance;

            if (oldNodeOrToken.IsToken)
            {
                var leftToken  = oldNodeOrToken.AsToken();
                var rightToken = newNodeOrToken.AsToken();

                distance = ComputeDistance(leftToken, rightToken);
                Debug.Assert(!SyntaxFactory.AreEquivalent(leftToken, rightToken) || distance == ExactMatchDist);
            }
            else
            {
                var leftNode  = oldNodeOrToken.AsNode();
                var rightNode = newNodeOrToken.AsNode();

                distance = ComputeDistance(leftNode, rightNode);
                Debug.Assert(!SyntaxFactory.AreEquivalent(leftNode, rightNode) || distance == ExactMatchDist);
            }

            return(distance);
        }
示例#9
0
        private static CompletionSyntax GetCompletionSyntax(SyntaxNodeOrToken nodeOrToken)
        {
            SyntaxNodeOrToken dot;
            SyntaxNode        prefix = null;

            if (nodeOrToken.IsNode)
            {
                prefix = nodeOrToken.AsNode();
                dot    = nodeOrToken.GetPreviousSibling();
                if (dot.Kind() != SyntaxKind.DotToken)
                {
                    return(new CompletionSyntax(null, prefix));
                }
            }
            else
            {
                if (nodeOrToken.Kind() != SyntaxKind.DotToken)
                {
                    return(new CompletionSyntax(null, prefix));
                }
                dot = nodeOrToken;
            }

            var previous = dot.GetPreviousSibling();

            return(previous.IsNode ? new CompletionSyntax(previous.AsNode(), prefix) : new CompletionSyntax(null, prefix));
        }
示例#10
0
        private static void CheckIfCommasAreAtTheSameLineAsThePreviousParameter(SyntaxNodeAnalysisContext context, SyntaxNodeOrTokenList nodeOrTokenList)
        {
            SyntaxNode previousNode = null;

            // If index is even we expecting parameter syntax node, otherwise we expecting comma token.
            for (int index = 0, count = nodeOrTokenList.Count; index < count; ++index)
            {
                SyntaxNodeOrToken nodeOrToken = nodeOrTokenList[index];
                if (index % 2 == 0)
                {
                    // We expecting node here
                    if (nodeOrToken.IsToken)
                    {
                        return;
                    }

                    previousNode = nodeOrToken.AsNode();
                }
                else
                {
                    // We expecting token here
                    if (nodeOrToken.IsNode)
                    {
                        return;
                    }

                    if (previousNode.GetEndLine() < nodeOrToken.GetLineSpan().StartLinePosition.Line)
                    {
                        var properties = TokenSpacingProperties.RemovePrecedingPreserveLayout;
                        context.ReportDiagnostic(Diagnostic.Create(Descriptor, nodeOrToken.GetLocation(), properties));
                    }
                }
            }
        }
示例#11
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));
                }
            }
        }
        public static FileLinePositionSpan GetSpan(SyntaxNodeOrToken nodeOrToken)
        {
            var span = nodeOrToken.Span;

            if (nodeOrToken.IsNode)
            {
                var node = nodeOrToken.AsNode();

                if (node is ConstructorDeclarationSyntax)
                {
                    var constructorDeclarationNode = node as ConstructorDeclarationSyntax;
                    span = constructorDeclarationNode.Identifier.Span;
                }
                else if (node is MethodDeclarationSyntax)
                {
                    var methodDeclarationNode = node as MethodDeclarationSyntax;
                    span = methodDeclarationNode.Identifier.Span;
                }
                else if (node is AccessorDeclarationSyntax)
                {
                    var accessprDecl = node as AccessorDeclarationSyntax;
                    span = accessprDecl.Keyword.Span;
                }

                else if (node is ObjectCreationExpressionSyntax)
                {
                    var objectCreationExpression = node as ObjectCreationExpressionSyntax;
                    span = objectCreationExpression.Type.Span;
                }
                else if (node is MemberAccessExpressionSyntax)
                {
                    var memberAccess = node as MemberAccessExpressionSyntax;
                    span = memberAccess.Name.Span;
                }
                else if (node is InvocationExpressionSyntax)
                {
                    var invocationExpression = node as InvocationExpressionSyntax;
                    span = invocationExpression.Expression.Span;

                    if (invocationExpression.Expression is MemberAccessExpressionSyntax)
                    {
                        var memberAccess = invocationExpression.Expression as MemberAccessExpressionSyntax;
                        span = memberAccess.Name.Span;
                    }
                    else
                    {
                    }
                }
                else
                {
                }
            }
            else
            {
            }

            var result = nodeOrToken.SyntaxTree.GetLineSpan(span);

            return(result);
        }
示例#13
0
        void ParseAccessNode(SyntaxNode sn, ParsingState state)
        {
            SyntaxNodeOrToken snt = sn.ChildNodesAndTokens().First();

            if (snt.Kind().Equals(SyntaxKind.SimpleMemberAccessExpression))
            {
                ParseAccessNode(snt.AsNode(), state);
            }
            else if (snt.IsNode)
            {
                ParseNode(snt.AsNode(), state);
            }
            else if (snt.IsToken)
            {
                ParseCommonToken(snt.AsToken(), state);
            }
        }
示例#14
0
        private static bool IsTypeName(
            SyntaxNodeOrToken nodeOrToken,
            SemanticModel semanticModel,
            CancellationToken cancellationToken)
        {
            // Syntactically, everything works out. We're in a pretty good spot to show 'when' now.
            // But let's not do it just yet... Consider these cases:
            // case SyntaxNode |
            // case SyntaxNode w|
            // If what we have here is known to be a type, we don't want to clutter the variable name suggestion list
            // with 'when' since we know that the resulting code would be semantically invalid.

            bool isVar;
            ImmutableArray <ISymbol> symbols;

            if (nodeOrToken.IsNode)
            {
                var node       = nodeOrToken.AsNode();
                var expression = node as ExpressionSyntax
                                 ?? (node as ConstantPatternSyntax)?.Expression;

                if (!(expression is TypeSyntax typeSyntax))
                {
                    return(false);
                }

                // We don't pass in the semantic model - let IsPotentialTypeName handle the cases where it's clear
                // from the syntax, but other than that, we need to do our own logic here.
                if (typeSyntax.IsPotentialTypeName(semanticModelOpt: null, cancellationToken))
                {
                    return(true);
                }

                isVar   = typeSyntax.IsVar;
                symbols = semanticModel.LookupName(typeSyntax, namespacesAndTypesOnly: false, cancellationToken);
            }
            else
            {
                // In a var pattern, the 'var' keyword is not wrapped in a type syntax, so we might just have a naked token.
                var token = nodeOrToken.AsToken();

                isVar   = token.Text == SyntaxFacts.GetText(SyntaxKind.VarKeyword);
                symbols = semanticModel.LookupSymbols(nodeOrToken.AsToken().SpanStart, null, token.Text);
            }

            if (symbols.Length == 0)
            {
                // For all unknown identifiers except var, we return false (therefore 'when' will be offered),
                // because the user could later create a type with this name OR a constant. We give them both options.
                // But with var, when there is no type or constant with this name, we instead make the reasonable
                // assumption that the user didn't just type 'var' to then create a constant named 'var', but really
                // is about to declare a variable. Therefore we don't want to interfere with the declaration.
                // However note that if such a constant already exists, we do the right thing and do offer 'when'.
                return(isVar);
            }

            return(symbols.All(symbol => symbol is IAliasSymbol || symbol is ITypeSymbol));
        }
        public static SyntaxNodeOrToken WithoutLeadingTrivia(this SyntaxNodeOrToken nodeOrToken)
        {
            if (nodeOrToken.IsNode)
            {
                return(nodeOrToken.AsNode().WithoutLeadingTrivia());
            }

            return(nodeOrToken.AsToken().WithoutLeadingTrivia());
        }
示例#16
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);
            }
示例#17
0
        public static Edit UpdateBetween(
            SyntaxNodeOrToken left, SyntaxTriviaList leftTrailingTrivia,
            SyntaxTriviaList rightLeadingTrivia, SyntaxNodeOrToken right)
        {
            var leftLastToken   = left.IsToken ? left.AsToken() : left.AsNode().GetLastToken();
            var rightFirstToken = right.IsToken ? right.AsToken() : right.AsNode().GetFirstToken();

            return(new Edit(leftLastToken, leftTrailingTrivia, rightFirstToken, rightLeadingTrivia));
        }
        public static SyntaxNode GetNode(this SyntaxNodeOrToken nodeOrToken)
        {
            if (!nodeOrToken.IsNode)
            {
                throw new ArgumentException("expected node", nameof(nodeOrToken));
            }

            return(nodeOrToken.AsNode());
        }
示例#19
0
        public IEnumerable <OutliningRegionSpan> FindRegions(SyntaxNodeOrToken nodeOrToken)
        {
            var node      = nodeOrToken.IsNode ? nodeOrToken.AsNode() : null;
            var typedNode = node as T;

            return(typedNode == null
                ? Enumerable.Empty <OutliningRegionSpan>()
                : FindRegions(typedNode));
        }
示例#20
0
        public TRoot Replace <TRoot>(TRoot root, SyntaxNodeOrToken oldNodeOrToken, SyntaxNodeOrToken newNodeOrToken) where TRoot : SyntaxNode
        {
            if (oldNodeOrToken.IsToken)
            {
                return(root.ReplaceToken(oldNodeOrToken.AsToken(), newNodeOrToken.AsToken()));
            }

            return(root.ReplaceNode(oldNodeOrToken.AsNode(), newNodeOrToken.AsNode()));
        }
示例#21
0
        internal Roslyn.Compilers.CSharp.SyntaxToken FindTokenInternal(int position)
        {
            SyntaxNodeOrToken syntaxNodeOrToken = (SyntaxNodeOrToken)this;

            while (syntaxNodeOrToken.AsNode() != null)
            {
                syntaxNodeOrToken = Roslyn.Compilers.CSharp.SyntaxNode.GetChildThatContainsPosition(syntaxNodeOrToken.ChildNodesAndTokens(), position);
            }
            return(syntaxNodeOrToken.AsToken());
        }
示例#22
0
        private void ClassifyNodeOrToken(SyntaxNodeOrToken nodeOrToken)
        {
            if (nodeOrToken.IsToken)
            {
                ClassifyToken(nodeOrToken.AsToken());
                return;
            }

            ClassifyNode(nodeOrToken.AsNode());
        }
示例#23
0
        private void ClassifyNodeOrToken(SyntaxNodeOrToken nodeOrToken)
        {
            if (nodeOrToken.IsToken)
            {
                ClassifyToken(nodeOrToken.AsToken());
                return;
            }

            ClassifyNode(nodeOrToken.AsNode());
        }
示例#24
0
        private void TestAnnotation(SyntaxAnnotation annotation, SyntaxNode root, SyntaxNodeOrToken oldNodeOrToken)
        {
            // Test for existence of exactly one annotation
            if (oldNodeOrToken.IsToken)
            {
                TestAnnotation(annotation, root, oldNodeOrToken.AsToken());
                return;
            }

            TestAnnotation(annotation, root, oldNodeOrToken.AsNode());
        }
示例#25
0
 private static int GetEndPosition(SyntaxNodeOrToken nodeOrToken)
 {
     if (nodeOrToken.IsToken)
     {
         return(nodeOrToken.Span.End);
     }
     else
     {
         return(nodeOrToken.AsNode().GetLastToken().Span.End);
     }
 }
示例#26
0
 public virtual object ExtractValue(SyntaxNodeOrToken nodeOrToken)
 {
     if (nodeOrToken.IsToken)
     {
         return(nodeOrToken.AsToken().Value);
     }
     else
     {
         return(ExtractValue(nodeOrToken.AsNode().ToString()));
     }
 }
        // Helpers for populating the treeview.

        private void AddNodeOrToken(TreeViewItem parentItem, SyntaxNodeOrToken nodeOrToken)
        {
            if (nodeOrToken.IsNode)
            {
                AddNode(parentItem, nodeOrToken.AsNode());
            }
            else
            {
                AddToken(parentItem, nodeOrToken.AsToken());
            }
        }
示例#28
0
            public Cursor MoveToFirstChild()
            {
                Debug.Assert(this.CurrentNodeOrToken.IsNode);

                // Just try to get the first node directly.  This is faster than getting the list of
                // child nodes and tokens (which forces all children to be enumerated for the sake
                // of counting.  It should always be safe to index the 0th element of a node.  But
                // just to make sure that this is not a problem, we verify that the slot count of the
                // node is greater than 0.
                var node = CurrentNodeOrToken.AsNode();

                // Interpolated strings cannot be scanned or parsed incrementally. Instead they must be
                // turned into and then reparsed from the single InterpolatedStringToken.  We therefore
                // do not break interpolated string nodes down into their constituent tokens, but
                // instead replace the whole parsed interpolated string expression with its pre-parsed
                // interpolated string token.
                if (node.Kind() == SyntaxKind.InterpolatedStringExpression)
                {
                    var greenToken = Lexer.RescanInterpolatedString(
                        (InterpolatedStringExpressionSyntax)node.Green
                        );
                    var redToken = new CodeAnalysis.SyntaxToken(
                        node.Parent,
                        greenToken,
                        node.Position,
                        _indexInParent
                        );
                    return(new Cursor(redToken, _indexInParent));
                }

                if (node.SlotCount > 0)
                {
                    var child = Microsoft.CodeAnalysis.ChildSyntaxList.ItemInternal(node, 0);
                    if (IsNonZeroWidthOrIsEndOfFile(child))
                    {
                        return(new Cursor(child, 0));
                    }
                }

                // Fallback to enumerating all children.
                int index = 0;

                foreach (var child in this.CurrentNodeOrToken.ChildNodesAndTokens())
                {
                    if (IsNonZeroWidthOrIsEndOfFile(child))
                    {
                        return(new Cursor(child, index));
                    }

                    index++;
                }

                return(new Cursor());
            }
示例#29
0
 public virtual string ExtractMetadataName(SyntaxNodeOrToken nodeOrToken)
 {
     if (nodeOrToken.IsToken)
     {
         return(nodeOrToken.AsToken().ValueText);
     }
     else
     {
         return(nodeOrToken.AsNode().ToString());
     }
 }
示例#30
0
        private void ClassifyNodeOrToken(SyntaxNodeOrToken nodeOrToken)
        {
            Debug.Assert(nodeOrToken.IsNode || nodeOrToken.IsToken);

            if (nodeOrToken.IsToken)
            {
                ClassifyToken(nodeOrToken.AsToken());
                return;
            }

            ClassifyNode(nodeOrToken.AsNode() !);
        }
 public static Result IsTokenwiseEquivalent(SyntaxNodeOrToken nodeOrTokenA, SyntaxNodeOrToken nodeOrTokenB)
 {
     if (nodeOrTokenA.IsNode && nodeOrTokenB.IsNode)
     {
         return(IsTokenwiseEquivalent(nodeOrTokenA.AsNode(), nodeOrTokenB.AsNode()));
     }
     if (nodeOrTokenA.IsToken && nodeOrTokenB.IsToken)
     {
         return(IsTokenwiseEquivalent(nodeOrTokenA.AsToken(), nodeOrTokenB.AsToken()));
     }
     return(Result.NotEquivalent);
 }
示例#32
0
 private void ClassifyNodeOrToken(SyntaxNodeOrToken nodeOrToken)
 {
     var node = nodeOrToken.AsNode();
     if (node != null)
     {
         ClassifyNode(node);
     }
     else
     {
         ClassifyToken(nodeOrToken.AsToken());
     }
 }
示例#33
0
        public override Match Run(SyntaxNodeOrToken nodeOrToken)
        {
            if (nodeOrToken.Kind() != _syntaxKind)
                return Match.NoMatch;

            var result = Match.Success;

            if (nodeOrToken.IsNode)
            {
                var node = nodeOrToken.AsNode();
                var children = node.ChildNodesAndTokens();

                var matcherIndex = 0;
                var matchedEnd = 0;

                for (var i = 0; i < children.Count; i++)
                {
                    if (matcherIndex >= _childMatchers.Length)
                        return Match.NoMatch;

                    while (i < children.Count && children[i].Span.Start < matchedEnd)
                        i++;

                    if (i >= children.Count)
                        break;

                    var child = children[i];
                    var matcher = _childMatchers[matcherIndex];
                    var match = matcher.Run(child);
                    if (!match.IsMatch)
                        return Match.NoMatch;

                    // Depending on much was captured, we need to skip some matchers.

                    if (match.Captures.Any())
                        matchedEnd = match.Captures.Max(c => c.EndNodeOrToken.Span.End);

                    result = result.AddCaptures(match.Captures);
                    matcherIndex++;
                }

                var allMatchersUsed = matcherIndex >= _childMatchers.Length;
                if (!allMatchersUsed)
                    return Match.NoMatch;
            }

            return result;
        }
示例#34
0
        public static void CheckParents(SyntaxNodeOrToken nodeOrToken, SyntaxTree expectedSyntaxTree)
        {
            Assert.Equal(expectedSyntaxTree, nodeOrToken.SyntaxTree);

            var span = nodeOrToken.Span;

            if (nodeOrToken.IsToken)
            {
                var token = nodeOrToken.AsToken();
                foreach (var trivia in token.LeadingTrivia)
                {
                    var tspan = trivia.Span;
                    var parentToken = trivia.Token;
                    Assert.Equal(parentToken, token);
                    if (trivia.HasStructure)
                    {
                        var parentTrivia = trivia.GetStructure().Parent;
                        Assert.Null(parentTrivia);
                        CheckParents((CSharpSyntaxNode)trivia.GetStructure(), expectedSyntaxTree);
                    }
                }

                foreach (var trivia in token.TrailingTrivia)
                {
                    var tspan = trivia.Span;
                    var parentToken = trivia.Token;
                    Assert.Equal(parentToken, token);
                    if (trivia.HasStructure)
                    {
                        var parentTrivia = trivia.GetStructure().Parent;
                        Assert.Null(parentTrivia);
                        CheckParents(trivia.GetStructure(), expectedSyntaxTree);
                    }
                }
            }
            else
            {
                var node = nodeOrToken.AsNode();
                foreach (var child in node.ChildNodesAndTokens())
                {
                    var parent = child.Parent;
                    Assert.Equal(node, parent);
                    CheckParents(child, expectedSyntaxTree);
                }
            }
        }
        private static SyntaxNodeOrToken GetNewSyntaxListItem(SyntaxNodeOrToken item)
        {
            if (!item.IsNode)
            {
                return item;
            }

            var member = (AnonymousObjectMemberDeclaratorSyntax)item.AsNode();
            var identifier = member.Expression as IdentifierNameSyntax;
            if (identifier != null &&
                identifier.Identifier.ValueText == member.NameEquals.Name.Identifier.ValueText)
            {
                return SyntaxFactory.AnonymousObjectMemberDeclarator(member.Expression).WithTriviaFrom(member);
            }

            return item;
        }
示例#36
0
        public override Match Run(SyntaxNodeOrToken nodeOrToken)
        {
            if (nodeOrToken.Kind() != SyntaxKind.ArgumentList)
                return Match.NoMatch;

            var argumentList = (ArgumentListSyntax) nodeOrToken.AsNode();
            if (_variable.MinOccurrences > argumentList.Arguments.Count)
                return Match.NoMatch;

            if (_variable.MaxOccurrences != null && _variable.MaxOccurrences < argumentList.Arguments.Count)
                return Match.NoMatch;

            if (argumentList.Arguments.Count == 0)
                return Match.Success;

            var first = argumentList.Arguments.First();
            var last = argumentList.Arguments.Last();
            return Match.Success.AddCapture(_variable, first, last);
        }
 private void ClassifyNodeOrToken(SyntaxNodeOrToken nodeOrToken)
 {
     var node = nodeOrToken.AsNode();
     if (node != null)
     {
         ClassifyNode(node);
     }
     else
     {
         ClassifyToken(nodeOrToken.AsToken());
     }
 }
示例#38
0
 public bool TryGetVariable(SyntaxNodeOrToken nodeOrToken, out PatternVariable variable)
 {
     return nodeOrToken.IsToken
         ? TryGetVariable(nodeOrToken.AsToken(), out variable)
         : TryGetVariable(nodeOrToken.AsNode(), out variable);
 }
        private bool ValidateNodeOrToken(SyntaxNodeOrToken nodeOrtoken, SyntaxTree tree, string filename = "", List<Failure> failures = null)
        {
            var retVal = true;
            if (nodeOrtoken.IsNode)
            {
                retVal = ValidateNonTerminal(nodeOrtoken.AsNode(), tree, filename, failures);
            }
            else
            {
                retVal = ValidateToken(nodeOrtoken.AsToken(), tree, filename, failures);
            }

            return retVal;
        }
 private static int GetEndPosition(SyntaxNodeOrToken nodeOrToken)
 {
     if (nodeOrToken.IsToken)
     {
         return nodeOrToken.Span.End;
     }
     else
     {
         return nodeOrToken.AsNode().GetLastToken().Span.End;
     }
 }
 public SourceLocationWithAssociatedNode(SyntaxTree syntaxTree, SyntaxNodeOrToken nodeOrToken, bool associateInParent = false)
     : this(syntaxTree, nodeOrToken.Span, nodeOrToken.IsNode ? nodeOrToken.AsNode() : nodeOrToken.AsToken().Parent, associateInParent)
 {
 }
        private BoundStatement RewriteForStatement(
            CSharpSyntaxNode syntax,
            ImmutableArray<LocalSymbol> outerLocals,
            BoundStatement rewrittenInitializer,
            ImmutableArray<LocalSymbol> innerLocals,
            BoundExpression rewrittenCondition,
            SyntaxNodeOrToken conditionSyntax,
            BoundStatement rewrittenIncrement,
            BoundStatement rewrittenBody,
            GeneratedLabelSymbol breakLabel,
            GeneratedLabelSymbol continueLabel,
            bool hasErrors)
        {
            Debug.Assert(rewrittenBody != null);

            // The sequence point behavior exhibited here is different from that of the native compiler.  In the native
            // compiler, if you have something like 
            //
            // for(int i = 0, j = 0; ; i++, j++)
            //     ^--------------^    ^------^   
            //
            // then all the initializers are treated as a single sequence point, as are
            // all the loop incrementers.
            //
            // We now make each one individually a sequence point:
            //
            // for(int i = 0, j = 0; ; i++, j++)
            //     ^-------^  ^---^    ^-^  ^-^
            //
            // If we decide that we want to preserve the native compiler stepping behavior
            // then we'll need to be a bit fancy here. The initializer and increment statements
            // can contain lambdas whose bodies need to have sequence points inserted, so we
            // need to make sure we visit the children. But we'll also need to make sure that
            // we do not generate one sequence point for each statement in the initializers
            // and the incrementers.

            var statementBuilder = ArrayBuilder<BoundStatement>.GetInstance();
            if (rewrittenInitializer != null)
            {
                statementBuilder.Add(rewrittenInitializer);
            }

            var startLabel = new GeneratedLabelSymbol("start");

            if (!innerLocals.IsDefaultOrEmpty)
            {
                var walker = new AnyLocalCapturedInALambdaWalker(innerLocals);

                if (walker.Analyze(rewrittenCondition) || walker.Analyze(rewrittenIncrement) || walker.Analyze(rewrittenBody))
                {
                    // If any inner local is captured within a lambda, we need to enter scope-block
                    // always from the top, that is where an instance of a display class will be created.
                    // The IL will be less optimal, but this shouldn't be a problem, given presence of lambdas.

                    // for (initializer; condition; increment)
                    //   body;
                    //
                    // becomes the following (with
                    // block added for locals)
                    //
                    // {
                    //   initializer;
                    // start:
                    //   {
                    //     GotoIfFalse condition break;
                    //     body;
                    // continue:
                    //     increment;
                    //     goto start;
                    //   }
                    // break:
                    // }

                    // start:
                    statementBuilder.Add(new BoundLabelStatement(syntax, startLabel));

                    var blockBuilder = ArrayBuilder<BoundStatement>.GetInstance();

                    //   GotoIfFalse condition break;
                    if (rewrittenCondition != null)
                    {
                        BoundStatement ifNotConditionGotoBreak = new BoundConditionalGoto(rewrittenCondition.Syntax, rewrittenCondition, false, breakLabel);

                        if (this.generateDebugInfo)
                        {
                            if (conditionSyntax.IsToken)
                            {
                                ifNotConditionGotoBreak = new BoundSequencePointWithSpan(syntax, ifNotConditionGotoBreak, conditionSyntax.Span);
                            }
                            else
                            {
                                ifNotConditionGotoBreak = new BoundSequencePoint((CSharpSyntaxNode)conditionSyntax.AsNode(), ifNotConditionGotoBreak);
                            }
                        }

                        blockBuilder.Add(ifNotConditionGotoBreak);
                    }

                    // body;
                    blockBuilder.Add(rewrittenBody);

                    // continue:
                    //   increment;
                    blockBuilder.Add(new BoundLabelStatement(syntax, continueLabel));
                    if (rewrittenIncrement != null)
                    {
                        blockBuilder.Add(rewrittenIncrement);
                    }

                    //     goto start;
                    blockBuilder.Add(new BoundGotoStatement(syntax, startLabel));

                    statementBuilder.Add(new BoundBlock(syntax, innerLocals, blockBuilder.ToImmutableAndFree()));

                    // break:
                    statementBuilder.Add(new BoundLabelStatement(syntax, breakLabel));

                    return new BoundBlock(syntax, outerLocals, statementBuilder.ToImmutableAndFree(), hasErrors);
                }
            }

            var endLabel = new GeneratedLabelSymbol("end");

            // for (initializer; condition; increment)
            //   body;
            //
            // becomes the following (with
            // block added for locals)
            //
            // {
            //   initializer;
            //   goto end;
            // start:
            //   body;
            // continue:
            //   increment;
            // end:
            //   GotoIfTrue condition start;
            // break:
            // }

            //  initializer;
            //  goto end;

            //mark the initial jump as hidden.
            //We do it to tell that this is not a part of previous statement.
            //This jump may be a target of another jump (for example if loops are nested) and that will make 
            //impression of the previous statement being re-executed
            var gotoEnd = new BoundSequencePoint(null, new BoundGotoStatement(syntax, endLabel));
            statementBuilder.Add(gotoEnd);

            // start:
            //   body;
            statementBuilder.Add(new BoundLabelStatement(syntax, startLabel));

            ArrayBuilder<BoundStatement> saveBuilder = null;

            if (!innerLocals.IsDefaultOrEmpty)
            {
                saveBuilder = statementBuilder;
                statementBuilder = ArrayBuilder<BoundStatement>.GetInstance();
            }

            statementBuilder.Add(rewrittenBody);

            // continue:
            //   increment;
            statementBuilder.Add(new BoundLabelStatement(syntax, continueLabel));
            if (rewrittenIncrement != null)
            {
                statementBuilder.Add(rewrittenIncrement);
            }

            // end:
            //   GotoIfTrue condition start;
            statementBuilder.Add(new BoundLabelStatement(syntax, endLabel));
            BoundStatement branchBack = null;
            if (rewrittenCondition != null)
            {
                branchBack = new BoundConditionalGoto(rewrittenCondition.Syntax, rewrittenCondition, true, startLabel);
            }
            else
            {
                branchBack = new BoundGotoStatement(syntax, startLabel);
            }

            if (this.generateDebugInfo)
            {
                if (conditionSyntax.IsToken)
                {
                    branchBack = new BoundSequencePointWithSpan(syntax, branchBack, conditionSyntax.Span);
                }
                else
                {
                    //if there is no condition, make this a hidden point so that 
                    //it does not count as a part of previous statement
                    branchBack = new BoundSequencePoint((CSharpSyntaxNode)conditionSyntax.AsNode(), branchBack);
                }
            }

            statementBuilder.Add(branchBack);

            if (!innerLocals.IsDefaultOrEmpty)
            {
                var block = new BoundBlock(syntax, innerLocals, statementBuilder.ToImmutableAndFree());
                statementBuilder = saveBuilder;
                statementBuilder.Add(block);
            }

            // break:
            statementBuilder.Add(new BoundLabelStatement(syntax, breakLabel));

            var statements = statementBuilder.ToImmutableAndFree();
            return new BoundBlock(syntax, outerLocals, statements, hasErrors);
        }
            private SyntaxNodeOrToken VisitNodeOrToken(SyntaxNodeOrToken nodeOrToken)
            {
                if (nodeOrToken.IsNode)
                    return Visit(nodeOrToken.AsNode());

                return VisitToken(nodeOrToken.AsToken());
            }
        private BoundStatement RewriteForStatement(
            CSharpSyntaxNode syntax,
            ImmutableArray<LocalSymbol> locals,
            BoundStatement rewrittenInitializer,
            BoundExpression rewrittenCondition,
            SyntaxNodeOrToken conditionSyntax,
            BoundStatement rewrittenIncrement,
            BoundStatement rewrittenBody,
            GeneratedLabelSymbol breakLabel,
            GeneratedLabelSymbol continueLabel,
            bool hasErrors)
        {
            // The sequence point behavior exhibited here is different from that of the native compiler.  In the native
            // compiler, if you have something like 
            //
            // for(int i = 0, j = 0; ; i++, j++)
            //     ^--------------^    ^------^   
            //
            // then all the initializers are treated as a single sequence point, as are
            // all the loop incrementers.
            //
            // We now make each one individually a sequence point:
            //
            // for(int i = 0, j = 0; ; i++, j++)
            //     ^-------^  ^---^    ^-^  ^-^
            //
            // If we decide that we want to preserve the native compiler stepping behavior
            // then we'll need to be a bit fancy here. The initializer and increment statements
            // can contain lambdas whose bodies need to have sequence points inserted, so we
            // need to make sure we visit the children. But we'll also need to make sure that
            // we do not generate one sequence point for each statement in the initializers
            // and the incrementers.

            var startLabel = new GeneratedLabelSymbol("start");
            var endLabel = new GeneratedLabelSymbol("end");

            // for (initializer; condition; increment)
            //   body;
            //
            // becomes the following (with
            // block added for locals)
            //
            // {
            //   initializer;
            //   goto end;
            // start:
            //   body;
            // continue:
            //   increment;
            // end:
            //   GotoIfTrue condition start;
            // break:
            // }

            //  initializer;
            //  goto end;
            var statementBuilder = ArrayBuilder<BoundStatement>.GetInstance();
            if (rewrittenInitializer != null)
            {
                statementBuilder.Add(rewrittenInitializer);
            }

            //mark the initial jump as hidden.
            //We do it to tell that this is not a part of previous statement.
            //This jump may be a target of another jump (for example if loops are nested) and that will make 
            //impression of the previous statement being re-executed
            var gotoEnd = new BoundSequencePoint(null, new BoundGotoStatement(syntax, endLabel));
            statementBuilder.Add(gotoEnd);

            // start:
            //   body;
            statementBuilder.Add(new BoundLabelStatement(syntax, startLabel));
            Debug.Assert(rewrittenBody != null);
            statementBuilder.Add(rewrittenBody);

            // continue:
            //   increment;
            statementBuilder.Add(new BoundLabelStatement(syntax, continueLabel));
            if (rewrittenIncrement != null)
            {
                statementBuilder.Add(rewrittenIncrement);
            }

            // end:
            //   GotoIfTrue condition start;
            statementBuilder.Add(new BoundLabelStatement(syntax, endLabel));
            BoundStatement branchBack = null;
            if (rewrittenCondition != null)
            {
                branchBack = new BoundConditionalGoto(rewrittenCondition.Syntax, rewrittenCondition, true, startLabel);
            }
            else
            {
                branchBack = new BoundGotoStatement(syntax, startLabel);
            }

            if (this.generateDebugInfo)
            {
                if (conditionSyntax.IsToken)
                {
                    branchBack = new BoundSequencePointWithSpan(syntax, branchBack, conditionSyntax.Span);
                }
                else
                {
                    //if there is no condition, make this a hidden point so that 
                    //it does not count as a part of previous statement
                    branchBack = new BoundSequencePoint((CSharpSyntaxNode)conditionSyntax.AsNode(), branchBack);
                }
            }

            statementBuilder.Add(branchBack);


            // break:
            statementBuilder.Add(new BoundLabelStatement(syntax, breakLabel));

            var statements = statementBuilder.ToImmutableAndFree();
            return new BoundBlock(syntax, locals, statements, hasErrors);
        }
        // Helpers for populating the treeview.

        private void AddNodeOrToken(TreeViewItem parentItem, SyntaxNodeOrToken nodeOrToken)
        {
            if (nodeOrToken.IsNode)
            {
                AddNode(parentItem, nodeOrToken.AsNode());
            }
            else
            {
                AddToken(parentItem, nodeOrToken.AsToken());
            }
        }
 protected override SyntaxNode GetInnermostNamespaceScope(SyntaxNodeOrToken nodeOrToken)
 {
     var node = nodeOrToken.IsNode ? nodeOrToken.AsNode() : nodeOrToken.Parent;
     return node.GetAncestorOrThis<NamespaceDeclarationSyntax>() ?? (SyntaxNode)node.GetAncestorOrThis<CompilationUnitSyntax>();
 }
示例#47
0
        private BoundStatement RewriteForStatement(
            SyntaxNode syntax,
            ReadOnlyArray<LocalSymbol> locals,
            BoundStatement rewrittenInitializer,
            BoundExpression rewrittenCondition,
            SyntaxNodeOrToken conditionSyntax,
            BoundStatement rewrittenIncrement,
            BoundStatement rewrittenBody,
            GeneratedLabelSymbol breakLabel,
            GeneratedLabelSymbol continueLabel,
            bool hasErrors)
        {
            var startLabel = new GeneratedLabelSymbol("start");
            var endLabel = new GeneratedLabelSymbol("end");

            // for (initializer; condition; increment)
            //   body;
            //
            // becomes the following (with
            // block added for locals)
            //
            // {
            //   initializer;
            //   goto end;
            // start:
            //   body;
            // continue:
            //   increment;
            // end:
            //   GotoIfTrue condition start;
            // break:
            // }

            //  initializer;
            //  goto end;
            var statementBuilder = ArrayBuilder<BoundStatement>.GetInstance();
            if (rewrittenInitializer != null)
            {
                statementBuilder.Add(rewrittenInitializer);
            }

            //mark the initial jump as hidden.
            //We do it to tell that this is not a part of previous statement.
            //This jump may be a target of another jump (for example if loops are nested) and that will make 
            //impression of the previous statement being re-executed
            var gotoEnd = new BoundSequencePoint(null, new BoundGotoStatement(syntax, endLabel));
            statementBuilder.Add(gotoEnd);

            // start:
            //   body;
            statementBuilder.Add(new BoundLabelStatement(syntax, startLabel));
            Debug.Assert(rewrittenBody != null);
            statementBuilder.Add(rewrittenBody);

            // continue:
            //   increment;
            statementBuilder.Add(new BoundLabelStatement(syntax, continueLabel));
            if (rewrittenIncrement != null)
            {
                statementBuilder.Add(rewrittenIncrement);
            }

            // end:
            //   GotoIfTrue condition start;
            statementBuilder.Add(new BoundLabelStatement(syntax, endLabel));
            BoundStatement branchBack = null;
            if (rewrittenCondition != null)
            {
                branchBack = new BoundConditionalGoto(rewrittenCondition.Syntax, rewrittenCondition, true, startLabel);
            }
            else
            {
                branchBack = new BoundGotoStatement(syntax, startLabel);
            }

            if (this.generateDebugInfo)
            {
                if (conditionSyntax.IsToken)
                {
                    branchBack = new BoundSequencePointWithSpan(syntax, branchBack, conditionSyntax.Span);
                }
                else
                {
                    //if there is no condition, make this a hidden point so that 
                    //it does not count as a part of previous statement
                    branchBack = new BoundSequencePoint(conditionSyntax.AsNode(), branchBack);
                }
            }

            statementBuilder.Add(branchBack);


            // break:
            statementBuilder.Add(new BoundLabelStatement(syntax, breakLabel));

            var statements = statementBuilder.ToReadOnlyAndFree();
            return new BoundBlock(syntax, locals, statements, hasErrors);
        }
        private void VisitImpl(SyntaxNodeOrToken nodeOrToken)
        {
            greatestChildPosition.Add(nodeOrToken, 0);

            SyntaxNode node = nodeOrToken.AsNode();

            IList<string> identity;
            if (node is CompilationUnitSyntax)
            {
                identity = new List<string>();
                identity.Add("CompilationUnit");
                identities.Add(nodeOrToken, identity);
            }
            else
            {
                identity = identities[nodeOrToken.Parent].ToList();
            }

            string name = null;
            if (node is NamespaceDeclarationSyntax)
            {
                name = ((NamespaceDeclarationSyntax)node).Name.ToString();
            }
            else if (node is ClassDeclarationSyntax)
            {
                name = ((ClassDeclarationSyntax)node).Identifier.ValueText;
            }
            else if (node is VariableDeclaratorSyntax)
            {
                name = ((VariableDeclaratorSyntax)node).Identifier.ValueText;
            }
            else if (node is MethodDeclarationSyntax)
            {
                name = ((MethodDeclarationSyntax)node).Identifier.ValueText;
            }
            else if (node is PropertyDeclarationSyntax)
            {
                name = ((PropertyDeclarationSyntax)node).Identifier.ValueText;
            }
            else if (node is UsingDirectiveSyntax)
            {
                name = ((UsingDirectiveSyntax)node).Name.ToFullString().Replace(".", string.Empty) ;
            }
            else if (nodeOrToken.IsToken)
            {
                name = nodeOrToken.AsToken().ValueText;
            }

            if (!(node is CompilationUnitSyntax))
            {
                identity.Add(
                    string.Format("{0}{1}", name,
                    (++greatestChildPosition[nodeOrToken.Parent]).ToString()));
                identities.Add(nodeOrToken, identity);
            }
        }
示例#49
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);
            }