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); }
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); }
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]); } }
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); }
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]); } }
private static bool IsNonZeroWidthOrIsEndOfFile(SyntaxNodeOrToken token) { return(token.CSharpKind() == SyntaxKind.EndOfFileToken || token.FullWidth != 0); }
private static void Print(SyntaxNodeOrToken node) { Debug.WriteLine("{0}(SyntaxKind.{1});", node.IsMissing ? "M" : "N", node.CSharpKind()); }
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; }