public static async Task<string> GetSourceCode(MethodDefinition methodDefinition, ILWeaver weaver = null) { return await Task.Run(() => { try { if (weaver != null) weaver.Apply(methodDefinition.Body); var settings = new DecompilerSettings { UsingDeclarations = false }; var context = new DecompilerContext(methodDefinition.Module) { CurrentType = methodDefinition.DeclaringType, Settings = settings }; var astBuilder = new AstBuilder(context); astBuilder.AddMethod(methodDefinition); var textOutput = new PlainTextOutput(); astBuilder.GenerateCode(textOutput); return textOutput.ToString(); } catch (Exception ex) { return "Error in creating source code from IL: " + ex.Message + Environment.NewLine + ex.StackTrace; } finally { if (weaver != null) methodDefinition.Body = null; } }); }
AstBuilder CreateBuilder(IDnlibDef item, CancellationToken token) { ModuleDef moduleDef; DecompilerContext ctx; AstBuilder builder; if (item is ModuleDef) { var def = (ModuleDef)item; moduleDef = def; builder = new AstBuilder(ctx = new DecompilerContext(moduleDef) { CancellationToken = token }); builder.AddAssembly(def, true); } else if (item is TypeDef) { var def = (TypeDef)item; moduleDef = def.Module; builder = new AstBuilder(ctx = new DecompilerContext(moduleDef) { CancellationToken = token }); builder.DecompileMethodBodies = false; ctx.CurrentType = def; builder.AddType(def); } else if (item is MethodDef) { var def = (MethodDef)item; moduleDef = def.Module; builder = new AstBuilder(ctx = new DecompilerContext(moduleDef) { CancellationToken = token }); ctx.CurrentType = def.DeclaringType; builder.AddMethod(def); } else if (item is FieldDef) { var def = (FieldDef)item; moduleDef = def.Module; builder = new AstBuilder(ctx = new DecompilerContext(moduleDef) { CancellationToken = token }); ctx.CurrentType = def.DeclaringType; builder.AddField(def); } else if (item is PropertyDef) { var def = (PropertyDef)item; moduleDef = def.Module; builder = new AstBuilder(ctx = new DecompilerContext(moduleDef) { CancellationToken = token }); ctx.CurrentType = def.DeclaringType; builder.AddProperty(def); } else if (item is EventDef) { var def = (EventDef)item; moduleDef = def.Module; builder = new AstBuilder(ctx = new DecompilerContext(moduleDef) { CancellationToken = token }); ctx.CurrentType = def.DeclaringType; builder.AddEvent(def); } else return null; ctx.Settings = new DecompilerSettings { UsingDeclarations = false }; return builder; }
void AddFieldsAndCtors(AstBuilder codeDomBuilder, TypeDefinition declaringType, bool isStatic) { foreach (var field in declaringType.Fields) { if (field.IsStatic == isStatic) codeDomBuilder.AddField(field); } foreach (var ctor in declaringType.Methods) { if (ctor.IsConstructor && ctor.IsStatic == isStatic) codeDomBuilder.AddMethod(ctor); } }
public static string ToSource(MethodDefinition methodDefinition) { var settings = new DecompilerSettings { UsingDeclarations = false }; var context = new DecompilerContext(methodDefinition.Module) { CurrentType = methodDefinition.DeclaringType, Settings = settings, }; var astBuilder = new AstBuilder(context); astBuilder.AddMethod(methodDefinition); var textOutput = new PlainTextOutput(); astBuilder.GenerateCode(textOutput); return textOutput.ToString(); }
/// <summary> /// Returns the code for a specific algorithm. /// </summary> /// <returns>The algorithm code.</returns> /// <param name="algorithmType">Algorithm type.</param> public static MethodDeclaration GetMethodCode(Type algorithmType, out AstBuilder astBuilder, string methodName) { var resolver = new DefaultAssemblyResolver(); resolver.AddSearchDirectory(new FileInfo(Assembly.GetExecutingAssembly().Location).Directory.FullName); var parameters = new ReaderParameters { AssemblyResolver = resolver, }; // Load Tychaia.ProceduralGeneration into Mono.Cecil. var module = AssemblyDefinition.ReadAssembly( Assembly.GetExecutingAssembly().Location, parameters).MainModule; // Now we have a reference to the method we want to decompile. TypeDefinition cecilType; MethodDefinition processCell; FindMethodName(module, algorithmType, methodName, out processCell, out cecilType); var decompilerSettings = new DecompilerSettings(); astBuilder = new AstBuilder(new DecompilerContext(module) { CurrentType = cecilType, Settings = decompilerSettings }); astBuilder.AddMethod(processCell); try { astBuilder.RunTransformations(); } catch (AssemblyResolutionException ex) { throw new Exception( "Unable to decompile algorithm source code for " + algorithmType.FullName + ".", ex); } astBuilder.CompilationUnit.AcceptVisitor(new InsertParenthesesVisitor { InsertParenthesesForReadability = true }); // Return. return astBuilder.CompilationUnit.Members.Where(v => v is MethodDeclaration).Cast<MethodDeclaration>().First(); }
// There are several methods available to override; in this sample, we deal with methods only public override void DecompileMethod(MethodDefinition method, ITextOutput output, DecompilationOptions options) { if (method.Body != null) { output.WriteLine("Size of method: {0} bytes", method.Body.CodeSize); ISmartTextOutput smartOutput = output as ISmartTextOutput; if (smartOutput != null) { // when writing to the text view (but not when writing to a file), we can even add UI elements such as buttons: smartOutput.AddButton(null, "Click me!", (sender, e) => (sender as Button).Content = "I was clicked!"); smartOutput.WriteLine(); } // ICSharpCode.Decompiler.Ast.AstBuilder can be used to decompile to C# AstBuilder b = new AstBuilder(new DecompilerContext(method.Module) { Settings = options.DecompilerSettings, CurrentType = method.DeclaringType }); b.AddMethod(method); b.RunTransformations(); output.WriteLine("Decompiled AST has {0} nodes", b.CompilationUnit.DescendantsAndSelf.Count()); } }
private static string Decompile(string name, MethodDefinition mtd) { var decompilerSettings = new ICSharpCode.Decompiler.DecompilerSettings { ShowXmlDocumentation = false, UsingDeclarations = false, }; var output = new ICSharpCode.Decompiler.PlainTextOutput(); var method = mtd; var astBuilder = new AstBuilder(new DecompilerContext(method.DeclaringType.Module) { CancellationToken = new CancellationToken(), CurrentType = method.DeclaringType, Settings = decompilerSettings, }); astBuilder.AddMethod(method); astBuilder.GenerateCode(output); var methodCode = output.ToString(); // remove top comment line //if (methodCode.StartsWith("//")) { // methodCode = methodCode.Substring(methodCode.IndexOf('\n') + 1); //} var attrRE = new Regex(@"^(?:\[[^]]+]\s*){1,}"); methodCode = attrRE.Replace(methodCode, "", 1); // change the method name to the mod's name for the method, and replace parameter names with game names var methodName = mtd.Name; var nameLocation = methodCode.IndexOf(" " + methodName) + 1; var nameEnd = nameLocation + methodName.Length; // Prepend "void " if this was a constructor (since methodCode won't have a return type) var correctName = mtd.IsConstructor ? ("void " + name) : name; methodCode = methodCode.Substring(0, nameLocation) + correctName + methodCode.Substring(nameEnd); return methodCode; }
CodeGeneratorMemberResult GenerateCode (IMethod method, CodeGenerationOptions options) { int bodyStartOffset = -1, bodyEndOffset = -1; StringBuilder result = new StringBuilder (); AppendObsoleteAttribute (result, options, method); AppendModifiers (result, options, method); if (method.IsPartial) result.Append ("partial "); AppendReturnType (result, options, method.ReturnType); result.Append (" "); if (options.ExplicitDeclaration) { AppendReturnType (result, options, method.DeclaringType); result.Append ("."); } result.Append (CSharpAmbience.FilterName (method.Name)); if (method.TypeParameters.Count > 0) { result.Append ("<"); for (int i = 0; i < method.TypeParameters.Count; i++) { if (i > 0) result.Append (", "); var p = method.TypeParameters [i]; result.Append (CSharpAmbience.FilterName (p.Name)); } result.Append (">"); } if (Policy.BeforeMethodDeclarationParentheses) result.Append (" "); result.Append ("("); AppendParameterList (result, options, method.Parameters); result.Append (")"); var typeParameters = method.TypeParameters; // This should also check the types are in the correct mscorlib Func<IType, bool> validBaseType = t => t.FullName != "System.Object" && t.FullName != "System.ValueType"; bool isFromInterface = method.DeclaringType != null && method.DeclaringTypeDefinition.Kind == TypeKind.Interface; if (!options.ExplicitDeclaration && isFromInterface && typeParameters.Any (p => p.HasDefaultConstructorConstraint || p.HasReferenceTypeConstraint || p.HasValueTypeConstraint || p.DirectBaseTypes.Any (validBaseType))) { result.Append (" where "); int typeParameterCount = 0; foreach (var p in typeParameters) { if (typeParameterCount != 0) result.Append (", "); typeParameterCount++; result.Append (CSharpAmbience.FilterName (p.Name)); result.Append (" : "); int constraintCount = 0; if (p.HasDefaultConstructorConstraint) { result.Append ("new ()"); constraintCount++; } if (p.HasValueTypeConstraint) { if (constraintCount != 0) result.Append (", "); result.Append ("struct"); constraintCount++; } if (p.HasReferenceTypeConstraint) { if (constraintCount != 0) result.Append (", "); result.Append ("class"); constraintCount++; } // bool hadInterfaces = false; foreach (var c in p.DirectBaseTypes.Where (validBaseType)) { if (constraintCount != 0) result.Append (", "); constraintCount++; AppendReturnType (result, options, c); // if (c.Kind == TypeKind.Interface) // hadInterfaces = true; } } } if (options.ImplementingType.Kind == TypeKind.Interface) { result.Append (";"); } else { AppendBraceStart (result, Policy.MethodBraceStyle); if (method.Name == "ToString" && (method.Parameters == null || method.Parameters.Count == 0) && method.ReturnType != null/* && method.ReturnType.FullName == "System.String"*/) { AppendIndent (result); bodyStartOffset = result.Length; result.Append ("return string.Format"); if (Policy.BeforeMethodDeclarationParentheses) result.Append (" "); result.Append ("(\"["); result.Append (options.ImplementingType.Name); if (options.ImplementingType.Properties.Any ()) result.Append (": "); int i = 0; foreach (IProperty property in options.ImplementingType.Properties) { if (property.IsStatic || !property.IsPublic) continue; if (i > 0) result.Append (", "); result.Append (property.Name); result.Append ("={"); result.Append (i++); result.Append ("}"); } result.Append ("]\""); foreach (IProperty property in options.ImplementingType.Properties) { if (property.IsStatic || !property.IsPublic) continue; result.Append (", "); result.Append (property.Name); } result.Append (");"); bodyEndOffset = result.Length; AppendLine (result); } else if (IsMonoTouchModelMember (method)) { AppendMonoTouchTodo (result, options, out bodyStartOffset, out bodyEndOffset); } else if (method.IsAbstract || !(method.IsVirtual || method.IsOverride) || method.DeclaringTypeDefinition.Kind == TypeKind.Interface) { AppendNotImplementedException (result, options, out bodyStartOffset, out bodyEndOffset); } else { bool skipBody = false; // Analyze if the body consists just of a single throw instruction // See: Bug 1373 - overriding [Model] class methods shouldn't insert base.Methods // TODO: Extend this to user defined code. try { if (method.Region.FileName == null) { var asm = AssemblyDefinition.ReadAssembly (method.ParentAssembly.UnresolvedAssembly.Location); foreach (var type in asm.MainModule.Types) { if (type.FullName != method.DeclaringType.FullName) continue; foreach (var m in type.Resolve ().Methods) { if (m.HasBody && m.Name == method.Name) { var context = new DecompilerContext (asm.MainModule); context.CurrentType = type; context.Settings = new DecompilerSettings () { AnonymousMethods = true, AutomaticEvents = true, AutomaticProperties = true, ForEachStatement = true, LockStatement = true }; var astBuilder = new AstBuilder (context); astBuilder.AddMethod (m); astBuilder.RunTransformations (o => false); var visitor = new ThrowsExceptionVisitor (); astBuilder.CompilationUnit.AcceptVisitor (visitor); skipBody = visitor.Throws; if (skipBody) break; } } if (skipBody) break; } } } catch (Exception) { } AppendIndent (result); bodyStartOffset = result.Length; if (!skipBody) { if (method.ReturnType.ReflectionName != typeof(void).FullName) result.Append ("return "); result.Append ("base."); result.Append (CSharpAmbience.FilterName (method.Name)); if (Policy.BeforeMethodCallParentheses) result.Append (" "); result.Append ("("); for (int i = 0; i < method.Parameters.Count; i++) { if (i > 0) result.Append (", "); var p = method.Parameters [i]; if (p.IsOut) result.Append ("out "); if (p.IsRef) result.Append ("ref "); result.Append (CSharpAmbience.FilterName (p.Name)); } result.Append (");"); } else { result.Append ("throw new System.NotImplementedException ();"); } bodyEndOffset = result.Length; AppendLine (result); } AppendBraceEnd (result, Policy.MethodBraceStyle); } return new CodeGeneratorMemberResult (result.ToString (), bodyStartOffset, bodyEndOffset); }
private void DecompileMethods(ClrMethod[] methods) { string moduleFileName = methods[0].Type.Module.FileName; string typeName = methods[0].Type.Name; var assemblyDef = AssemblyDefinition.ReadAssembly(moduleFileName); var typeDef = TypeDefFromAssemblyDef(typeName, assemblyDef); AstBuilder decompiler = new AstBuilder( new DecompilerContext(typeDef.Module) { CurrentType = typeDef }); foreach (var method in methods) { var methodDef = typeDef.Methods.Single( m => m.MetadataToken.ToUInt32() == method.MetadataToken); decompiler.AddMethod(methodDef); } GenerateCode(decompiler); }
public override string GetTooltip(MemberReference member) { MethodDefinition md = member as MethodDefinition; PropertyDefinition pd = member as PropertyDefinition; EventDefinition ed = member as EventDefinition; FieldDefinition fd = member as FieldDefinition; if (md != null || pd != null || ed != null || fd != null) { AstBuilder b = new AstBuilder(new DecompilerContext(member.Module) { Settings = new DecompilerSettings { UsingDeclarations = false } }); b.DecompileMethodBodies = false; if (md != null) b.AddMethod(md); else if (pd != null) b.AddProperty(pd); else if (ed != null) b.AddEvent(ed); else b.AddField(fd); b.RunTransformations(); foreach (var attribute in b.CompilationUnit.Descendants.OfType<AttributeSection>()) attribute.Remove(); StringWriter w = new StringWriter(); b.GenerateCode(new PlainTextOutput(w)); return Regex.Replace(w.ToString(), @"\s+", " ").TrimEnd(); } return base.GetTooltip(member); }
public ICSharpCode.AvalonEdit.Document.TextDocument Decompile(object obj) { AvalonEditTextOutput aeto = new AvalonEditTextOutput(); AstBuilder ast = new AstBuilder(new DecompilerContext(ModuleDefinition.CreateModule("ash", ModuleKind.NetModule))); switch (obj.GetType().Name) { case "AssemblyDefinition": ast = new AstBuilder(new DecompilerContext((obj as AssemblyDefinition).MainModule) { Settings = new DecompilerSettings() }); try { ast.AddAssembly(obj as AssemblyDefinition); } catch (AssemblyResolutionException e) { MessageBox.Show("Could not load assembly " + e.AssemblyReference.FullName); } break; case "TypeDefinition": ast = CreateAstBuilder((obj as TypeDefinition), true); try { ast.AddType(obj as TypeDefinition); } catch (AssemblyResolutionException e) { MessageBox.Show("Could not load assembly " + e.AssemblyReference.FullName); } break; case "MethodDefinition": MethodDefinition method = (obj as MethodDefinition); ast = CreateAstBuilder(method.DeclaringType, true); if (method.IsConstructor && !method.IsStatic && !method.DeclaringType.IsValueType) { foreach (var field in method.DeclaringType.Fields) if (field.IsStatic == method.IsStatic) { try { ast.AddField(field); } catch (AssemblyResolutionException e) { MessageBox.Show("Could not load assembly " + e.AssemblyReference.Name); } } foreach (var ctor in method.DeclaringType.Methods) if (ctor.IsConstructor && ctor.IsStatic == method.IsStatic) { try { ast.AddMethod(ctor); } catch (AssemblyResolutionException e) { MessageBox.Show("Could not load assembly " + e.AssemblyReference.Name); } } } else { try { ast.AddMethod(obj as MethodDefinition); } catch (AssemblyResolutionException e) { MessageBox.Show("Could not load assembly " + e.AssemblyReference.Name); } } break; case "PropertyDefinition": ast = CreateAstBuilder((obj as PropertyDefinition).DeclaringType, true); try { ast.AddProperty(obj as PropertyDefinition); } catch (AssemblyResolutionException e) { MessageBox.Show("Could not load assembly " + e.AssemblyReference.Name); } break; case "FieldDefinition": ast = CreateAstBuilder((obj as FieldDefinition).DeclaringType, true); try { ast.AddField(obj as FieldDefinition); } catch (AssemblyResolutionException e) { MessageBox.Show("Could not load assembly " + e.AssemblyReference.Name); } break; case "EventDefinition": ast = CreateAstBuilder((obj as EventDefinition).DeclaringType, true); try { ast.AddEvent(obj as EventDefinition); } catch (AssemblyResolutionException e) { MessageBox.Show("Could not load assembly " + e.AssemblyReference.Name); } break; default: return new ICSharpCode.AvalonEdit.Document.TextDocument(); } try { ast.GenerateCode(aeto); } catch (AssemblyResolutionException e) { MessageBox.Show("Could not load assembly upon code generation:\r" + e.AssemblyReference.FullName); } return aeto.GetDocument(); }