/// <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(); }
public static ILSpyUnresolvedFile Create(DecompiledTypeReference name, AstBuilder builder) { var writer = new StringWriter(); var target = new TextWriterTokenWriter(writer) { IndentationString = "\t" }; var output = new DebugInfoTokenWriterDecorator(TokenWriter.WrapInWriterThatSetsLocationsInAST(target)); builder.RunTransformations(); var syntaxTree = builder.SyntaxTree; syntaxTree.AcceptVisitor(new InsertParenthesesVisitor { InsertParenthesesForReadability = true }); syntaxTree.AcceptVisitor(new CSharpOutputVisitor(output, FormattingOptionsFactory.CreateSharpDevelop())); ILSpyUnresolvedFile file = new ILSpyUnresolvedFile(name); var v = new TypeSystemConvertVisitor(file); syntaxTree.AcceptVisitor(v); file.MemberLocations = output.MemberLocations; file.DebugSymbols = output.DebugSymbols; file.output = writer.ToString(); return file; }
// 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()); } }
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); }
void RunTransformsAndGenerateCode(AstBuilder astBuilder, ITextOutput output, DecompilationOptions options, IAstTransform additionalTransform = null) { astBuilder.RunTransformations(transformAbortCondition); if (additionalTransform != null) { additionalTransform.Run(astBuilder.CompilationUnit); } if (options.DecompilerSettings.ShowXmlDocumentation) { AddXmlDocTransform.Run(astBuilder.CompilationUnit); } astBuilder.GenerateCode(output); }
void RunTransformsAndGenerateCode(AstBuilder astBuilder, ITextOutput output, DecompilationOptions options, IAstTransform additionalTransform = null) { astBuilder.RunTransformations(transformAbortCondition); if (additionalTransform != null) { additionalTransform.Run(astBuilder.SyntaxTree); } if (options.DecompilerSettings.ShowXmlDocumentation) { try { AddXmlDocTransform.Run(astBuilder.SyntaxTree); } catch (XmlException ex) { string[] msg = (" Exception while reading XmlDoc: " + ex.ToString()).Split(new[]{'\r', '\n'}, StringSplitOptions.RemoveEmptyEntries); var insertionPoint = astBuilder.SyntaxTree.FirstChild; for (int i = 0; i < msg.Length; i++) astBuilder.SyntaxTree.InsertChildBefore(insertionPoint, new Comment(msg[i], CommentType.Documentation), Roles.Comment); } } astBuilder.GenerateCode(output); }
void Run(Config config) { if (config.ShowHelp) { Console.WriteLine ("Netjs compiler, Copyright 2014 Frank A. Krueger"); Console.WriteLine ("netjs [options] assembly-file"); return; } if (string.IsNullOrEmpty (config.MainAssembly)) { throw new Exception ("No assembly specified."); } var asmPath = Path.GetFullPath (config.MainAssembly); asmDir = Path.GetDirectoryName (asmPath); var outPath = Path.ChangeExtension (asmPath, ".ts"); Step ("Reading IL"); var parameters = new ReaderParameters { AssemblyResolver = this, }; var asm = AssemblyDefinition.ReadAssembly (asmPath, parameters); mscorlib = AssemblyDefinition.ReadAssembly (typeof(String).Assembly.Location, parameters); system = AssemblyDefinition.ReadAssembly (typeof(INotifyPropertyChanged).Assembly.Location, parameters); systemCore = AssemblyDefinition.ReadAssembly (typeof(Enumerable).Assembly.Location, parameters); Step ("Decompiling IL to C#"); var context = new DecompilerContext (asm.MainModule); context.Settings.ForEachStatement = false; context.Settings.ObjectOrCollectionInitializers = false; context.Settings.UsingStatement = false; context.Settings.AsyncAwait = false; context.Settings.AutomaticProperties = true; context.Settings.AutomaticEvents = true; context.Settings.QueryExpressions = false; context.Settings.AlwaysGenerateExceptionVariableForCatchBlocks = true; context.Settings.UsingDeclarations = false; context.Settings.FullyQualifyAmbiguousTypeNames = true; context.Settings.YieldReturn = false; var builder = new AstBuilder (context); builder.AddAssembly (asm); foreach (var a in referencedAssemblies.Values) { if (a != null) builder.AddAssembly (a); } builder.RunTransformations (); Step ("Translating C# to TypeScript"); new CsToTs ().Run (builder.SyntaxTree); Step ("Writing"); using (var outputWriter = new StreamWriter (outPath)) { var output = new PlainTextOutput (outputWriter); builder.GenerateCode (output, (s, e) => new TsOutputVisitor (s, e)); } Step ("Done"); }
void RunTransformsAndGenerateCode(AstBuilder astBuilder, ITextOutput output, DecompilationOptions options, ModuleDefinition module) { astBuilder.RunTransformations(transformAbortCondition); if (options.DecompilerSettings.ShowXmlDocumentation) AddXmlDocTransform.Run(astBuilder.CompilationUnit); var unit = astBuilder.CompilationUnit.AcceptVisitor(new CSharpToVBConverterVisitor(new ILSpyEnvironmentProvider()), null); var outputFormatter = new VBTextOutputFormatter(output); var formattingPolicy = new VBFormattingOptions(); unit.AcceptVisitor(new OutputVisitor(outputFormatter, formattingPolicy), null); }
void RunTransformsAndGenerateCode(AstBuilder astBuilder, ITextOutput output, DecompilationContext ctx, IAstTransform additionalTransform = null) { astBuilder.RunTransformations(transformAbortCondition); if (additionalTransform != null) { additionalTransform.Run(astBuilder.SyntaxTree); } AddXmlDocumentation(langSettings.Settings, astBuilder); astBuilder.GenerateCode(output); }
void RunTransformsAndGenerateCode(AstBuilder astBuilder, ITextOutput output, DecompilationOptions options, ModuleDef module) { astBuilder.RunTransformations(transformAbortCondition); if (options.DecompilerSettings.ShowXmlDocumentation) { try { AddXmlDocTransform.Run(astBuilder.SyntaxTree); } catch (XmlException ex) { string[] msg = (" Exception while reading XmlDoc: " + ex.ToString()).Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); var insertionPoint = astBuilder.SyntaxTree.FirstChild; for (int i = 0; i < msg.Length; i++) astBuilder.SyntaxTree.InsertChildBefore(insertionPoint, new CSharp.Comment(msg[i], CSharp.CommentType.Documentation), CSharp.Roles.Comment); } } var csharpUnit = astBuilder.SyntaxTree; csharpUnit.AcceptVisitor(new NRefactory.CSharp.InsertParenthesesVisitor() { InsertParenthesesForReadability = true }); var unit = csharpUnit.AcceptVisitor(new CSharpToVBConverterVisitor(new ILSpyEnvironmentProvider()), null); var outputFormatter = new VBTextOutputFormatter(output); var formattingPolicy = new VBFormattingOptions(); unit.AcceptVisitor(new OutputVisitor(outputFormatter, formattingPolicy), null); }
public static List<ReferenceSegment> Decompile (TextEditor data, ModuleDefinition module, TypeDefinition currentType, Action<AstBuilder> setData, DecompilerSettings settings) { var context = new DecompilerContext (module); var source = new CancellationTokenSource (); context.CancellationToken = source.Token; context.CurrentType = currentType; context.Settings = settings; try { var astBuilder = new AstBuilder (context); setData (astBuilder); astBuilder.RunTransformations (o => false); GeneratedCodeSettings.Default.Apply (astBuilder.SyntaxTree); var output = new ColoredCSharpFormatter (data); astBuilder.GenerateCode (output); output.SetDocumentData (); return output.ReferencedSegments; } catch (Exception e) { // exception -> try to decompile without method bodies try { var astBuilder = new AstBuilder (context); astBuilder.DecompileMethodBodies = false; setData (astBuilder); astBuilder.RunTransformations (o => false); GeneratedCodeSettings.Default.Apply (astBuilder.SyntaxTree); var output = new ColoredCSharpFormatter (data); astBuilder.GenerateCode (output); output.SetDocumentData (); data.InsertText (data.Length, "/* body decompilation failed: \n" + e + " */"); } catch (Exception e2) { data.Text = "/* fallback decompilation failed: \n" + e2 +"*/"; } } return null; }
void Run(Config config) { if (config.AssembliesToDecompile.Count == 0) { config.ShowHelp = true; } if (config.ShowHelp) { Console.WriteLine ("Netjs compiler, Copyright 2014-2016 Frank A. Krueger"); Console.WriteLine ("netjs [options] assembly-files"); Console.WriteLine (" --help, -h Show usage information"); Console.WriteLine (" --includerefs, -r Decompile referenced assemblies"); return; } string outPath = ""; var asmPaths = new List<string> (); foreach (var asmRelPath in config.AssembliesToDecompile) { var asmPath = Path.GetFullPath (asmRelPath); asmPaths.Add (asmPath); if (string.IsNullOrEmpty (outPath)) { outPath = Path.ChangeExtension (asmPath, ".ts"); } var asmDir = Path.GetDirectoryName (asmPath); if (!asmSearchPaths.Exists (x => x.Item1 == asmDir)) { asmSearchPaths.Add (Tuple.Create (asmDir, config.IncludeRefs)); } } Step ("Reading IL"); globalReaderParameters.AssemblyResolver = this; globalReaderParameters.ReadingMode = ReadingMode.Immediate; var libDir = Path.GetDirectoryName (typeof (String).Assembly.Location); asmSearchPaths.Add (Tuple.Create(libDir, false)); asmSearchPaths.Add (Tuple.Create(Path.Combine (libDir, "Facades"), false)); AssemblyDefinition firstAsm = null; foreach (var asmPath in asmPaths) { var asm = AssemblyDefinition.ReadAssembly (asmPath, globalReaderParameters); if (firstAsm == null) firstAsm = asm; referencedAssemblies[asm.Name.Name] = asm; decompileAssemblies.Add (asm); } Step ("Decompiling IL to C#"); var context = new DecompilerContext (firstAsm.MainModule); context.Settings.ForEachStatement = false; context.Settings.ObjectOrCollectionInitializers = false; context.Settings.UsingStatement = false; context.Settings.AsyncAwait = false; context.Settings.AutomaticProperties = true; context.Settings.AutomaticEvents = true; context.Settings.QueryExpressions = false; context.Settings.AlwaysGenerateExceptionVariableForCatchBlocks = true; context.Settings.UsingDeclarations = false; context.Settings.FullyQualifyAmbiguousTypeNames = true; context.Settings.YieldReturn = false; var builder = new AstBuilder (context); var decompiled = new HashSet<string> (); for (;;) { var a = decompileAssemblies.FirstOrDefault (x => !decompiled.Contains (x.FullName)); if (a != null) { Info (" Decompiling {0}", a.FullName); builder.AddAssembly (a); decompiled.Add (a.FullName); } else { break; } } builder.RunTransformations (); Step ("Translating C# to TypeScript"); new CsToTs ().Run (builder.SyntaxTree); Step ("Writing"); using (var outputWriter = new StreamWriter (outPath)) { var output = new PlainTextOutput (outputWriter); builder.GenerateCode (output, (s, e) => new TsOutputVisitor (s, e)); } Step ("Done"); }
public static List<ReferenceSegment> Decompile (TextEditorData data, ModuleDefinition module, TypeDefinition currentType, Action<AstBuilder> setData) { try { var types = DesktopService.GetMimeTypeInheritanceChain (data.Document.MimeType); var codePolicy = MonoDevelop.Projects.Policies.PolicyService.GetDefaultPolicy<MonoDevelop.CSharp.Formatting.CSharpFormattingPolicy> (types); var context = new DecompilerContext (module); var source = new CancellationTokenSource (); context.CancellationToken = source.Token; context.CurrentType = currentType; context.Settings = new DecompilerSettings () { AnonymousMethods = true, AutomaticEvents = true, AutomaticProperties = true, ForEachStatement = true, LockStatement = true }; AstBuilder astBuilder = new AstBuilder (context); setData (astBuilder); astBuilder.RunTransformations (o => false); var output = new ColoredCSharpFormatter (data.Document); astBuilder.GenerateCode (output, codePolicy.CreateOptions ()); output.SetDocumentData (); return output.ReferencedSegments; } catch (Exception e) { data.Text = "Decompilation failed: \n" + e; } return null; }
public static List<ReferenceSegment> Decompile (TextEditorData data, ModuleDefinition module, TypeDefinition currentType, Action<AstBuilder> setData, DecompilerSettings settings) { try { var context = new DecompilerContext (module); var source = new CancellationTokenSource (); context.CancellationToken = source.Token; context.CurrentType = currentType; context.Settings = settings; AstBuilder astBuilder = new AstBuilder (context); setData (astBuilder); astBuilder.RunTransformations (o => false); GeneratedCodeSettings.Default.Apply (astBuilder.CompilationUnit); var output = new ColoredCSharpFormatter (data.Document); astBuilder.GenerateCode (output); output.SetDocumentData (); return output.ReferencedSegments; } catch (Exception e) { data.Text = "Decompilation failed: \n" + e; } return null; }
void RunTransformsAndGenerateCode(AstBuilder astBuilder, ITextOutput output, DecompilationOptions options, ModuleDefinition module) { astBuilder.RunTransformations(transformAbortCondition); if (options.DecompilerSettings.ShowXmlDocumentation) AddXmlDocTransform.Run(astBuilder.SyntaxTree); var csharpUnit = astBuilder.SyntaxTree; csharpUnit.AcceptVisitor(new NRefactory.CSharp.InsertParenthesesVisitor() { InsertParenthesesForReadability = true }); var unit = csharpUnit.AcceptVisitor(new CSharpToVBConverterVisitor(new ILSpyEnvironmentProvider()), null); var outputFormatter = new VBTextOutputFormatter(output); var formattingPolicy = new VBFormattingOptions(); unit.AcceptVisitor(new OutputVisitor(outputFormatter, formattingPolicy), null); }
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); }
void RunTransformsAndGenerateCode(AstBuilder astBuilder, ITextOutput output, DecompilationContext ctx, IAstTransform additionalTransform = null) { astBuilder.RunTransformations(transformAbortCondition); if (additionalTransform != null) { additionalTransform.Run(astBuilder.SyntaxTree); } CSharpLanguage.AddXmlDocumentation(langSettings.Settings, astBuilder); var csharpUnit = astBuilder.SyntaxTree; csharpUnit.AcceptVisitor(new ICSharpCode.NRefactory.CSharp.InsertParenthesesVisitor() { InsertParenthesesForReadability = true }); var unit = csharpUnit.AcceptVisitor(new CSharpToVBConverterVisitor(new ILSpyEnvironmentProvider()), null); var outputFormatter = new VBTextOutputFormatter(output); var formattingPolicy = new VBFormattingOptions(); unit.AcceptVisitor(new OutputVisitor(outputFormatter, formattingPolicy), null); }