Пример #1
0
        public void Decompile(Stream assemblyStream, TextWriter resultWriter)
        {
            // ReSharper disable once AgentHeisenbug.CallToNonThreadSafeStaticMethodInThreadSafeType
            var module = ModuleDefinition.ReadModule(assemblyStream);
            ((BaseAssemblyResolver)module.AssemblyResolver).AddSearchDirectory(
                Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)
            );

            var context = new DecompilerContext(module) {
                Settings = {
                    AnonymousMethods = false,
                    YieldReturn = false,
                    AsyncAwait = false,
                    AutomaticProperties = false,
                    ExpressionTrees = false
                }
            };

            var ast = new AstBuilder(context);
            ast.AddAssembly(module.Assembly);

            RunTransforms(ast, context);

            // I cannot use GenerateCode as it re-runs all the transforms
            var userCode = GetUserCode(ast);
            WriteResult(resultWriter, userCode, context);
        }
Пример #2
0
 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;
         }
     });
 }
		public void DecompileOnDemand(TypeDefinition type)
		{
			if (type == null)
				return;
			
			if (CheckMappings(type.MetadataToken.ToInt32()))
				return;
			
			try {
				DecompilerContext context = new DecompilerContext(type.Module);
				AstBuilder astBuilder = new AstBuilder(context);
				astBuilder.AddType(type);
				astBuilder.GenerateCode(new PlainTextOutput());
				
				int token = type.MetadataToken.ToInt32();
				var info = new DecompileInformation {
					CodeMappings = astBuilder.CodeMappings,
					LocalVariables = astBuilder.LocalVariables,
					DecompiledMemberReferences = astBuilder.DecompiledMemberReferences
				};
				
				// save the data
				DebugInformation.AddOrUpdate(token, info, (k, v) => info);
			} catch {
				return;
			}
		}
Пример #4
0
        private static void CompareAssemblyAgainstCSharp(string expectedCSharpCode, string asmFilePath)
        {
            var module = Utils.OpenModule(asmFilePath);
            try
            {
                try { module.LoadPdb(); } catch { }
                AstBuilder decompiler = new AstBuilder(DecompilerContext.CreateTestContext(module));
                decompiler.AddAssembly(module, false, true, true);
                new Helpers.RemoveCompilerAttribute().Run(decompiler.SyntaxTree);
                StringWriter output = new StringWriter();

                // the F# assembly contains a namespace `<StartupCode$tmp6D55>` where the part after tmp is randomly generated.
                // remove this from the ast to simplify the diff
                var startupCodeNode = decompiler.SyntaxTree.Children.OfType<NamespaceDeclaration>().SingleOrDefault(d => d.Name.StartsWith("<StartupCode$", StringComparison.Ordinal));
                if (startupCodeNode != null)
                    startupCodeNode.Remove();

                decompiler.GenerateCode(new PlainTextOutput(output));
                var fullCSharpCode = output.ToString();

                CodeAssert.AreEqual(expectedCSharpCode, output.ToString());
            }
            finally
            {
                File.Delete(asmFilePath);
                File.Delete(Path.ChangeExtension(asmFilePath, ".pdb"));
            }
        }
Пример #5
0
        private IEnumerable<AstNode> GetUserCode(AstBuilder ast)
        {
            //if (!scriptMode)
                return new[] { ast.SyntaxTree };

            //var scriptClass = ast.CompilationUnit.Descendants.OfType<TypeDeclaration>().First(t => t.Name == "Script");
            //return FlattenScript(scriptClass);
        }
 internal MethodBuilder(MethodDefinition methodDefinition, ModuleDefinition currentModule) {
     _methodDefinition = methodDefinition;
     _builder = new AstDecompiler.AstBuilder(new DecompilerContext(currentModule) {
         CurrentMethod = methodDefinition,
         CurrentType = methodDefinition.DeclaringType,
         Settings = new DecompilerSettings()
     });
 }
Пример #7
0
        //private IEnumerable<AstNode> FlattenScript(TypeDeclaration scriptClass) {
        //    foreach (var member in scriptClass.Members) {
        //        var constructor = member as ConstructorDeclaration;
        //        if (constructor != null) {
        //            foreach (var statement in constructor.Body.Statements) {
        //                yield return statement;
        //            }
        //        }
        //        else {
        //            yield return member;
        //        }
        //    }
        //}
        private void RunTransforms(AstBuilder ast, DecompilerContext context)
        {
            var transforms = TransformationPipeline.CreatePipeline(context).ToList();
            transforms[transforms.FindIndex(t => t is ConvertConstructorCallIntoInitializer)] = new RoslynFriendlyConvertConstructorCallIntoInitializer();

            foreach (var transform in transforms) {
                transform.Run(ast.SyntaxTree);
            }
        }
