ICSharpCode Decompiler从TypeReferenceExpression到TypeDeclaration?

时间:2015-03-23 18:35:43

标签: .net decompiling icsharpcode ilspy

我正在使用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 ...

只要有TypeReferenceExpression之类的行,语法树就会包含Math.Abs() s。如何在同一语法树中存在引用类型的TypeDeclaration时检索它?

我得到的最接近的是TypeReferenceExpression.Type.ToTypeReference().Resolve(),但这对编排非常重,我已经(我猜)语法树中的所有信息。我还尝试使用命名空间标识符进行手动查找,但我想应该有更好的方法。

1 个答案:

答案 0 :(得分:3)

您可以使用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>());

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

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

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