public override void VisitCompilationUnit(CompilationUnitSyntax compilationUnit) { foreach (var m in compilationUnit.ChildNodes()) { Cx.Try(m, null, () => ((CSharpSyntaxNode)m).Accept(this)); } ExtractGlobalStatements(compilationUnit); // Gather comments: foreach (var trivia in compilationUnit.DescendantTrivia(compilationUnit.Span, descendIntoTrivia: true)) { CommentPopulator.ExtractComment(Cx, trivia); } foreach (var trivia in compilationUnit.GetLeadingTrivia()) { CommentPopulator.ExtractComment(Cx, trivia); } foreach (var trivia in compilationUnit.GetTrailingTrivia()) { CommentPopulator.ExtractComment(Cx, trivia); } }
private static IEnumerable <Diagnostic> GetExpectedDiagnostics(CompilationUnitSyntax root) { var multilineComments = root .DescendantTrivia() .Where(c => c.Kind() == SyntaxKind.MultiLineCommentTrivia); var commentPairs = GroupCommentsIntoAdjacentPairs( multilineComments ); foreach (var comments in commentPairs) { var start = comments.Item1; var end = comments.Item2; var startContents = GetMultiLineCommentContents(start); var endContents = GetMultiLineCommentContents(end); var diagnosticExpectation = DiagnosticExpectation.Parse(startContents); // Every assertion's start comment must map to a diagnostic // defined in Common.Diagnostics DiagnosticDescriptor descriptor; if (!m_possibleDiagnostics.TryGetValue(diagnosticExpectation.Name, out descriptor)) { Assert.Fail($"Comment at {start.GetLocation()} doesn't map to a diagnostic defined in Common.Diagnostic"); } // Every assertion-comment pair starts with a comment // containing the name of a diagnostic and then an empty // (multiline) comment to mark the end of the diagnostic. // Note that this means that assertions cannot overlap. if (endContents != "") { Assert.Fail($"Expected empty comment at {end.GetLocation()} to end comment at {start.GetLocation()}, got {end}"); } // The diagnostic must be between the two delimiting comments, // with one leading and trailing space inside the delimiters. // i.e. /* Foo */ abcdef hijklmno pqr /**/ // ------------------- // ^ expected Foo diagnostic // // TODO: it would be nice to do fuzzier matching (e.g. ignore // leading and trailing whitespace inside delimiters.) var diagStart = start.GetLocation().SourceSpan.End + 1; var diagEnd = end.GetLocation().SourceSpan.Start - 1; Assert.Less(diagStart, diagEnd); var diagSpan = TextSpan.FromBounds(diagStart, diagEnd); yield return(Diagnostic.Create( descriptor: descriptor, location: Location.Create(root.SyntaxTree, diagSpan), messageArgs: diagnosticExpectation.Arguments.ToArray() )); } }
private static IEnumerable <SyntaxTrivia> GetCommentsWithCode(CompilationUnitSyntax root, CancellationToken cancellationToken) { var commentTrivias = root.DescendantTrivia() .Where(x => x.IsKind(SyntaxKind.MultiLineCommentTrivia) || x.IsKind(SyntaxKind.SingleLineCommentTrivia)) .ToArray(); var comments = commentTrivias .Select(GetCommentText) .ToList(); return(GetCommentsWithCodeIndexes(comments, cancellationToken) .Select(x => commentTrivias[x])); }
public override void VisitCompilationUnit(CompilationUnitSyntax compilationUnit) { foreach (var m in compilationUnit.ChildNodes()) { cx.Try(m, null, () => ((CSharpSyntaxNode)m).Accept(this)); } // Gather comments: foreach (SyntaxTrivia trivia in compilationUnit.DescendantTrivia(compilationUnit.Span)) { CommentLine.Extract(cx, trivia); } foreach (var trivia in compilationUnit.GetLeadingTrivia()) { CommentLine.Extract(cx, trivia); } foreach (var trivia in compilationUnit.GetTrailingTrivia()) { CommentLine.Extract(cx, trivia); } }