0

I have been working on some Roslyn code analyzer. My goal is to analyze exceptions and Catch blocks.

I got to a situation when I am able to analyze nodes and get NamedType of every Exception possibly thrown by the node. At the same time I am able to enumerate all Catch blocks related to such a node.

I need to resolve whether given NamedType is equal to Catch expression declaration or its base class.

Illustrative code:

var typeName = "System.ArgumentNullException";
NamedType exceptionType = _compilatorStartContext.Compilation.GetTypeByMetadataName(typeName);
// exceptionType = NamedType System.IO.IOException

var tryStatement = arg as TryStatementSyntax;
CatchDeclarationSyntax @catch = tryStatement.Catches.First();
var declaration = @catch.Declaration;
// declaration = CatchDeclarationSyntax CatchDeclaration (Exception)
// TODO: decide whether declaration can be instantiated from exceptionType
m0sa
  • 10,712
  • 4
  • 44
  • 91

1 Answers1

2

You need to use the semantic model for that.

After you get hold of it you can do this:

// var declaredType = analysisContext.SemanticModel.GetDeclaredSymbol(@catch.Declaration).Type;
// ^^ only works on catch(FooException x), doesn't work on catch (FooException) 
var declaredType = analysisContext.SemanticModel.GetTypeInfo(@catch.Declaration.Type);
var implements = false;
for (var i = declaredType.Type; i != null; i = i.BaseType)
{
    if (i == exceptionType)
    {
        implements = true;
        break;
    }
}
// implements holds the result
m0sa
  • 10,712
  • 4
  • 44
  • 91
  • I forgot to say I tried this approach. The issue here is that `analysisContext.SemanticModel.GetDeclaredSymbol(@catch.Declaration)` returns `null`. – Jiří Travěnec Aug 19 '16 at 11:35
  • @JiříTravěnec ah, I see, the issue is that `GetDeclaredSymbol` doesn't work with declarations without a variable identifier, e.g. `catch (InvalidOperationException) { ... }`, see updated answer – m0sa Aug 19 '16 at 11:47
  • This gives me `ArgumentException` with detail stating "Syntax node is not within syntax tree". – Jiří Travěnec Aug 19 '16 at 15:51
  • 1
    @JiříTravěnec then you don't have the right semantic model for the tryStatement. Can you update your question to show exactly how you get the tryStatement and the semantic model? Any way, if you're not rewriting any syntax trees, you should be able to get the right semantic model with `_compilatorStartContext.Compilation.GetSemanticModel(@catch.SyntaxTree).` – m0sa Aug 19 '16 at 16:36
  • I have combined everything you mentioned and it works. I will try to post final solution some time later. Thx. – Jiří Travěnec Aug 24 '16 at 22:02