解析 Catch 表达式中声明的异常类型

Resolving type of exception declared in Catch expression

我一直在研究一些 Roslyn 代码分析器。我的目标是分析异常和 Catch 块。

我遇到了这样一种情况,我能够分析节点并获得节点可能抛出的每个 Exception 中的 NamedType。同时,我能够枚举与该节点相关的所有 Catch 个块。

我需要解决给定 NamedType 是否等于 Catch 表达式声明 或其基数 class.

说明代码:

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

为此您需要使用语义模型。

掌握后可以这样做:

// 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