ICSharpCode 反编译器从 TypeReferenceExpression 到 TypeDeclaration?

ICSharpCode Decompiler get from TypeReferenceExpression to TypeDeclaration?

我正在使用 ICSharpCode.Decompiler.Ast.AstBuilder(SharpDevelop、NRefactory 和 ILSpy 在后台使用它;也从那里获得了灵感)从代码中构建一个抽象语法树,来自 .NET 通用中间语言组装.

var assembly = AssemblyDefinition.ReadAssembly(assemblyPath);
var astBuilder = new AstBuilder(new DecompilerContext(assembly.MainModule));
astBuilder.AddAssembly(assembly);
// astBuilder.SyntaxTree ...

只要有像 Math.Abs() 这样的行,语法树就会包含 TypeReferenceExpressions。当引用类型也存在于同一语法树中时,如何检索引用类型的 TypeDeclaration

我得到的最接近的是 TypeReferenceExpression.Type.ToTypeReference().Resolve() 但这很难编排,而且我已经(我想)语法树中的所有信息。我也尝试使用名称空间和标识符进行手动查找,但我想应该有更好的方法。

您可以使用SyntaxTree.GetTypes()枚举所有反编译类型。因为这很重,我会建立一个参考声明查找,例如:

var assembly = AssemblyDefinition.ReadAssembly(assemblyPath);
var astBuilder = new AstBuilder(new DecompilerContext(assembly.MainModule));

astBuilder.AddAssembly(assembly);

var ast = astBuilder.SyntaxTree;

var lookup = ast.GetTypes(true)
                .ToDictionary(d => (TypeReference)d.Annotation<TypeDefinition>());

然后您可以从 TypeReferenceExpression 中获取 TypeReference 并使用它在查找中查找类型的声明:

TypeReferenceExpression e = /* ... */;
TypeDeclaration declaration;

if (lookup.TryGetValue(e.Type.Annotation<TypeReference>(), out declaration))
    Console.WriteLine(declaration.GetText());  // do whatever