Пример #8
0
 public AnalysisLayer(StorageLayer layer)
 {
     AstBuilder astBuilder;
     var method = DecompileUtil.GetMethodCode(layer.Algorithm.GetType(), out astBuilder, "ProcessCell");
     this.Name = layer.Algorithm.GetType().Name;
     this.Code = method.Body.GetTrackedText();
     this.Algorithm = layer.Algorithm;
     this.AstBuilder = astBuilder;
 }
Пример #9
0
		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;
		}
Пример #10
0
		/// <summary>
		/// Compiles and decompiles a source code.
		/// </summary>
		/// <param name="code">The source code to copile.</param>
		/// <returns>The decompilation result of compiled source code.</returns>
		static string RoundtripCode(string code)
		{
			AssemblyDefinition assembly = Compile(code);
			AstBuilder decompiler = new AstBuilder(new DecompilerContext());
			decompiler.AddAssembly(assembly);
			decompiler.Transform(new Helpers.RemoveCompilerAttribute());
			StringWriter output = new StringWriter();
			decompiler.GenerateCode(new PlainTextOutput(output));
			return output.ToString();
		}
 internal MethodBuilder(MethodDefinition methodDefinition, ModuleDefinition currentModule)
 {
     _methodDefinition = methodDefinition;
     _builder          = new AstDecompiler.AstBuilder(new DecompilerContext(currentModule)
     {
         CurrentMethod = methodDefinition,
         CurrentType   = methodDefinition.DeclaringType,
         Settings      = new DecompilerSettings()
     });
 }
Пример #12
0
        public void DecompileFile(string input, TextWriter writer)
        {
            var assembly = AssemblyDefinition.ReadAssembly(input, new ReaderParameters() {
                AssemblyResolver = new IgnoringExceptionsAssemblyResolver()
            });

            var decompiler = new AstBuilder(new DecompilerContext(assembly.MainModule));
            decompiler.AddAssembly(assembly);
            decompiler.GenerateCode(new PlainTextOutput(writer));
            writer.Close();
        }
Пример #13
0
 protected override void InnerGenerateCode(AstBuilder astBuilder, ITextOutput output)
 {
     if (output is StringBuilderTextOutput)
     {
         GenerateAstJson(astBuilder, output);
     }
     else
     {
         base.InnerGenerateCode(astBuilder, output);
     }
 }
Пример #14
0
		void Run(string compiledFile, string expectedOutputFile)
		{
			string expectedOutput = File.ReadAllText(Path.Combine(path, expectedOutputFile));
			var assembly = AssemblyDefinition.ReadAssembly(Path.Combine(path, compiledFile));
			AstBuilder decompiler = new AstBuilder(new DecompilerContext(assembly.MainModule));
			decompiler.AddAssembly(assembly);
			new Helpers.RemoveCompilerAttribute().Run(decompiler.SyntaxTree);
			StringWriter output = new StringWriter();
			decompiler.GenerateCode(new PlainTextOutput(output));
			CodeAssert.AreEqual(expectedOutput, output.ToString());
		}
Пример #15
0
 public void Decompile()
 {
     AssemblyDefinition assembly = AssemblyDefinition.ReadAssembly("Salient.JsonSchemaUtilities.dll");
     DecompilerSettings settings = new DecompilerSettings();
     settings.FullyQualifyAmbiguousTypeNames = false;
     AstBuilder decompiler = new AstBuilder(new DecompilerContext(assembly.MainModule) { Settings = settings });
     decompiler.AddAssembly(assembly);
     //new Helpers.RemoveCompilerAttribute().Run(decompiler.CompilationUnit);
     StringWriter output = new StringWriter();
     decompiler.GenerateCode(new PlainTextOutput(output));
     var code = output.ToString();
 }
Пример #16
0
		/// <summary>
		/// Compiles and decompiles a source code.
		/// </summary>
		/// <param name="code">The source code to copile.</param>
		/// <returns>The decompilation result of compiled source code.</returns>
		static string RoundtripCode(string code)
		{
			DecompilerSettings settings = new DecompilerSettings();
			settings.FullyQualifyAmbiguousTypeNames = false;
			AssemblyDefinition assembly = Compile(code);
			AstBuilder decompiler = new AstBuilder(new DecompilerContext(assembly.MainModule) { Settings = settings });
			decompiler.AddAssembly(assembly);
			new Helpers.RemoveCompilerAttribute().Run(decompiler.CompilationUnit);
			StringWriter output = new StringWriter();
			decompiler.GenerateCode(new PlainTextOutput(output));
			return output.ToString();
		}
