Roslyn Analyzer : Analyzing Comments

One of the things one might encounter quite early while writing a Roslyn Code analyzer for comments is it is slightly different from detection of Syntax Nodes. In fact, it is not a node at all.

Syntax nodes represent syntactic constructs, for example declaration, statements, clauses and expressions. A Comment do not quite fall in the same category. It is rather a Syntax Trivia. Syntax Trivia are, as Microsoft states, largely non-significant components such as whitespaces, comments and preprocessor directives. Due to their rather insignificant presence, they are not included as child nodes of Syntax Tree. However, since they are still important in their own ways, they are still part of the Syntax Tree.

For the same reason, you would need to register a SyntaxTreeAction using RegisterSyntaxTreeAction rather SyntaxNodeAction using RegisterSyntaxNodeAction. For analyzing comments, our typical Initialize() method would like the following.

public override void Initialize(AnalysisContext context)
{
    context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.None);
    context.EnableConcurrentExecution();

    context.RegisterSyntaxTreeAction(AnalyzeComment);
}

The next step involves parsing the SingleLineCommentTrivia and MultiLineCommentTrivia trivias from the syntax tree. You could achieve this with a simple Linq Query.

private void AnalyzeComment(SyntaxTreeAnalysisContext context)
{
    SyntaxNode root = context.Tree.GetCompilationUnitRoot(context.CancellationToken);
    var commentTrivias = root.DescendantTrivia()
                            .Where(x => x.IsKind(SyntaxKind.SingleLineCommentTrivia) || x.IsKind(SyntaxKind.MultiLineCommentTrivia));

    // Rest of the code
}

That’s all you need. Didn’t that turn up quite easy. I wish there was a easy to parse the actual comment out of Trivia, however, unfortunately, I haven’t found one yet (not sure if one exist). At the moment, the most likely way to use the ToString() method. This would in fact, include comment characters as well, which you can parse out using Regex or simple string transformations.

Evil Code #009 : nameof Operator

The nameof() operator has been so commonly used by the developers that one could not be called guilty if he assumes it was there since C# was born. Despite that, there are days it might still surprise you.

What would be your reply if I asked you to predict the output of the following.

nameof(School.Division.Student)

No prizes for guessing. It wouldn’t be hard to guess that the output would be “Student”. So what is the surprise factor.

Let me add some more constraint to the code. What could be the output is the code was compiled on Visual Studio 2017, v15.5.x ? Would your answer change ?

If you were to say that you answer would still be the same, then here is the surprise for you. This is a bug on the C# compiler, which results in compiler error when you use nested properties /sub expression of the format X.Y.Z.

CS0120: An object reference is required for the non-static field, method, or property 'C.Instance'

This bug was fixed in 15.7.x, and anyone using a Visual Studio with version 15.7.x or above, would be able to see the desired result of “Student”.

If you are one of those lucky ones as yours truely, then you are in for an unusual compiler error. If you are interested to read more on the issue, please follow the issue on Github here.