From a00dfeb061784a06c2c955488a275ff6e0b1bcf0 Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Sat, 6 Jun 2015 16:49:42 +0200 Subject: [PATCH] 'decompile as project' improvements --- .../CSharp/CSharpDecompiler.cs | 40 ++++++++++++++----- ILSpy/Languages/CSharpLanguage.cs | 26 ++++++------ 2 files changed, 41 insertions(+), 25 deletions(-) diff --git a/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs b/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs index ca70dfe35..9e2b6c5da 100644 --- a/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs +++ b/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs @@ -116,17 +116,33 @@ namespace ICSharpCode.Decompiler.CSharp rootNode.AcceptVisitor(new InsertParenthesesVisitor { InsertParenthesesForReadability = true }); } - public SyntaxTree DecompileWholeModuleAsSingleFile() + /// + /// Decompile assembly and module attributes. + /// + public SyntaxTree DecompileModuleAndAssemblyAttributes() { var decompilationContext = new SimpleTypeResolveContext(typeSystem.MainAssembly); SyntaxTree syntaxTree = new SyntaxTree(); - foreach (var a in typeSystem.Compilation.MainAssembly.AssemblyAttributes) - { + DoDecompileModuleAndAssemblyAttributes(decompilationContext, syntaxTree); + RunTransforms(syntaxTree, decompilationContext); + return syntaxTree; + } + + void DoDecompileModuleAndAssemblyAttributes(ITypeResolveContext decompilationContext, SyntaxTree syntaxTree) + { + foreach (var a in typeSystem.Compilation.MainAssembly.AssemblyAttributes) { var astBuilder = CreateAstBuilder(decompilationContext); var attrSection = new AttributeSection(astBuilder.ConvertAttribute(a)); attrSection.AttributeTarget = "assembly"; syntaxTree.AddChild(attrSection, SyntaxTree.MemberRole); } + } + + public SyntaxTree DecompileWholeModuleAsSingleFile() + { + var decompilationContext = new SimpleTypeResolveContext(typeSystem.MainAssembly); + SyntaxTree syntaxTree = new SyntaxTree(); + DoDecompileModuleAndAssemblyAttributes(decompilationContext, syntaxTree); string currentNamespace = null; AstNode groupNode = null; foreach (var cecilType in typeSystem.ModuleDefinition.Types) { @@ -150,7 +166,7 @@ namespace ICSharpCode.Decompiler.CSharp return syntaxTree; } - public EntityDeclaration Decompile(TypeDefinition typeDefinition) + public SyntaxTree Decompile(TypeDefinition typeDefinition) { if (typeDefinition == null) throw new ArgumentNullException("typeDefinition"); @@ -158,9 +174,10 @@ namespace ICSharpCode.Decompiler.CSharp if (typeDef == null) throw new InvalidOperationException("Could not find type definition in NR type system"); var decompilationContext = new SimpleTypeResolveContext(typeDef); - var decl = DoDecompile(typeDef, decompilationContext); - RunTransforms(decl, decompilationContext); - return decl; + var syntaxTree = new SyntaxTree(); + syntaxTree.Members.Add(DoDecompile(typeDef, decompilationContext)); + RunTransforms(syntaxTree, decompilationContext); + return syntaxTree; } EntityDeclaration DoDecompile(ITypeDefinition typeDef, ITypeResolveContext decompilationContext) @@ -221,7 +238,7 @@ namespace ICSharpCode.Decompiler.CSharp return typeDecl; } - public EntityDeclaration Decompile(MethodDefinition methodDefinition) + public SyntaxTree Decompile(MethodDefinition methodDefinition) { if (methodDefinition == null) throw new ArgumentNullException("methodDefinition"); @@ -229,9 +246,10 @@ namespace ICSharpCode.Decompiler.CSharp if (method == null) throw new InvalidOperationException("Could not find method in NR type system"); var decompilationContext = new SimpleTypeResolveContext(method); - var decl = DoDecompile(methodDefinition, method, decompilationContext); - RunTransforms(decl, decompilationContext); - return decl; + var syntaxTree = new SyntaxTree(); + syntaxTree.Members.Add(DoDecompile(methodDefinition, method, decompilationContext)); + RunTransforms(syntaxTree, decompilationContext); + return syntaxTree; } EntityDeclaration DoDecompile(MethodDefinition methodDefinition, IMethod method, ITypeResolveContext decompilationContext) diff --git a/ILSpy/Languages/CSharpLanguage.cs b/ILSpy/Languages/CSharpLanguage.cs index 4b183bcf1..18db14b9e 100644 --- a/ILSpy/Languages/CSharpLanguage.cs +++ b/ILSpy/Languages/CSharpLanguage.cs @@ -330,11 +330,10 @@ namespace ICSharpCode.ILSpy if (options.FullDecompilation) { SyntaxTree st = decompiler.DecompileWholeModuleAsSingleFile(); output.WriteLine(st.ToString()); + } else { + SyntaxTree st = decompiler.DecompileModuleAndAssemblyAttributes(); + output.WriteLine(st.ToString()); } -// AstBuilder codeDomBuilder = CreateAstBuilder(options, currentModule: assembly.ModuleDefinition); -// codeDomBuilder.AddAssembly(assembly.ModuleDefinition, onlyAssemblyLevel: !options.FullDecompilation); -// codeDomBuilder.RunTransformations(transformAbortCondition); -// codeDomBuilder.GenerateCode(output); } } } @@ -474,21 +473,21 @@ namespace ICSharpCode.ILSpy return true; } - IEnumerable> WriteAssemblyInfo(ModuleDefinition module, DecompilationOptions options, HashSet directories) + IEnumerable> WriteAssemblyInfo(DecompilerTypeSystem ts, DecompilationOptions options, HashSet directories) { // don't automatically load additional assemblies when an assembly node is selected in the tree view using (LoadedAssembly.DisableAssemblyLoad()) { -// AstBuilder codeDomBuilder = CreateAstBuilder(options, currentModule: module); -// codeDomBuilder.AddAssembly(module, onlyAssemblyLevel: true); -// codeDomBuilder.RunTransformations(transformAbortCondition); + CSharpDecompiler decompiler = new CSharpDecompiler(ts); + SyntaxTree syntaxTree = decompiler.DecompileModuleAndAssemblyAttributes(); string prop = "Properties"; if (directories.Add("Properties")) Directory.CreateDirectory(Path.Combine(options.SaveAsProjectDirectory, prop)); string assemblyInfo = Path.Combine(prop, "AssemblyInfo" + this.FileExtension); -// using (StreamWriter w = new StreamWriter(Path.Combine(options.SaveAsProjectDirectory, assemblyInfo))) -// codeDomBuilder.GenerateCode(new PlainTextOutput(w)); + using (StreamWriter w = new StreamWriter(Path.Combine(options.SaveAsProjectDirectory, assemblyInfo))) { + syntaxTree.AcceptVisitor(new CSharpOutputVisitor(w, options.DecompilerSettings.CSharpFormattingOptions)); + } return new Tuple[] { Tuple.Create("Compile", assemblyInfo) }; } } @@ -508,7 +507,6 @@ namespace ICSharpCode.ILSpy } }, StringComparer.OrdinalIgnoreCase).ToList(); DecompilerTypeSystem ts = new DecompilerTypeSystem(module); -// AstMethodBodyBuilder.ClearUnhandledOpcodes(); Parallel.ForEach( files, new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount }, @@ -516,12 +514,12 @@ namespace ICSharpCode.ILSpy using (StreamWriter w = new StreamWriter(Path.Combine(options.SaveAsProjectDirectory, file.Key))) { CSharpDecompiler decompiler = new CSharpDecompiler(ts); foreach (TypeDefinition type in file) { - w.WriteLine(decompiler.Decompile(type).ToString()); + var syntaxTree = decompiler.Decompile(type); + syntaxTree.AcceptVisitor(new CSharpOutputVisitor(w, options.DecompilerSettings.CSharpFormattingOptions)); } } }); -// AstMethodBodyBuilder.PrintNumberOfUnhandledOpcodes(); - return files.Select(f => Tuple.Create("Compile", f.Key)).Concat(WriteAssemblyInfo(module, options, directories)); + return files.Select(f => Tuple.Create("Compile", f.Key)).Concat(WriteAssemblyInfo(ts, options, directories)); } #endregion