Пример #17
0
		protected static void AssertRoundtripCode(string fileName, bool optimize = false, bool useDebug = false, int compilerVersion = 4)
		{
			var code = RemoveIgnorableLines(File.ReadLines(fileName));
			AssemblyDef assembly = CompileLegacy(code, optimize, useDebug, compilerVersion);

			AstBuilder decompiler = new AstBuilder(DecompilerContext.CreateTestContext(assembly.ManifestModule));
			decompiler.AddAssembly(assembly);
			new Helpers.RemoveCompilerAttribute().Run(decompiler.SyntaxTree);

			StringWriter output = new StringWriter();
			decompiler.GenerateCode(new PlainTextOutput(output));
			CodeAssert.AreEqual(code, output.ToString());
		}
 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);
     }
 }
Пример #19
0
 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();
 }
Пример #20
0
		static void TestFile(string fileName)
		{
			string code = File.ReadAllText(fileName);
			AssemblyDefinition assembly = Compile(code);
			AstBuilder decompiler = new AstBuilder(new DecompilerContext());
			decompiler.AddAssembly(assembly);
			decompiler.Transform(new Helpers.RemoveCompilerAttribute());
			StringWriter output = new StringWriter();
			decompiler.GenerateCode(new PlainTextOutput(output));
			StringWriter diff = new StringWriter();
			if (!Compare(code, output.ToString(), diff)) {
				throw new Exception("Test failure." + Environment.NewLine + diff.ToString());
			}
		}
Пример #21
0
 void GenerateAstJson(AstBuilder astBuilder, ITextOutput output)
 {
     var visitor = new AstCsToJsonVisitor(output);
     astBuilder.SyntaxTree.AcceptVisitor(new InsertParenthesesVisitor { InsertParenthesesForReadability = true });
     astBuilder.SyntaxTree.AcceptVisitor(visitor);
     AstCsToJsonVisitor visit = visitor as AstCsToJsonVisitor;
     if (visit != null)
     {
         result = visit.LastValue;
     }
     else
     {
         result = null;
     } 
 }
Пример #22
0
        /// <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();
        }
Пример #23
0
		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;
		}
Пример #24
0
		// 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());
			}
		}
Пример #25
0
 public static async Task<string> GetSourceCode(TypeDefinition typeDefinition)
 {
     return await Task.Run(() =>
     {
         try
         {
             var settings = new DecompilerSettings { UsingDeclarations = true };
             var context = new DecompilerContext(typeDefinition.Module)
             {
                 CurrentType = typeDefinition,
                 Settings = settings
             };
             var astBuilder = new AstBuilder(context);
             var textOutput = new PlainTextOutput();
             astBuilder.GenerateCode(textOutput);
             return textOutput.ToString();
         }
         catch (Exception ex)
         {
             return "Error in creating source code from Type: " + ex.Message + ex.Message + Environment.NewLine + ex.StackTrace;
         }
     });
 }
Пример #26
0
		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);
		}
Пример #28
0
 private void GenerateCode(AstBuilder decompiler)
 {
     decompiler.GenerateCode(_output);
     if (!String.IsNullOrEmpty(OutputFileName))
     {
         File.WriteAllText(OutputFileName, _output.ToString());
     }
     else
     {
         _context.Write(_output.ToString());
     }
 }
Пример #29
0
        private void DecompileTypeFromModule(string typeName, string moduleFileName)
        {
            var assemblyDef = AssemblyDefinition.ReadAssembly(moduleFileName);
            var typeDef = TypeDefFromAssemblyDef(typeName, assemblyDef);

            AstBuilder decompiler = new AstBuilder(
                new DecompilerContext(typeDef.Module));
            decompiler.AddType(typeDef);

            GenerateCode(decompiler);
        }
Пример #30
0
        private void DecompileModule(ClrModule module)
        {
            var assemblyDef = AssemblyDefinition.ReadAssembly(module.FileName);
            AstBuilder decompiler = new AstBuilder(
                new DecompilerContext(assemblyDef.MainModule));
            decompiler.AddAssembly(assemblyDef);

            GenerateCode(decompiler);
        }
Пример #31
-1
        public string GetClass(TypeIdentity identity)
        {
            // Before we attempt to fetch it just try a decompilation.
            GetAssembly(identity.AssemblyPath);

            ModuleDefinition moduleDef;
            if (!this.loadedModules.TryGetValue(identity.AssemblyPath, out moduleDef))
            {
                // Can't find the assembly, just return nothing.
                return string.Empty;
            }

            TypeDefinition typeDef = moduleDef.GetType(identity.FullyQualifiedName);
            if (typeDef == null)
            {
                // If we can't find our type just return as well.
                return string.Empty;
            }

            DecompilerContext context = new DecompilerContext(moduleDef);
            AstBuilder astBuilder = new AstBuilder(context);
            astBuilder.AddType(typeDef);

            PlainTextOutput textOutput = new PlainTextOutput();
            astBuilder.GenerateCode(textOutput);
            return textOutput.ToString();
        }