2016-03-21 3 views
0

Apparemment, ICSharpCode Decompiler ne décompose pas les classes internes qui ont été créées par le compilateur C# pour une expression lambda. Considérons l'exemple suivant:Les classes imbriquées de l'expression Lambda manquant dans l'arborescence de syntaxe avec ICSharpCode Decompiler

Dans certains cas, une expression lambda dans C# sera compilée dans une classe interne avec une méthode contenant le corps de lambda. Par exemple. un code C# comme ceci:

class MyClass 
{ 
    public void MyMethod() 
    { 
     Parallel.For(0, 10, i => 
     { 
      ... = 3 * i; 
     }) 
    } 
} 

se traduira par le compilateur d'ajouter une classe interne comme ci-dessous:

class MyClass 
{ 
    public void MyMethod() 
    ... 

    public class c__DisplayClass2() 
    { 
     public int i; 

     public void b__0() 
     { 
      ... = 3 * i; 
     } 
    } 
} 

(peut-être pas exactement comme ça, mais vous voyez l'idée.)

maintenant le problème est que lorsque j'essaie de construire un AST par programmation à partir de l'assemblage de MyClass en utilisant ICSharpCode.Decompiler.Ast.AstBuilder ces classes internes ne sont pas incluses dans l'AST (tout le reste est bien). Je peux même voir ces classes générées parmi les annotations MyClassTypeDecleration: l'annotation avec le type Mono.Cecil.TypeDefinition liste correctement ces classes internes dans sa propriété NestedTypes (elles ont donc été correctement chargées à partir de l'assembly mais pas ajoutées à l'arbre de syntaxe; , les classes internes créées manuellement sont correctement décompilées).

Voir aussi cette question ILSpy j'ai ouvert: https://github.com/icsharpcode/ILSpy/issues/686

Suis-je manque quelque chose évidente ici? J'ai aussi regardé l'assemblage de ILSpy en utilisant l'interface graphique et là le code en question est correctement décompilé (mais pas avec une classe interne mais plutôt le lambda est reconstruit).

Répondre

0

J'ai découvert le problème: vous devez exécuter astBuilder.RunTransformations(); avant de travailler avec l'arbre de syntaxe, qui va également recréer des délégués.

Avant que je l'ai fait:

var assembly = AssemblyDefinition.ReadAssembly(typeof(Program).Assembly.Location); 
var decompilerContext = new DecompilerContext(assembly.MainModule); 
var astBuilder = new AstBuilder(decompilerContext); 
astBuilder.AddAssembly(assembly); 

var syntaxTree = astBuilder.SyntaxTree; 

Cependant, pour l'arbre de syntaxe pour être correctement initialisé vous en avez besoin:

var assembly = AssemblyDefinition.ReadAssembly(typeof(Program).Assembly.Location); 
var decompilerContext = new DecompilerContext(assembly.MainModule); 
var astBuilder = new AstBuilder(decompilerContext); 
astBuilder.AddAssembly(assembly); 
astBuilder.RunTransformations(); // This is new. 

var syntaxTree = astBuilder.SyntaxTree;