Process encountered symbols while also having access to a SemanticModel in Roslyn

379 views Asked by At

in a Roslyn Analyzer project, I want to flag all symbols marked with a particular attribute. For example, if the symbol is a method, then I want this method (or rather, its definition, although this distinction is not so relevant because GetAttributes gives me what I need anyways) to be checked for this attribute anywhere it is invoked or even simply used without any direct invocation (such as in a method group). Likewise, I would want any references (variable declaration, cast, type parameter, return type, etc.) to a certain (named) type to be checked to see if the type is decorated with the corresponding attribute.

Now, I thought I could get away with simply registering a symbol action using RegisterSymbolAction on AnalysisContext, but the thing is that, while I have the ability to break on symbols directly (without doing any syntax manipulation), I do not have a SemanticModel to interpret the symbols I find, as it is not on the SymbolAnalysisContext type. This means that I cannot even check if the attribute is of the right type, let alone do any other related comparative operation.

Now, from what I have gathered from the source code, the semantic model is not guaranteed to be valid when a call to the handler method that is provided to RegisterSymbolAction is invoked for a particular symbol (since it might not even have finished building yet). That being said, is there a way to actually be provided with a symbol (or at least a collection of encountered symbols) and a corresponding valid semantic model at the same time ? What I am trying to avoid, if I can, is to be forced to go through a whole syntax tree (most probably obtained from a SemanticModelAnalysisContext) and to interpret each and every node to its potential symbol equivalent.

I am not saying that it is not a valid solution, I am just looking for a potential alternative that I do not know about. I was maybe thinking of something along the lines of CompilationAnalysisContext or CodeBlockAnalysisContext, but so far, I've had no luck.

1

There are 1 answers

3
JoshVarty On BEST ANSWER

If I understand correctly, you're trying to get access to a SemanticModel from SymbolAnalysisContext?

On the Compilation property you can use GetSemanticModel() and pass in the syntax tree of the symbol you're looking at.

private static void AnalyzeSymbol(SymbolAnalysisContext context)
{
    var compilation = context.Compilation;
    var syntax = context.Symbol.DeclaringSyntaxReferences.First(); //Careful, partial methods might burn you
    var model = compilation.GetSemanticModel(syntax.SyntaxTree);
    //Use your model however you please!
}