Beispiel #1
0
		public static void RunStep1(DecompilerContext context, ILBlock method)
		{
			if (!context.Settings.AsyncAwait)
				return; // abort if async decompilation is disabled
			var yrd = new AsyncDecompiler();
			yrd.context = context;
			if (!yrd.MatchTaskCreationPattern(method))
				return;
			#if DEBUG
			if (Debugger.IsAttached) {
				yrd.Run();
			} else {
				#endif
				try {
					yrd.Run();
				} catch (SymbolicAnalysisFailedException) {
					return;
				}
				#if DEBUG
			}
			#endif
			context.CurrentMethodIsAsync = true;
			
			method.Body.Clear();
			method.EntryGoto = null;
			method.Body.AddRange(yrd.newTopLevelBody);
			ILAstOptimizer.RemoveRedundantCode(method);
		}
Beispiel #2
0
		HashSet<ILVariable> localVariablesToDefine = new HashSet<ILVariable>(); // local variables that are missing a definition
		
		/// <summary>
		/// Creates the body for the method definition.
		/// </summary>
		/// <param name="methodDef">Method definition to decompile.</param>
		/// <param name="context">Decompilation context.</param>
		/// <param name="parameters">Parameter declarations of the method being decompiled.
		/// These are used to update the parameter names when the decompiler generates names for the parameters.</param>
		/// <param name="localVariables">Local variables storage that will be filled/updated with the local variables.</param>
		/// <returns>Block for the method body</returns>
		public static BlockStatement CreateMethodBody(MethodDefinition methodDef,
		                                              DecompilerContext context,
		                                              IEnumerable<ParameterDeclaration> parameters = null,
		                                              ConcurrentDictionary<int, IEnumerable<ILVariable>> localVariables = null)
		{
			if (localVariables == null)
				localVariables = new ConcurrentDictionary<int, IEnumerable<ILVariable>>();
			
			MethodDefinition oldCurrentMethod = context.CurrentMethod;
			Debug.Assert(oldCurrentMethod == null || oldCurrentMethod == methodDef);
			context.CurrentMethod = methodDef;
			try {
				AstMethodBodyBuilder builder = new AstMethodBodyBuilder();
				builder.methodDef = methodDef;
				builder.context = context;
				builder.typeSystem = methodDef.Module.TypeSystem;
				if (Debugger.IsAttached) {
					return builder.CreateMethodBody(parameters, localVariables);
				} else {
					try {
						return builder.CreateMethodBody(parameters, localVariables);
					} catch (OperationCanceledException) {
						throw;
					} catch (Exception ex) {
						throw new ICSharpCode.Decompiler.DecompilerException(methodDef, ex);
					}
				}
			} finally {
				context.CurrentMethod = oldCurrentMethod;
			}
		}
		public static void Run(DecompilerContext context, ILBlock method)
		{
			if (!context.Settings.YieldReturn)
				return; // abort if enumerator decompilation is disabled
			var yrd = new YieldReturnDecompiler();
			yrd.context = context;
			if (!yrd.MatchEnumeratorCreationPattern(method))
				return;
			yrd.enumeratorType = yrd.enumeratorCtor.DeclaringType;
			#if DEBUG
			if (Debugger.IsAttached) {
				yrd.Run();
			} else {
				#endif
				try {
					yrd.Run();
				} catch (YieldAnalysisFailedException) {
					return;
				}
				#if DEBUG
			}
			#endif
			method.Body.Clear();
			method.EntryGoto = null;
			method.Body.AddRange(yrd.newBody);
		}
Beispiel #4
0
		public static void Run(DecompilerContext context, ILBlock method)
		{
			if (!context.Settings.YieldReturn)
				return; // abort if enumerator decompilation is disabled
			var yrd = new YieldReturnDecompiler();
			yrd.context = context;
			if (!yrd.MatchEnumeratorCreationPattern(method))
				return;
			yrd.enumeratorType = yrd.enumeratorCtor.DeclaringType;
			#if DEBUG
			if (Debugger.IsAttached) {
				yrd.Run();
			} else {
				#endif
				try {
					yrd.Run();
				} catch (SymbolicAnalysisFailedException) {
					return;
				}
				#if DEBUG
			}
			#endif
			method.Body.Clear();
			method.EntryGoto = null;
			method.Body.AddRange(yrd.newBody);
			
			// Repeat the inlining/copy propagation optimization because the conversion of field access
			// to local variables can open up additional inlining possibilities.
			ILInlining inlining = new ILInlining(method);
			inlining.InlineAllVariables();
			inlining.CopyPropagation();
		}
Beispiel #5
0
		HashSet<ILVariable> localVariablesToDefine = new HashSet<ILVariable>(); // local variables that are missing a definition
		
		/// <summary>
		/// Creates the body for the method definition.
		/// </summary>
		/// <param name="methodDef">Method definition to decompile.</param>
		/// <param name="context">Decompilation context.</param>
		/// <param name="parameters">Parameter declarations of the method being decompiled.
		/// These are used to update the parameter names when the decompiler generates names for the parameters.</param>
		/// <returns>Block for the method body</returns>
		public static BlockStatement CreateMethodBody(MethodDef methodDef,
		                                              DecompilerContext context,
		                                              IEnumerable<ParameterDeclaration> parameters,
													  out MemberMapping mm)
		{
			MethodDef oldCurrentMethod = context.CurrentMethod;
			Debug.Assert(oldCurrentMethod == null || oldCurrentMethod == methodDef);
			context.CurrentMethod = methodDef;
			context.CurrentMethodIsAsync = false;
			try {
				AstMethodBodyBuilder builder = new AstMethodBodyBuilder();
				builder.methodDef = methodDef;
				builder.context = context;
				builder.corLib = methodDef.Module.CorLibTypes;
				if (Debugger.IsAttached) {
					return builder.CreateMethodBody(parameters, out mm);
				} else {
					try {
						return builder.CreateMethodBody(parameters, out mm);
					} catch (OperationCanceledException) {
						throw;
					} catch (Exception ex) {
						throw new ICSharpCode.Decompiler.DecompilerException(methodDef, ex);
					}
				}
			} finally {
				context.CurrentMethod = oldCurrentMethod;
			}
		}
Beispiel #6
0
		public static void Run(DecompilerContext context, ILBlock method, List<ILNode> list_ILNode, Func<ILBlock, ILInlining> getILInlining)
		{
			if (!context.Settings.YieldReturn)
				return; // abort if enumerator decompilation is disabled
			var yrd = new YieldReturnDecompiler();
			yrd.context = context;
			if (!yrd.MatchEnumeratorCreationPattern(method))
				return;
			yrd.enumeratorType = yrd.enumeratorCtor.DeclaringType;
			#if DEBUG && CRASH_IN_DEBUG_MODE
			if (Debugger.IsAttached) {
				yrd.Run();
			} else {
				#endif
				try {
					yrd.Run();
				} catch (SymbolicAnalysisFailedException) {
					return;
				}
				#if DEBUG && CRASH_IN_DEBUG_MODE
			}
			#endif
			method.Body.Clear();
			method.EntryGoto = null;
			method.Body.AddRange(yrd.newBody);//TODO: Make sure that the removed ILRanges from Clear() above is saved in the new body
			
			// Repeat the inlining/copy propagation optimization because the conversion of field access
			// to local variables can open up additional inlining possibilities.
			var inlining = getILInlining(method);
			inlining.InlineAllVariables();
			inlining.CopyPropagation(list_ILNode);
		}
Beispiel #7
0
		HashSet<ILVariable> localVariablesToDefine = new HashSet<ILVariable>(); // local variables that are missing a definition
		
		public static BlockStatement CreateMethodBody(MethodDefinition methodDef, DecompilerContext context)
		{
			MethodDefinition oldCurrentMethod = context.CurrentMethod;
			Debug.Assert(oldCurrentMethod == null || oldCurrentMethod == methodDef);
			context.CurrentMethod = methodDef;
			try {
				AstMethodBodyBuilder builder = new AstMethodBodyBuilder();
				builder.methodDef = methodDef;
				builder.context = context;
				builder.typeSystem = methodDef.Module.TypeSystem;
				if (Debugger.IsAttached) {
					return builder.CreateMethodBody();
				} else {
					try {
						return builder.CreateMethodBody();
					} catch (OperationCanceledException) {
						throw;
					} catch (Exception ex) {
						throw new ICSharpCode.Decompiler.DecompilerException(methodDef, ex);
					}
				}
			} finally {
				context.CurrentMethod = oldCurrentMethod;
			}
		}
Beispiel #8
0
 public static void Run(DecompilerContext context, AstBlock method)
 {
     var ta = new TypeAnalysis(context);
     ta.CreateDependencyGraph(method);
     ta.IdentifySingleLoadVariables();
     ta.RunInference();
 }
        public static void RunTransformationsUntil(AstNode node, Predicate<IAstTransform> abortCondition, DecompilerContext context)
        {
            if (node == null)
                return;
            for (int i = 0; i < 4; i++) {
                context.CancellationToken.ThrowIfCancellationRequested();
                if (Options.ReduceAstJumps) {
                    node.AcceptVisitor(new Transforms.Ast.RemoveGotos(), null);
                    node.AcceptVisitor(new Transforms.Ast.RemoveDeadLabels(), null);
                }
                if (Options.ReduceAstLoops) {
                    node.AcceptVisitor(new Transforms.Ast.RestoreLoop(), null);
                }
                if (Options.ReduceAstOther) {
                    node.AcceptVisitor(new Transforms.Ast.RemoveEmptyElseBody(), null);
                }
            }

            foreach (var transform in CreatePipeline(context)) {
                context.CancellationToken.ThrowIfCancellationRequested();
                if (abortCondition != null && abortCondition(transform))
                    return;
                transform.Run(node);
            }
        }
Beispiel #10
0
		public override void DecompileMethod(MethodDefinition method, ITextOutput output, DecompilationOptions options)
		{
			if (!method.HasBody) {
				return;
			}
			
			ILAstBuilder astBuilder = new ILAstBuilder();
			ILBlock ilMethod = new ILBlock();
			ilMethod.Body = astBuilder.Build(method, inlineVariables);
			
			if (abortBeforeStep != null) {
				DecompilerContext context = new DecompilerContext { CurrentType = method.DeclaringType, CurrentMethod = method };
				new ILAstOptimizer().Optimize(context, ilMethod, abortBeforeStep.Value);
			}
			
			var allVariables = astBuilder.Variables
				.Concat(ilMethod.GetSelfAndChildrenRecursive<ILExpression>().Select(e => e.Operand as ILVariable).Where(v => v != null)).Distinct();
			foreach (ILVariable v in allVariables) {
				output.WriteDefinition(v.Name, v);
				if (v.Type != null) {
					output.Write(" : ");
					v.Type.WriteTo(output, true, true);
				}
				output.WriteLine();
			}
			output.WriteLine();
			
			foreach (ILNode node in ilMethod.Body) {
				node.WriteTo(output);
				output.WriteLine();
			}
		}
Beispiel #11
0
 public DecompilerCache(DecompilerContext ctx)
 {
     this.pipelinePool = new ObjectPool<IAstTransformPoolObject[]>(() => TransformationPipeline.CreatePipeline(ctx), null);
     this.ilAstBuilderPool = new ObjectPool<ILAstBuilder>(() => new ILAstBuilder(), a => a.Reset());
     this.ilAstOptimizerPool = new ObjectPool<ILAstOptimizer>(() => new ILAstOptimizer(), a => a.Reset());
     this.gotoRemovalPool = new ObjectPool<GotoRemoval>(() => new GotoRemoval(ctx), a => a.Reset());
     this.astMethodBodyBuilderPool = new ObjectPool<AstMethodBodyBuilder>(() => new AstMethodBodyBuilder(), a => a.Reset());
 }
		public static Expression TryConvert(DecompilerContext context, Expression expr)
		{
			Expression converted = new ExpressionTreeConverter(context).Convert(expr);
			if (converted != null) {
				converted.AddAnnotation(new ExpressionTreeLambdaAnnotation());
			}
			return converted;
		}
Beispiel #13
0
		public TextTokenWriter(ITextOutput output, DecompilerContext context)
		{
			if (output == null)
				throw new ArgumentNullException("output");
			if (context == null)
				throw new ArgumentNullException("context");
			this.output = output;
			this.context = context;
		}
        static void RunOnCore()
        {
            Console.Write("Dry run...");
            DateTime startDryRun = DateTime.UtcNow;
            {
                var _para = new ReaderParameters(ReadingMode.Immediate)
                {
                    AssemblyResolver = new AssemblyResolver(),
                    ReadSymbols = false
                };
                var sys = AssemblyDefinition.ReadAssembly(typeof(TestingLogic).Assembly.Location, _para);
                var _dc = new DecompilerContext(sys.MainModule);
                var _astb = new AstBuilder(_dc);
                _astb.AddAssembly(sys);
                _astb.RunTransformations();
                _astb.GenerateCode(new DummyOutput());
            }
            TimeSpan dryRunTime = DateTime.UtcNow - startDryRun;
            Console.WriteLine(" O.K. " + dryRunTime.TotalSeconds.ToString("0.000") + " s.");

            Console.Write("Press Esc to skip large assembly reading");
            if (Console.ReadKey().Key != ConsoleKey.Escape)
            {
                Console.Write("Reading assembly...");
                DateTime startReading = DateTime.UtcNow;
                var msco = AssemblyDefinition.ReadAssembly(typeof(int).Assembly.Location);
                TimeSpan readAssemblyTime = DateTime.UtcNow - startReading;
                Console.WriteLine(" O.K. " + readAssemblyTime.TotalSeconds.ToString("0.000") + " s.");

                Console.Write("new DecompilerContext(), new AstBuilder()...");
                DateTime startNewContext = DateTime.UtcNow;
                var dc = new DecompilerContext(msco.MainModule);
                var astb = new AstBuilder(dc);
                TimeSpan newContextTime = DateTime.UtcNow - startNewContext;
                Console.WriteLine(" O.K. " + newContextTime.TotalSeconds.ToString("0.000") + " s.");

                Console.Write("AstBuilder.AddAssembly()...");
                DateTime startAddAssembly = DateTime.UtcNow;
                astb.AddAssembly(msco);
                TimeSpan decompilerInitTime = DateTime.UtcNow - startAddAssembly;
                Console.WriteLine(" O.K. " + decompilerInitTime.TotalSeconds.ToString("0.000") + " s.");

                Console.Write("AstBuilder.RunTransformations()...");
                DateTime startTransform = DateTime.UtcNow;
                astb.RunTransformations();
                TimeSpan transformTime = DateTime.UtcNow - startTransform;
                Console.WriteLine(" O.K. " + transformTime.TotalSeconds.ToString("0.000") + " s.");

                Console.Write("AstBuilder.GenerateCode()...");
                DateTime startGeneration = DateTime.UtcNow;
                astb.GenerateCode(new DummyOutput());
                TimeSpan generationTime = DateTime.UtcNow - startGeneration;
                Console.WriteLine(" O.K. " + generationTime.TotalSeconds.ToString("0.000") + " s.");

                Console.Write("Press any key to exit"); Console.ReadKey();
            }
        }
		public static IAstTransform[] CreatePipeline(DecompilerContext context)
		{
			return new IAstTransform[] {
				new PushNegation(),
				new DelegateConstruction(context),
				new PatternStatementTransform(),
				new ConvertConstructorCallIntoInitializer(),
				new ReplaceMethodCallsWithOperators(),
			};
		}
Beispiel #16
0
		public static void Run(DecompilerContext context, ILBlock method)
		{
			TypeAnalysis ta = new TypeAnalysis();
			ta.context = context;
			ta.module = context.CurrentMethod.Module;
			ta.typeSystem = ta.module.TypeSystem;
			ta.method = method;
			ta.InferTypes(method);
			ta.InferRemainingStores();
		}
		public static void Run(DecompilerContext context, ILBlock method)
		{
			TypeAnalysis ta = new TypeAnalysis();
			ta.context = context;
			ta.module = context.CurrentMethod.Module;
			ta.typeSystem = ta.module.TypeSystem;
			ta.method = method;
			ta.CreateDependencyGraph(method);
			ta.IdentifySingleLoadVariables();
			ta.RunInference();
		}
		public static void RunTransformationsUntil(AstNode node, Predicate<IAstTransform> abortCondition, DecompilerContext context)
		{
			if (node == null)
				return;
			
			foreach (var transform in CreatePipeline(context)) {
				context.CancellationToken.ThrowIfCancellationRequested();
				if (abortCondition != null && abortCondition(transform))
					return;
				transform.Run(node);
			}
		}
		public static void RunTransformationsUntil(AstNode node, Predicate<IAstTransform> abortCondition, DecompilerContext context)
		{
			if (node == null)
				return;
			
			foreach (var transform in CreatePipeline(context)) {
				context.VerifyProgress();
				if (abortCondition != null && abortCondition(transform))
					return;
				transform.Run(node);
			}
		}
Beispiel #20
0
		public static void Run(DecompilerContext context, ILBlock method)
		{
			PeepholeTransforms transforms = new PeepholeTransforms();
			transforms.context = context;
			transforms.method = method;
			
			PeepholeTransform[] blockTransforms = {
				ArrayInitializers.Transform(method),
				transforms.CachedDelegateInitialization
			};
			Func<ILExpression, ILExpression>[] exprTransforms = {
				EliminateDups,
				HandleDecimalConstants
			};
			// Traverse in post order so that nested blocks are transformed first. This is required so that
			// patterns on the parent block can assume that all nested blocks are already transformed.
			foreach (var node in TreeTraversal.PostOrder<ILNode>(method, c => c != null ? c.GetChildren() : null)) {
				ILBlock block = node as ILBlock;
				ILExpression expr;
				if (block != null) {
					// go through the instructions in reverse so that transforms can build up nested structures inside-out
					for (int i = block.Body.Count - 1; i >= 0; i--) {
						context.CancellationToken.ThrowIfCancellationRequested();
						expr = block.Body[i] as ILExpression;
						if (expr != null) {
							// apply expr transforms to top-level expr in block
							foreach (var t in exprTransforms)
								expr = t(expr);
							block.Body[i] = expr;
						}
						// apply block transforms
						foreach (var t in blockTransforms) {
							t(block, ref i);
							Debug.Assert(i <= block.Body.Count && i >= 0);
							if (i == block.Body.Count) // special case: retry all transforms
								break;
						}
					}
				}
				expr = node as ILExpression;
				if (expr != null) {
					// apply expr transforms to all arguments
					for (int i = 0; i < expr.Arguments.Count; i++) {
						ILExpression arg = expr.Arguments[i];
						foreach (var t in exprTransforms)
							arg = t(arg);
						expr.Arguments[i] = arg;
					}
				}
			}
		}
		public static IAstTransform[] CreatePipeline(DecompilerContext context)
		{
			return new IAstTransform[] {
				new PushNegation(),
				new DelegateConstruction(context),
				new PatternStatementTransform(context),
				new ReplaceMethodCallsWithOperators(),
				new IntroduceUnsafeModifier(),
				new AddCheckedBlocks(),
				new DeclareVariables(context), // should run after most transforms that modify statements
				new ConvertConstructorCallIntoInitializer(), // must run after DeclareVariables
				new IntroduceUsingDeclarations(context)
			};
		}
Beispiel #22
0
		public SimpleControlFlow(DecompilerContext context, ILBlock method)
		{
			this.context = context;
			this.typeSystem = context.CurrentMethod.Module.TypeSystem;
			
			foreach(ILLabel target in method.GetSelfAndChildrenRecursive<ILExpression>(e => e.IsBranch()).SelectMany(e => e.GetBranchTargets())) {
				labelGlobalRefCount[target] = labelGlobalRefCount.GetOrDefault(target) + 1;
			}
			foreach(ILBasicBlock bb in method.GetSelfAndChildrenRecursive<ILBasicBlock>()) {
				foreach(ILLabel label in bb.GetChildren().OfType<ILLabel>()) {
					labelToBasicBlock[label] = bb;
				}
			}
		}
Beispiel #23
0
		public static void AssignNamesToVariables(DecompilerContext context, IEnumerable<ILVariable> parameters, IEnumerable<ILVariable> variables, ILBlock methodBody)
		{
			NameVariables nv = new NameVariables();
			nv.context = context;
			nv.fieldNamesInCurrentType = context.CurrentType.Fields.Select(f => f.Name).ToList();
			nv.AddExistingNames(parameters.Select(p => p.Name));
			nv.AddExistingNames(variables.Where(v => v.IsGenerated).Select(v => v.Name));
			foreach (ILVariable p in parameters) {
				if (string.IsNullOrEmpty(p.Name))
					p.Name = nv.GenerateNameForVariable(p, methodBody);
			}
			foreach (ILVariable varDef in variables) {
				if (!varDef.IsGenerated) {
					varDef.Name = nv.GenerateNameForVariable(varDef, methodBody);
				}
			}
		}
        public void Optimize(DecompilerContext context, ILBlock method, ILAstOptimizationStep abortBeforeStep = ILAstOptimizationStep.None)
        {
            if (abortBeforeStep == ILAstOptimizationStep.SplitToMovableBlocks) return;
            foreach(ILBlock block in method.GetSelfAndChildrenRecursive<ILBlock>().ToList()) {
                SplitToBasicBlocks(block);
            }

            OptimizeShortCircuits(method);

            if (abortBeforeStep == ILAstOptimizationStep.FindLoops) return;
            foreach(ILBlock block in method.GetSelfAndChildrenRecursive<ILBlock>().ToList()) {
                ControlFlowGraph graph;
                graph = BuildGraph(block.Body, (ILLabel)block.EntryGoto.Operand);
                graph.ComputeDominance(context.CancellationToken);
                graph.ComputeDominanceFrontier();
                block.Body = FindLoops(new HashSet<ControlFlowNode>(graph.Nodes.Skip(3)), graph.EntryPoint, false);
            }

            if (abortBeforeStep == ILAstOptimizationStep.FindConditions) return;
            foreach(ILBlock block in method.GetSelfAndChildrenRecursive<ILBlock>().ToList()) {
                ControlFlowGraph graph;
                graph = BuildGraph(block.Body, (ILLabel)block.EntryGoto.Operand);
                // TODO: Fix
                if (graph == null)
                    continue;
                graph.ComputeDominance(context.CancellationToken);
                graph.ComputeDominanceFrontier();
                block.Body = FindConditions(new HashSet<ControlFlowNode>(graph.Nodes.Skip(3)), graph.EntryPoint);
            }

            if (abortBeforeStep == ILAstOptimizationStep.FlattenNestedMovableBlocks) return;
            FlattenBasicBlocks(method);

            if (abortBeforeStep == ILAstOptimizationStep.SimpleGotoRemoval) return;
            SimpleGotoRemoval(method);

            if (abortBeforeStep == ILAstOptimizationStep.RemoveDeadLabels) return;
            RemoveDeadLabels(method);

            if (abortBeforeStep == ILAstOptimizationStep.HandleArrayInitializers) return;
            ArrayInitializers.Transform(method);

            if (abortBeforeStep == ILAstOptimizationStep.TypeInference) return;
            TypeAnalysis.Run(context, method);
        }
Beispiel #25
0
        /// <summary>
        /// Perform all dot42 related Ast conversions.
        /// </summary>
        public static void Convert(DecompilerContext context, AstBlock ast, MethodSource currentMethod, AssemblyCompiler compiler)
        {
            if (ast.IsOptimizedForTarget)
                return;            
#if DEBUG
            //Debugger.Launch();
            if ((currentMethod.Method != null) && (currentMethod.Method.Name.Equals("runTest", StringComparison.OrdinalIgnoreCase)))
            {
                //Debugger.Launch();
            }
#endif

            IntPtrConverter.Convert(ast, compiler);
            TypeOfConverter.Convert(ast, compiler);
            BranchOptimizer.Convert(ast);
            CompoundAssignmentConverter.Convert(ast);
            ByReferenceParamConverter.Convert(context, ast, compiler);
            CompareUnorderedConverter.Convert(ast);
            EnumConverter.Convert(ast, compiler);
            EnumOptimizer.Convert(ast, compiler);

            // Keep this order
            NullableConverter.Convert(ast, compiler);
            PrimitiveAddressOfConverter.Convert(ast, currentMethod, compiler);
            StructCallConverter.Convert(ast, compiler);
            // end

            InitializeStructVariablesConverter.Convert(ast);
            DelegateConverter.Convert(ast);
            LdcWideConverter.Convert(ast);
            LdLocWithConversionConverter.Convert(ast);
            ConvertAfterLoadConversionConverter.Convert(ast);
            ConvertBeforeStoreConversionConverter.Convert(ast);
            CleanupConverter.Convert(ast);

            GenericsConverter.Convert(ast);

            // Expand cast expressions
            CastConverter.Convert(ast, currentMethod, compiler);

            // Expand generic instance information
            GenericInstanceConverter.Convert(ast, currentMethod, compiler);

        }
Beispiel #26
0
		public static IAstTransformPoolObject[] CreatePipeline(DecompilerContext context)
		{
			return new IAstTransformPoolObject[] {
				new PushNegation(),
				new DelegateConstruction(context),
				new PatternStatementTransform(context),
				new ReplaceMethodCallsWithOperators(context),
				new IntroduceUnsafeModifier(),
				new AddCheckedBlocks(),
				new DeclareVariables(context), // should run after most transforms that modify statements
				new ConvertConstructorCallIntoInitializer(context), // must run after DeclareVariables
				new DecimalConstantTransform(),
				new IntroduceUsingDeclarations(context),
				new IntroduceExtensionMethods(context), // must run after IntroduceUsingDeclarations
				new IntroduceQueryExpressions(context), // must run after IntroduceExtensionMethods
				new CombineQueryExpressions(context),
				new FlattenSwitchBlocks(), 
			};
		}
Beispiel #27
0
		public static void RunTransformationsUntil(AstNode node, Predicate<IAstTransform> abortCondition, DecompilerContext context)
		{
			if (node == null)
				return;

			var pipeline = context.Cache.GetPipelinePool();
			try {
				foreach (var transform in pipeline) {
					transform.Reset(context);
					context.CancellationToken.ThrowIfCancellationRequested();
					if (abortCondition != null && abortCondition(transform))
						return;
					transform.Run(node);
				}
			}
			finally {
				context.Cache.Return(pipeline);
			}
		}
		HashSet<ILVariable> localVariablesToDefine = new HashSet<ILVariable>(); // local variables that are missing a definition
		
		/// <summary>
		/// Creates the body for the method definition.
		/// </summary>
		/// <param name="methodDef">Method definition to decompile.</param>
		/// <param name="context">Decompilation context.</param>
		/// <param name="parameters">Parameter declarations of the method being decompiled.
		/// These are used to update the parameter names when the decompiler generates names for the parameters.</param>
		/// <param name="localVariables">Local variables storage that will be filled/updated with the local variables.</param>
		/// <returns>Block for the method body</returns>
		public static BlockStatement CreateMethodBody(MethodDefinition methodDef,
		                                              DecompilerContext context,
		                                              IEnumerable<ParameterDeclaration> parameters = null,
		                                              /*Concurrent*/Dictionary<int, IEnumerable<ILVariable>> localVariables = null)
		{
			if (localVariables == null)
				localVariables = new /*Concurrent*/Dictionary<int, IEnumerable<ILVariable>>();
			
			MethodDefinition oldCurrentMethod = context.CurrentMethod;
			Debug.Assert(oldCurrentMethod == null || oldCurrentMethod == methodDef);
			context.CurrentMethod = methodDef;
			try {
				AstMethodBodyBuilder builder = new AstMethodBodyBuilder();
				builder.methodDef = methodDef;
				builder.context = context;
				builder.typeSystem = methodDef.Module.TypeSystem;
				return builder.CreateMethodBody(parameters, localVariables);
			} finally {
				context.CurrentMethod = oldCurrentMethod;
			}
		}
Beispiel #29
0
 public static void AssignNamesToVariables(DecompilerContext context, IEnumerable<ILVariable> parameters, IEnumerable<ILVariable> variables, ILBlock methodBody)
 {
     NameVariables nv = new NameVariables();
     nv.context = context;
     nv.fieldNamesInCurrentType = context.CurrentType.Fields.Select(f => f.Name).ToList();
     // First mark existing variable names as reserved.
     foreach (string name in context.ReservedVariableNames)
         nv.AddExistingName(name);
     foreach (var p in parameters)
         nv.AddExistingName(p.Name);
     foreach (var v in variables) {
         if (v.IsGenerated) {
             // don't introduce names for variables generated by ILSpy - keep "expr"/"arg"
             nv.AddExistingName(v.Name);
         } else if (v.OriginalVariable != null && context.Settings.UseDebugSymbols) {
             string varName = v.OriginalVariable.Name;
             if (string.IsNullOrEmpty(varName) || varName.StartsWith("V_", StringComparison.Ordinal) || !IsValidName(varName))
             {
                 // don't use the name from the debug symbols if it looks like a generated name
                 v.Name = null;
             } else {
                 // use the name from the debug symbols
                 // (but ensure we don't use the same name for two variables)
                 v.Name = nv.GetAlternativeName(varName);
             }
         } else {
             v.Name = null;
         }
     }
     // Now generate names:
     foreach (ILVariable p in parameters) {
         if (string.IsNullOrEmpty(p.Name))
             p.Name = nv.GenerateNameForVariable(p, methodBody);
     }
     foreach (ILVariable varDef in variables) {
         if (string.IsNullOrEmpty(varDef.Name))
             varDef.Name = nv.GenerateNameForVariable(varDef, methodBody);
     }
 }
		public SimpleControlFlow(DecompilerContext context, ILBlock method)
		{
			this.context = context;
			this.typeSystem = context.CurrentMethod.Module.TypeSystem;

            var labelTargets =
                from e in method.EnumerateSelfAndChildrenRecursive().OfType<ILExpression>()
                where e.IsBranch()
                from t in e.GetBranchTargets()
                select t;
			
			foreach(ILLabel target in labelTargets) {
				labelGlobalRefCount[target] = labelGlobalRefCount.GetOrDefault(target) + 1;
			}

            var basicBlocks = method.EnumerateSelfAndChildrenRecursive().OfType<ILBasicBlock>();

			foreach(ILBasicBlock bb in basicBlocks) {
				foreach(ILLabel label in bb.GetChildren().OfType<ILLabel>()) {
					labelToBasicBlock[label] = bb;
				}
			}
		}
Beispiel #31
0
        public override void Decompile(MethodDef method, IDecompilerOutput output, DecompilationContext ctx)
        {
            WriteCommentBegin(output, true);
            output.Write("Method: ", BoxedTextColor.Comment);
            output.Write(IdentifierEscaper.Escape(method.FullName), method, DecompilerReferenceFlags.Definition, BoxedTextColor.Comment);
            WriteCommentEnd(output, true);
            output.WriteLine();

            if (!method.HasBody)
            {
                return;
            }

            var bodyInfo = StartKeywordBlock(output, ".body", method);

            ILAstBuilder      astBuilder = new ILAstBuilder();
            ILBlock           ilMethod   = new ILBlock(CodeBracesRangeFlags.MethodBraces);
            DecompilerContext context    = new DecompilerContext(settingsVersion, method.Module, MetadataTextColorProvider)
            {
                CurrentType      = method.DeclaringType,
                CurrentMethod    = method,
                CalculateILSpans = ctx.CalculateILSpans,
            };

            ilMethod.Body = astBuilder.Build(method, inlineVariables, context);

            var                  stateMachineKind = StateMachineKind.None;
            MethodDef?           inlinedMethod    = null;
            AsyncMethodDebugInfo?asyncInfo        = null;
            string?              compilerName     = null;

            if (!(abortBeforeStep is null))
            {
                var optimizer = new ILAstOptimizer();
                optimizer.Optimize(context, ilMethod, out stateMachineKind, out inlinedMethod, out asyncInfo, abortBeforeStep.Value);
                compilerName = optimizer.CompilerName;
            }

            if (context.CurrentMethodIsYieldReturn)
            {
                output.Write("yield", BoxedTextColor.Keyword);
                output.Write(" ", BoxedTextColor.Text);
                output.WriteLine("return", BoxedTextColor.Keyword);
            }
            if (context.CurrentMethodIsAsync)
            {
                output.Write("async", BoxedTextColor.Keyword);
                output.Write("/", BoxedTextColor.Punctuation);
                output.WriteLine("await", BoxedTextColor.Keyword);
            }

            var allVariables = ilMethod.GetSelfAndChildrenRecursive <ILExpression>().Select(e => e.Operand as ILVariable)
                               .Where(v => !(v is null) && !v.IsParameter).Distinct();

            foreach (var v in allVariables)
            {
                Debug2.Assert(!(v is null));
                output.Write(IdentifierEscaper.Escape(v.Name), v.GetTextReferenceObject(), DecompilerReferenceFlags.Local | DecompilerReferenceFlags.Definition, v.IsParameter ? BoxedTextColor.Parameter : BoxedTextColor.Local);
                if (!(v.Type is null))
                {
                    output.Write(" ", BoxedTextColor.Text);
                    output.Write(":", BoxedTextColor.Punctuation);
                    output.Write(" ", BoxedTextColor.Text);
                    if (v.IsPinned)
                    {
                        output.Write("pinned", BoxedTextColor.Keyword);
                        output.Write(" ", BoxedTextColor.Text);
                    }
                    v.Type.WriteTo(output, ILNameSyntax.ShortTypeName);
                }
                if (v.GeneratedByDecompiler)
                {
                    output.Write(" ", BoxedTextColor.Text);
                    var start = output.NextPosition;
                    output.Write("[", BoxedTextColor.Punctuation);
                    output.Write("generated", BoxedTextColor.Keyword);
                    var end = output.NextPosition;
                    output.Write("]", BoxedTextColor.Punctuation);
                    output.AddBracePair(new TextSpan(start, 1), new TextSpan(end, 1), CodeBracesRangeFlags.SquareBrackets);
                }
                output.WriteLine();
            }

            var localVariables = new HashSet <ILVariable>(GetVariables(ilMethod));
            var builder        = new MethodDebugInfoBuilder(settingsVersion, stateMachineKind, inlinedMethod ?? method, !(inlinedMethod is null) ? method : null, CreateSourceLocals(localVariables), CreateSourceParameters(localVariables), asyncInfo);

            builder.CompilerName = compilerName;
            foreach (ILNode node in ilMethod.Body)
            {
                node.WriteTo(output, builder);
                if (!node.WritesNewLine)
                {
                    output.WriteLine();
                }
            }
            output.AddDebugInfo(builder.Create());
            EndKeywordBlock(output, bodyInfo, CodeBracesRangeFlags.MethodBraces, addLineSeparator: true);
        }
 public ConvertConstructorCallIntoInitializer(DecompilerContext context)
 {
     Reset(context);
 }
Beispiel #33
0
        public static void AssignNamesToVariables(DecompilerContext context, IEnumerable <ILVariable> parameters, IEnumerable <ILVariable> variables, ILBlock methodBody)
        {
            NameVariables nv = new NameVariables();

            nv.context = context;
            nv.fieldNamesInCurrentType = context.CurrentType.Fields.Select(f => f.Name).ToList();
            // First mark existing variable names as reserved.
            foreach (string name in context.ReservedVariableNames)
            {
                nv.AddExistingName(name);
            }
            foreach (var p in parameters)
            {
                nv.AddExistingName(p.Name);
            }
            foreach (var v in variables)
            {
                if (v.IsGenerated)
                {
                    // don't introduce names for variables generated by ILSpy - keep "expr"/"arg"
                    nv.AddExistingName(v.Name);
                }
                else if (v.OriginalVariable != null && context.Settings.UseDebugSymbols)
                {
                    string varName = v.OriginalVariable.Name;
                    if (string.IsNullOrEmpty(varName) || varName.StartsWith("V_", StringComparison.Ordinal) || !IsValidName(varName))
                    {
                        // don't use the name from the debug symbols if it looks like a generated name
                        v.Name = null;
                    }
                    else
                    {
                        // use the name from the debug symbols
                        // (but ensure we don't use the same name for two variables)
                        v.Name = nv.GetAlternativeName(varName);
                    }
                }
                else
                {
                    string name = v.Name.Substring(1, Math.Max(0, v.Name.IndexOf('>') - 1));
                    if (IsValidName(name))
                    {
                        v.Name = nv.GetAlternativeName(name);
                    }
                    else
                    {
                        v.Name = null;
                    }
                }
            }
            // Now generate names:
            foreach (ILVariable p in parameters)
            {
                if (string.IsNullOrEmpty(p.Name))
                {
                    p.Name = nv.GenerateNameForVariable(p, methodBody);
                }
            }
            foreach (ILVariable varDef in variables)
            {
                if (string.IsNullOrEmpty(varDef.Name))
                {
                    varDef.Name = nv.GenerateNameForVariable(varDef, methodBody);
                }
            }
        }
Beispiel #34
0
        void Run(Config config)
        {
            if (config.ShowHelp)
            {
                Console.WriteLine("Netjs compiler, Copyright 2014 Frank A. Krueger");
                Console.WriteLine("netjs [options] assembly-file");
                Console.WriteLine("   -help                Lists all compiler options (short: -?)");
                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");
        }
Beispiel #35
0
        public static void RunTransformationsUntil(AstNode node, Predicate <IAstTransform> abortCondition, DecompilerContext context)
        {
            if (node == null)
            {
                return;
            }

            foreach (var transform in CreatePipeline(context))
            {
                context.CancellationToken.ThrowIfCancellationRequested();
                if (abortCondition != null && abortCondition(transform))
                {
                    return;
                }
                transform.Run(node);
            }
        }
Beispiel #36
0
 public void Initialize(DecompilerContext context)
 {
     this.context = context;
     this.labelToCfNode.Clear();
     this.nextLabelIndex = 0;
 }
 public IntroduceExtensionMethods(DecompilerContext context)
 {
     this.context = context;
 }
Beispiel #38
0
 private ExpressionTreeConverter(DecompilerContext context, StringBuilder sb)
 {
     this.context       = context;
     this.stringBuilder = sb;
 }
Beispiel #39
0
 public DelegateConstruction(DecompilerContext context) : base(context)
 {
 }
Beispiel #40
0
        bool HandleAnonymousMethod(ObjectCreateExpression objectCreateExpression, Expression target, MethodReference methodRef)
        {
            if (!context.Settings.AnonymousMethods)
            {
                return(false);                // anonymous method decompilation is disabled
            }
            if (target != null && !(target is IdentifierExpression || target is ThisReferenceExpression || target is NullReferenceExpression))
            {
                return(false);                // don't copy arbitrary expressions, deal with identifiers only
            }
            // Anonymous methods are defined in the same assembly
            MethodDefinition method = methodRef.ResolveWithinSameModule();

            if (!IsAnonymousMethod(context, method))
            {
                return(false);
            }

            // Create AnonymousMethodExpression and prepare parameters
            AnonymousMethodExpression ame = new AnonymousMethodExpression();

            ame.CopyAnnotationsFrom(objectCreateExpression); // copy ILRanges etc.
            ame.RemoveAnnotations <MethodReference>();       // remove reference to delegate ctor
            ame.AddAnnotation(method);                       // add reference to anonymous method
            ame.Parameters.AddRange(AstBuilder.MakeParameters(method, isLambda: true));
            ame.HasParameterList = true;

            // rename variables so that they don't conflict with the parameters:
            foreach (ParameterDeclaration pd in ame.Parameters)
            {
                EnsureVariableNameIsAvailable(objectCreateExpression, pd.Name);
            }

            // Decompile the anonymous method:

            DecompilerContext subContext = context.Clone();

            subContext.CurrentMethod        = method;
            subContext.CurrentMethodIsAsync = false;
            subContext.ReservedVariableNames.AddRange(currentlyUsedVariableNames);
            BlockStatement body = AstMethodBodyBuilder.CreateMethodBody(method, subContext, ame.Parameters);

            TransformationPipeline.RunTransformationsUntil(body, v => v is DelegateConstruction, subContext);
            body.AcceptVisitor(this, null);


            bool isLambda = false;

            if (ame.Parameters.All(p => p.ParameterModifier == ParameterModifier.None))
            {
                isLambda = (body.Statements.Count == 1 && body.Statements.Single() is ReturnStatement);
            }
            // Remove the parameter list from an AnonymousMethodExpression if the original method had no names,
            // and the parameters are not used in the method body
            if (!isLambda && method.Parameters.All(p => string.IsNullOrEmpty(p.Name)))
            {
                var parameterReferencingIdentifiers =
                    from ident in body.Descendants.OfType <IdentifierExpression>()
                    let v = ident.Annotation <ILVariable>()
                            where v != null && v.IsParameter && method.Parameters.Contains(v.OriginalParameter)
                            select ident;
                if (!parameterReferencingIdentifiers.Any())
                {
                    ame.Parameters.Clear();
                    ame.HasParameterList = false;
                }
            }

            // Replace all occurrences of 'this' in the method body with the delegate's target:
            foreach (AstNode node in body.Descendants)
            {
                if (node is ThisReferenceExpression)
                {
                    node.ReplaceWith(target.Clone());
                }
            }
            Expression replacement;

            if (isLambda)
            {
                LambdaExpression lambda = new LambdaExpression();
                lambda.CopyAnnotationsFrom(ame);
                ame.Parameters.MoveTo(lambda.Parameters);
                Expression returnExpr = ((ReturnStatement)body.Statements.Single()).Expression;
                returnExpr.Remove();
                lambda.Body = returnExpr;
                replacement = lambda;
            }
            else
            {
                ame.Body    = body;
                replacement = ame;
            }
            var expectedType = objectCreateExpression.Annotation <TypeInformation>().ExpectedType.Resolve();

            if (expectedType != null && !expectedType.IsDelegate())
            {
                var simplifiedDelegateCreation = (ObjectCreateExpression)objectCreateExpression.Clone();
                simplifiedDelegateCreation.Arguments.Clear();
                simplifiedDelegateCreation.Arguments.Add(replacement);
                replacement = simplifiedDelegateCreation;
            }
            objectCreateExpression.ReplaceWith(replacement);
            return(true);
        }
Beispiel #41
0
        public override void Decompile(MethodDef method, ITextOutput output, DecompilationContext ctx)
        {
            WriteCommentBegin(output, true);
            output.Write("Method: ", TextTokenKind.Comment);
            output.WriteDefinition(IdentifierEscaper.Escape(method.FullName), method, TextTokenKind.Comment, false);
            WriteCommentEnd(output, true);
            output.WriteLine();

            if (!method.HasBody)
            {
                return;
            }

            StartKeywordBlock(output, ".body", method);

            ILAstBuilder      astBuilder = new ILAstBuilder();
            ILBlock           ilMethod   = new ILBlock();
            DecompilerContext context    = new DecompilerContext(method.Module)
            {
                CurrentType = method.DeclaringType, CurrentMethod = method
            };

            ilMethod.Body = astBuilder.Build(method, inlineVariables, context);

            if (abortBeforeStep != null)
            {
                new ILAstOptimizer().Optimize(context, ilMethod, abortBeforeStep.Value);
            }

            if (context.CurrentMethodIsAsync)
            {
                output.Write("async", TextTokenKind.Keyword);
                output.Write("/", TextTokenKind.Operator);
                output.WriteLine("await", TextTokenKind.Keyword);
            }

            var allVariables = ilMethod.GetSelfAndChildrenRecursive <ILExpression>().Select(e => e.Operand as ILVariable)
                               .Where(v => v != null && !v.IsParameter).Distinct();

            foreach (ILVariable v in allVariables)
            {
                output.WriteDefinition(IdentifierEscaper.Escape(v.Name), v, v.IsParameter ? TextTokenKind.Parameter : TextTokenKind.Local);
                if (v.Type != null)
                {
                    output.WriteSpace();
                    output.Write(":", TextTokenKind.Operator);
                    output.WriteSpace();
                    if (v.IsPinned)
                    {
                        output.Write("pinned", TextTokenKind.Keyword);
                        output.WriteSpace();
                    }
                    v.Type.WriteTo(output, ILNameSyntax.ShortTypeName);
                }
                if (v.GeneratedByDecompiler)
                {
                    output.WriteSpace();
                    output.Write("[", TextTokenKind.Operator);
                    output.Write("generated", TextTokenKind.Keyword);
                    output.Write("]", TextTokenKind.Operator);
                }
                output.WriteLine();
            }

            var memberMapping = new MemberMapping(method);

            foreach (ILNode node in ilMethod.Body)
            {
                node.WriteTo(output, memberMapping);
                if (!node.WritesNewLine)
                {
                    output.WriteLine();
                }
            }
            output.AddDebugSymbols(memberMapping);
            EndKeywordBlock(output);
        }
Beispiel #42
0
        Dictionary <int, Action <XamlContext, XElement> > ExtractConnectionId(XamlContext ctx, MethodDef method)
        {
            var context = new DecompilerContext(method.Module)
            {
                CurrentType       = method.DeclaringType,
                CurrentMethod     = method,
                CancellationToken = ctx.CancellationToken
            };
            var body = new ILBlock(new ILAstBuilder().Build(method, true, context));

            new ILAstOptimizer().Optimize(context, body);

            var sw = body.GetSelfAndChildrenRecursive <ILSwitch>().FirstOrDefault();

            if (sw == null)
            {
                return(null);
            }

            var connIds = new Dictionary <int, Action <XamlContext, XElement> >();

            foreach (var cas in sw.CaseBlocks)
            {
                if (cas.Values == null)
                {
                    continue;
                }

                Action <XamlContext, XElement> cb = null;
                foreach (var node in cas.Body)
                {
                    var expr = node as ILExpression;
                    if (expr == null)
                    {
                        continue;
                    }

                    switch (expr.Code)
                    {
                    case ILCode.Stfld:
                        cb += new FieldAssignment {
                            FieldName = ((IField)expr.Operand).Name
                        }.Callback;
                        break;

                    case ILCode.Call:
                    case ILCode.Callvirt:
                        var operand = (IMethod)expr.Operand;
                        if (operand.Name == "AddHandler" && operand.DeclaringType.FullName == "System.Windows.UIElement")
                        {
                            // Attached event
                            var re      = expr.Arguments[1];
                            var ctor    = expr.Arguments[2];
                            var reField = re.Operand as IField;

                            if (re.Code != ILCode.Ldsfld || ctor.Code != ILCode.Newobj ||
                                ctor.Arguments.Count != 2 || ctor.Arguments[1].Code != ILCode.Ldftn)
                            {
                                cb += new Error {
                                    Msg = string.Format(dnSpy_BamlDecompiler_Resources.Error_AttachedEvent, reField.Name)
                                }.Callback;
                                break;
                            }
                            var    handler = (IMethod)ctor.Arguments[1].Operand;
                            string evName  = reField.Name;
                            if (evName.EndsWith("Event"))
                            {
                                evName = evName.Substring(0, evName.Length - 5);
                            }

                            cb += new EventAttachment {
                                AttachedType = reField.DeclaringType.ResolveTypeDefThrow(),
                                EventName    = evName,
                                MethodName   = handler.Name
                            }.Callback;
                        }
                        else
                        {
                            // CLR event
                            var add = operand.ResolveMethodDefThrow();
                            var ev  = add.DeclaringType.Events.FirstOrDefault(e => e.AddMethod == add);

                            var ctor = expr.Arguments[1];
                            if (ev == null || ctor.Code != ILCode.Newobj ||
                                ctor.Arguments.Count != 2 || ctor.Arguments[1].Code != ILCode.Ldftn)
                            {
                                cb += new Error {
                                    Msg = string.Format(dnSpy_BamlDecompiler_Resources.Error_AttachedEvent, add.Name)
                                }.Callback;
                                break;
                            }
                            var handler = (IMethod)ctor.Arguments[1].Operand;

                            cb += new EventAttachment {
                                EventName  = ev.Name,
                                MethodName = handler.Name
                            }.Callback;
                        }
                        break;
                    }
                }

                if (cb != null)
                {
                    foreach (var id in cas.Values)
                    {
                        connIds[id] = cb;
                    }
                }
            }

            return(connIds.Count == 0 ? null : connIds);
        }
Beispiel #43
0
 public CombineQueryExpressions(DecompilerContext context)
 {
     this.context = context;
 }
Beispiel #44
0
        private static bool ProcessStatement(Statement general, Dictionary <int, HashSet <int
                                                                                          > > mapExtPost)
        {
            if (general.type == Statement.Type_Root)
            {
                Statement stat = general.GetFirst();
                if (stat.type != Statement.Type_General)
                {
                    return(true);
                }
                else
                {
                    bool complete = ProcessStatement(stat, mapExtPost);
                    if (complete)
                    {
                        // replace general purpose statement with simple one
                        general.ReplaceStatement(stat, stat.GetFirst());
                    }
                    return(complete);
                }
            }
            bool mapRefreshed = (mapExtPost.Count == 0);

            for (int mapstage = 0; mapstage < 2; mapstage++)
            {
                for (int reducibility = 0; reducibility < 5; reducibility++)
                {
                    // FIXME: implement proper node splitting. For now up to 5 nodes in sequence are splitted.
                    if (reducibility > 0)
                    {
                        //					try {
                        //						DotExporter.toDotFile(general, new File("c:\\Temp\\stat1.dot"));
                        //					} catch(Exception ex) {ex.printStackTrace();}
                        // take care of irreducible control flow graphs
                        if (IrreducibleCFGDeobfuscator.IsStatementIrreducible(general))
                        {
                            if (!IrreducibleCFGDeobfuscator.SplitIrreducibleNode(general))
                            {
                                DecompilerContext.GetLogger().WriteMessage("Irreducible statement cannot be decomposed!"
                                                                           , IFernflowerLogger.Severity.Error);
                                break;
                            }
                        }
                        else
                        {
                            if (mapstage == 2 || mapRefreshed)
                            {
                                // last chance lost
                                DecompilerContext.GetLogger().WriteMessage("Statement cannot be decomposed although reducible!"
                                                                           , IFernflowerLogger.Severity.Error);
                            }
                            break;
                        }
                        //					try {
                        //						DotExporter.toDotFile(general, new File("c:\\Temp\\stat1.dot"));
                        //					} catch(Exception ex) {ex.printStackTrace();}
                        mapExtPost   = new Dictionary <int, HashSet <int> >();
                        mapRefreshed = true;
                    }
                    for (int i = 0; i < 2; i++)
                    {
                        bool forceall = i != 0;
                        while (true)
                        {
                            if (FindSimpleStatements(general, mapExtPost))
                            {
                                reducibility = 0;
                            }
                            if (general.type == Statement.Type_Placeholder)
                            {
                                return(true);
                            }
                            Statement stat = FindGeneralStatement(general, forceall, mapExtPost);
                            if (stat != null)
                            {
                                bool complete = ProcessStatement(stat, general.GetFirst() == stat ? mapExtPost :
                                                                 new Dictionary <int, HashSet <int> >());
                                if (complete)
                                {
                                    // replace general purpose statement with simple one
                                    general.ReplaceStatement(stat, stat.GetFirst());
                                }
                                else
                                {
                                    return(false);
                                }
                                mapExtPost   = new Dictionary <int, HashSet <int> >();
                                mapRefreshed = true;
                                reducibility = 0;
                            }
                            else
                            {
                                break;
                            }
                        }
                    }
                }
                //				try {
                //					DotExporter.toDotFile(general, new File("c:\\Temp\\stat1.dot"));
                //				} catch (Exception ex) {
                //					ex.printStackTrace();
                //				}
                if (mapRefreshed)
                {
                    break;
                }
                else
                {
                    mapExtPost = new Dictionary <int, HashSet <int> >();
                }
            }
            return(false);
        }
Beispiel #45
0
 public LoopsAndConditions(DecompilerContext context)
 {
     Initialize(context);
 }
        /// <summary>
        /// Optimize expressions
        /// </summary>
        public static void Convert(DecompilerContext context, AstBlock ast, AssemblyCompiler compiler)
        {
            // Convert stobj/stind_ref
            foreach (var node in ast.GetExpressions(x => (x.Arguments.Count == 2) && ((x.Code == AstCode.Stobj) || (x.Code == AstCode.Stind_Ref))))
            {
                var addrNode  = node.Arguments[0];
                var valueNode = node.Arguments[1];

                AstVariable variable;
                if ((addrNode.GetResultType().IsByReference) && addrNode.Match(AstCode.Ldloc, out variable))
                {
                    if (variable.IsThis && valueNode.Match(AstCode.DefaultValue))
                    {
                        // Struct init : this()
                        node.CopyFrom(new AstExpression(node.SourceLocation, AstCode.Nop, null));
                    }
                    else if (!variable.IsThis)
                    {
                        // Convert byref type to array type
                        var addrType  = (XByReferenceType)addrNode.GetResultType();
                        var arrayType = new XArrayType(addrType.ElementType);
                        addrNode.ExpectedType = arrayType;
                        addrNode.InferredType = arrayType;

                        // Convert to stelem array, index, value
                        var int32Type = compiler.Module.TypeSystem.Int;
                        node.Arguments.Insert(1, new AstExpression(node.SourceLocation, AstCode.Ldc_I4, 0).SetType(int32Type));
                        node.Code = arrayType.ElementType.GetStElemCode();
                    }
                    else
                    {
                        // Convert to stloc
                    }
                }
            }

            // Convert ldobj
            var resetTypes = false;
            var processed  = new HashSet <AstExpression>();

            foreach (var pair in ast.GetExpressionPairs())
            {
                var node = pair.Expression;
                if ((node.Arguments.Count == 1) && ((node.Code == AstCode.Ldobj) || (node.Code == AstCode.Ldind_Ref)))
                {
                    var parent         = pair.Parent;
                    var useAsValue     = true;
                    var isCallArgument = (parent != null) && (parent.Code.IsCall());
                    var isBoxArgument  = (parent != null) && (parent.Match(AstCode.Box));
                    if (isCallArgument && (node.Code == AstCode.Ldobj))
                    {
                        if (IsArgByRefOrOut(node, parent))
                        {
                            useAsValue = false;
                        }
                    }

                    if (isBoxArgument)
                    {
                        var boxType = (XTypeReference)parent.Operand;
                        if (!boxType.IsGenericParameter)
                        {
                            useAsValue = false;
                        }
                    }

                    var ldlocNode = node.Arguments[0];
                    processed.Add(ldlocNode);
                    var addrNodeType = ldlocNode.GetResultType();

                    if (ldlocNode.MatchThis())
                    {
                        useAsValue = false;
                    }

                    if (useAsValue)
                    {
                        if ((addrNodeType.IsByReference) && (ldlocNode.Code == AstCode.Ldloc))
                        {
                            // Convert byref type to array type
                            var addrType  = (XByReferenceType)ldlocNode.GetResultType();
                            var arrayType = new XArrayType(addrType.ElementType);
                            ldlocNode.ExpectedType = arrayType;
                            ldlocNode.InferredType = arrayType;

                            // Convert to ldelem array, index, value
                            var int32Type = compiler.Module.TypeSystem.Int;
                            node.Arguments.Insert(1, new AstExpression(node.SourceLocation, AstCode.Ldc_I4, 0).SetType(int32Type));
                            node.Code = arrayType.ElementType.GetLdElemCode();
                            node.SetType(arrayType.ElementType);
                            resetTypes = true;
                        }
                    }
                    else if (isCallArgument && (ldlocNode.Code == AstCode.Ldloc))
                    {
                        var             typeRef = (XTypeReference)node.Operand;
                        XTypeDefinition typeDef;
                        if ((typeRef != null) && typeRef.TryResolve(out typeDef) && typeDef.IsValueType &&
                            !typeDef.IsPrimitive)
                        {
                            // Replace by ldloc
                            node.Code    = AstCode.Ldloc;
                            node.Operand = ldlocNode.Operand;
                            node.Arguments.Clear();
                        }
                    }
                }
                else if ((node.Code == AstCode.Ldloc) && ((AstVariable)node.Operand).IsParameter && (node.GetResultType().IsByReference))
                {
                    var parent = pair.Parent;
                    if ((parent != null) && (parent.Code == AstCode.Ldobj))
                    {
                        continue;
                    }
                    var useAsValue     = true;
                    var isCallArgument = (parent != null) && (parent.Code.IsCall());
                    var isBoxArgument  = (parent != null) && (parent.Match(AstCode.Box));
                    if (isCallArgument)
                    {
                        if (IsArgByRefOrOut(node, parent))
                        {
                            useAsValue = false;
                        }
                    }

                    if (isBoxArgument)
                    {
                        useAsValue = false;
                    }

                    if (node.MatchThis())
                    {
                        useAsValue = false;
                    }

                    if (useAsValue)
                    {
                        // Convert byref type to array type
                        var addrType  = (XByReferenceType)node.GetResultType();
                        var arrayType = new XArrayType(addrType.ElementType);
                        var clone     = new AstExpression(node).SetType(arrayType);

                        // Convert to ldelem array, index, value
                        var int32Type = compiler.Module.TypeSystem.Int;
                        node.SetArguments(clone, new AstExpression(node.SourceLocation, AstCode.Ldc_I4, 0).SetType(int32Type));
                        node.Code = arrayType.ElementType.GetLdElemCode();
                        node.SetType(arrayType.ElementType);
                        resetTypes = true;
                    }
                }
            }

            if (resetTypes)
            {
                TypeAnalysis.Run(context, ast);
            }
        }
Beispiel #47
0
        public bool Compile()
        {
            LogLine(1, "Compiling Xaml");
            LogLine(1, "\nAssembly: {0}", Assembly);
            if (!string.IsNullOrEmpty(DependencyPaths))
            {
                LogLine(1, "DependencyPaths: \t{0}", DependencyPaths);
            }
            if (!string.IsNullOrEmpty(ReferencePath))
            {
                LogLine(1, "ReferencePath: \t{0}", ReferencePath.Replace("//", "/"));
            }
            LogLine(3, "DebugSymbols:\"{0}\"", DebugSymbols);
            var  skipassembly = true;            //change this to false to enable XamlC by default
            bool success      = true;

            if (!File.Exists(Assembly))
            {
                LogLine(1, "Assembly file not found. Skipping XamlC.");
                return(true);
            }

            var resolver = new XamlCAssemblyResolver();

            if (!string.IsNullOrEmpty(DependencyPaths))
            {
                foreach (var dep in DependencyPaths.Split(';'))
                {
                    LogLine(3, "Adding searchpath {0}", dep);
                    resolver.AddSearchDirectory(dep);
                }
            }

            if (!string.IsNullOrEmpty(ReferencePath))
            {
                var paths = ReferencePath.Replace("//", "/").Split(';');
                foreach (var p in paths)
                {
                    var searchpath = Path.GetDirectoryName(p);
                    LogLine(3, "Adding searchpath {0}", searchpath);
                    resolver.AddSearchDirectory(searchpath);
                    //					LogLine (3, "Referencing {0}", p);
                    //					resolver.AddAssembly (p);
                }
            }

            var assemblyDefinition = AssemblyDefinition.ReadAssembly(Path.GetFullPath(Assembly), new ReaderParameters
            {
                AssemblyResolver = resolver,
                ReadSymbols      = DebugSymbols
            });

            CustomAttribute xamlcAttr;

            if (assemblyDefinition.HasCustomAttributes &&
                (xamlcAttr =
                     assemblyDefinition.CustomAttributes.FirstOrDefault(
                         ca => ca.AttributeType.FullName == "Xamarin.Forms.Xaml.XamlCompilationAttribute")) != null)
            {
                var options = (XamlCompilationOptions)xamlcAttr.ConstructorArguments[0].Value;
                if ((options & XamlCompilationOptions.Skip) == XamlCompilationOptions.Skip)
                {
                    skipassembly = true;
                }
                if ((options & XamlCompilationOptions.Compile) == XamlCompilationOptions.Compile)
                {
                    skipassembly = false;
                }
            }

            foreach (var module in assemblyDefinition.Modules)
            {
                var skipmodule = skipassembly;
                if (module.HasCustomAttributes &&
                    (xamlcAttr =
                         module.CustomAttributes.FirstOrDefault(
                             ca => ca.AttributeType.FullName == "Xamarin.Forms.Xaml.XamlCompilationAttribute")) != null)
                {
                    var options = (XamlCompilationOptions)xamlcAttr.ConstructorArguments[0].Value;
                    if ((options & XamlCompilationOptions.Skip) == XamlCompilationOptions.Skip)
                    {
                        skipmodule = true;
                    }
                    if ((options & XamlCompilationOptions.Compile) == XamlCompilationOptions.Compile)
                    {
                        skipmodule = false;
                    }
                }

                LogLine(2, " Module: {0}", module.Name);
                var resourcesToPrune = new List <EmbeddedResource>();
                foreach (var resource in module.Resources.OfType <EmbeddedResource>())
                {
                    LogString(2, "  Resource: {0}... ", resource.Name);
                    string classname;
                    if (!resource.IsXaml(out classname))
                    {
                        LogLine(2, "skipped.");
                        continue;
                    }
                    TypeDefinition typeDef = module.GetType(classname);
                    if (typeDef == null)
                    {
                        LogLine(2, "no type found... skipped.");
                        continue;
                    }
                    var skiptype = skipmodule;
                    if (typeDef.HasCustomAttributes &&
                        (xamlcAttr =
                             typeDef.CustomAttributes.FirstOrDefault(
                                 ca => ca.AttributeType.FullName == "Xamarin.Forms.Xaml.XamlCompilationAttribute")) != null)
                    {
                        var options = (XamlCompilationOptions)xamlcAttr.ConstructorArguments[0].Value;
                        if ((options & XamlCompilationOptions.Skip) == XamlCompilationOptions.Skip)
                        {
                            skiptype = true;
                        }
                        if ((options & XamlCompilationOptions.Compile) == XamlCompilationOptions.Compile)
                        {
                            skiptype = false;
                        }
                    }
                    if (skiptype)
                    {
                        LogLine(2, "Has XamlCompilationAttribute set to Skip and not Compile... skipped");
                        continue;
                    }

                    var initComp = typeDef.Methods.FirstOrDefault(md => md.Name == "InitializeComponent");
                    if (initComp == null)
                    {
                        LogLine(2, "no InitializeComponent found... skipped.");
                        continue;
                    }
                    LogLine(2, "");

                    var initCompRuntime = typeDef.Methods.FirstOrDefault(md => md.Name == "__InitComponentRuntime");
                    if (initCompRuntime != null)
                    {
                        LogLine(2, "   __InitComponentRuntime already exists... not duplicating");
                    }
                    else
                    {
                        LogString(2, "   Duplicating {0}.InitializeComponent () into {0}.__InitComponentRuntime ... ", typeDef.Name);
                        initCompRuntime = DuplicateMethodDef(typeDef, initComp, "__InitComponentRuntime");
                        LogLine(2, "done.");
                    }

                    LogString(2, "   Parsing Xaml... ");
                    var rootnode = ParseXaml(resource.GetResourceStream(), typeDef);
                    if (rootnode == null)
                    {
                        LogLine(2, "failed.");
                        continue;
                    }
                    LogLine(2, "done.");

                    hasCompiledXamlResources = true;

                    try
                    {
                        LogString(2, "   Replacing {0}.InitializeComponent ()... ", typeDef.Name);
                        var body = new MethodBody(initComp);
                        var il   = body.GetILProcessor();
                        il.Emit(OpCodes.Nop);

                        // Generating branching code for the Previewer
                        //	IL_0007:  call class [mscorlib]System.Func`2<class [mscorlib]System.Type,string> class [Xamarin.Forms.Xaml.Internals]Xamarin.Forms.Xaml.XamlLoader::get_XamlFileProvider()
                        //  IL_000c:  brfalse IL_0031
                        //  IL_0011:  call class [mscorlib]System.Func`2<class [mscorlib]System.Type,string> class [Xamarin.Forms.Xaml.Internals]Xamarin.Forms.Xaml.XamlLoader::get_XamlFileProvider()
                        //  IL_0016:  ldarg.0
                        //  IL_0017:  call instance class [mscorlib]System.Type object::GetType()
                        //  IL_001c:  callvirt instance !1 class [mscorlib]System.Func`2<class [mscorlib]System.Type, string>::Invoke(!0)
                        //  IL_0021:  brfalse IL_0031
                        //  IL_0026:  ldarg.0
                        //  IL_0027:  call instance void class Xamarin.Forms.Xaml.UnitTests.XamlLoaderGetXamlForTypeTests::__InitComponentRuntime()
                        //  IL_002c:  ret
                        //  IL_0031:  nop

                        var nop = Instruction.Create(OpCodes.Nop);
                        var getXamlFileProvider = body.Method.Module.Import(body.Method.Module.Import(typeof(Xamarin.Forms.Xaml.Internals.XamlLoader))
                                                                            .Resolve()
                                                                            .Properties.FirstOrDefault(pd => pd.Name == "XamlFileProvider")
                                                                            .GetMethod);
                        il.Emit(OpCodes.Call, getXamlFileProvider);
                        il.Emit(OpCodes.Brfalse, nop);
                        il.Emit(OpCodes.Call, getXamlFileProvider);
                        il.Emit(OpCodes.Ldarg_0);
                        var getType = body.Method.Module.Import(body.Method.Module.Import(typeof(object))
                                                                .Resolve()
                                                                .Methods.FirstOrDefault(md => md.Name == "GetType"));
                        il.Emit(OpCodes.Call, getType);
                        var func = body.Method.Module.Import(body.Method.Module.Import(typeof(Func <Type, string>))
                                                             .Resolve()
                                                             .Methods.FirstOrDefault(md => md.Name == "Invoke"));
                        func = func.ResolveGenericParameters(body.Method.Module.Import(typeof(Func <Type, string>)), body.Method.Module);
                        il.Emit(OpCodes.Callvirt, func);
                        il.Emit(OpCodes.Brfalse, nop);
                        il.Emit(OpCodes.Ldarg_0);
                        il.Emit(OpCodes.Call, initCompRuntime);
                        il.Emit(OpCodes.Ret);
                        il.Append(nop);

                        var visitorContext = new ILContext(il, body);

                        rootnode.Accept(new XamlNodeVisitor((node, parent) => node.Parent = parent), null);
                        rootnode.Accept(new ExpandMarkupsVisitor(visitorContext), null);
                        rootnode.Accept(new PruneIgnoredNodesVisitor(), null);
                        rootnode.Accept(new CreateObjectVisitor(visitorContext), null);
                        rootnode.Accept(new SetNamescopesAndRegisterNamesVisitor(visitorContext), null);
                        rootnode.Accept(new SetFieldVisitor(visitorContext), null);
                        rootnode.Accept(new SetResourcesVisitor(visitorContext), null);
                        rootnode.Accept(new SetPropertiesVisitor(visitorContext, true), null);

                        il.Emit(OpCodes.Ret);
                        initComp.Body = body;
                    }
                    catch (XamlParseException xpe)
                    {
                        LogLine(2, "failed.");
                        LogError(null, null, null, resource.Name, xpe.XmlInfo.LineNumber, xpe.XmlInfo.LinePosition, 0, 0, xpe.Message,
                                 xpe.HelpLink, xpe.Source);
                        LogLine(4, xpe.StackTrace);
                        success = false;
                        continue;
                    }
                    catch (XmlException xe)
                    {
                        LogLine(2, "failed.");
                        LogError(null, null, null, resource.Name, xe.LineNumber, xe.LinePosition, 0, 0, xe.Message, xe.HelpLink, xe.Source);
                        LogLine(4, xe.StackTrace);
                        success = false;
                        continue;
                    }
                    catch (Exception e)
                    {
                        LogLine(2, "failed.");
                        LogError(null, null, null, resource.Name, 0, 0, 0, 0, e.Message, e.HelpLink, e.Source);
                        LogLine(4, e.StackTrace);
                        success = false;
                        continue;
                    }
                    LogLine(2, "done.");

                    if (OptimizeIL)
                    {
                        LogString(2, "   Optimizing IL... ");
                        initComp.Body.OptimizeMacros();
                        LogLine(2, "done");
                    }

                    if (OutputGeneratedILAsCode)
                    {
                        var filepath = Path.Combine(Path.GetDirectoryName(Assembly), typeDef.FullName + ".decompiled.cs");
                        LogString(2, "   Decompiling {0} into {1}...", typeDef.FullName, filepath);
                        var decompilerContext = new DecompilerContext(module);
                        using (var writer = new StreamWriter(filepath))
                        {
                            var output = new PlainTextOutput(writer);

                            var codeDomBuilder = new AstBuilder(decompilerContext);
                            codeDomBuilder.AddType(typeDef);
                            codeDomBuilder.GenerateCode(output);
                        }

                        LogLine(2, "done");
                    }
                    resourcesToPrune.Add(resource);
                }
                if (!KeepXamlResources)
                {
                    if (resourcesToPrune.Any())
                    {
                        LogLine(2, "  Removing compiled xaml resources");
                    }
                    foreach (var resource in resourcesToPrune)
                    {
                        LogString(2, "   Removing {0}... ", resource.Name);
                        module.Resources.Remove(resource);
                        LogLine(2, "done");
                    }
                }

                LogLine(2, "");
            }

            if (!hasCompiledXamlResources)
            {
                LogLine(1, "No compiled resources. Skipping writing assembly.");
                return(success);
            }

            LogString(1, "Writing the assembly... ");
            try
            {
                assemblyDefinition.Write(Assembly, new WriterParameters
                {
                    WriteSymbols = DebugSymbols
                });
                LogLine(1, "done.");
            }
            catch (Exception e)
            {
                LogLine(1, "failed.");
                LogError(null, null, null, null, 0, 0, 0, 0, e.Message, e.HelpLink, e.Source);
                LogLine(4, e.StackTrace);
                success = false;
            }

            return(success);
        }
Beispiel #48
0
        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");
        }
Beispiel #49
0
 public AstOptimizer(DecompilerContext context, AstBlock method)
 {
     this.context = context;
     this.method  = method;
 }
Beispiel #50
0
        public void Optimize(DecompilerContext context, ILBlock method, ILAstOptimizationStep abortBeforeStep = ILAstOptimizationStep.None)
        {
            this.context    = context;
            this.typeSystem = context.CurrentMethod.Module.TypeSystem;
            this.method     = method;

            if (abortBeforeStep == ILAstOptimizationStep.RemoveRedundantCode)
            {
                return;
            }
            RemoveRedundantCode(method);

            if (abortBeforeStep == ILAstOptimizationStep.ReduceBranchInstructionSet)
            {
                return;
            }
            foreach (ILBlock block in method.GetSelfAndChildrenRecursive <ILBlock>())
            {
                ReduceBranchInstructionSet(block);
            }
            // ReduceBranchInstructionSet runs before inlining because the non-aggressive inlining heuristic
            // looks at which type of instruction consumes the inlined variable.

            if (abortBeforeStep == ILAstOptimizationStep.InlineVariables)
            {
                return;
            }
            // Works better after simple goto removal because of the following debug pattern: stloc X; br Next; Next:; ldloc X
            ILInlining inlining1 = new ILInlining(method);

            inlining1.InlineAllVariables();

            if (abortBeforeStep == ILAstOptimizationStep.CopyPropagation)
            {
                return;
            }
            inlining1.CopyPropagation();

            if (abortBeforeStep == ILAstOptimizationStep.YieldReturn)
            {
                return;
            }
            YieldReturnDecompiler.Run(context, method);
            AsyncDecompiler.RunStep1(context, method);

            if (abortBeforeStep == ILAstOptimizationStep.AsyncAwait)
            {
                return;
            }
            AsyncDecompiler.RunStep2(context, method);

            //if (abortBeforeStep == ILAstOptimizationStep.PropertyAccessInstructions) return;
            //IntroducePropertyAccessInstructions(method);

            if (abortBeforeStep == ILAstOptimizationStep.SplitToMovableBlocks)
            {
                return;
            }
            foreach (ILBlock block in method.GetSelfAndChildrenRecursive <ILBlock>())
            {
                SplitToBasicBlocks(block);
            }

            if (abortBeforeStep == ILAstOptimizationStep.TypeInference)
            {
                return;
            }
            // Types are needed for the ternary operator optimization
            TypeAnalysis.Run(context, method);

            foreach (ILBlock block in method.GetSelfAndChildrenRecursive <ILBlock>())
            {
                bool modified;
                do
                {
                    modified = false;

                    if (abortBeforeStep == ILAstOptimizationStep.SimplifyShortCircuit)
                    {
                        return;
                    }
                    modified |= block.RunOptimization(new SimpleControlFlow(context, method).SimplifyShortCircuit);

                    if (abortBeforeStep == ILAstOptimizationStep.SimplifyTernaryOperator)
                    {
                        return;
                    }
                    modified |= block.RunOptimization(new SimpleControlFlow(context, method).SimplifyTernaryOperator);

                    if (abortBeforeStep == ILAstOptimizationStep.SimplifyNullCoalescing)
                    {
                        return;
                    }
                    modified |= block.RunOptimization(new SimpleControlFlow(context, method).SimplifyNullCoalescing);

                    if (abortBeforeStep == ILAstOptimizationStep.JoinBasicBlocks)
                    {
                        return;
                    }
                    modified |= block.RunOptimization(new SimpleControlFlow(context, method).JoinBasicBlocks);

                    if (abortBeforeStep == ILAstOptimizationStep.SimplifyLogicNot)
                    {
                        return;
                    }
                    modified |= block.RunOptimization(SimplifyLogicNot);

                    if (abortBeforeStep == ILAstOptimizationStep.SimplifyShiftOperators)
                    {
                        return;
                    }
                    modified |= block.RunOptimization(SimplifyShiftOperators);

                    if (abortBeforeStep == ILAstOptimizationStep.TypeConversionSimplifications)
                    {
                        return;
                    }
                    modified |= block.RunOptimization(TypeConversionSimplifications);

                    if (abortBeforeStep == ILAstOptimizationStep.SimplifyLdObjAndStObj)
                    {
                        return;
                    }
                    modified |= block.RunOptimization(SimplifyLdObjAndStObj);

                    if (abortBeforeStep == ILAstOptimizationStep.SimplifyCustomShortCircuit)
                    {
                        return;
                    }
                    modified |= block.RunOptimization(new SimpleControlFlow(context, method).SimplifyCustomShortCircuit);

                    if (abortBeforeStep == ILAstOptimizationStep.SimplifyLiftedOperators)
                    {
                        return;
                    }
                    modified |= block.RunOptimization(SimplifyLiftedOperators);

                    //if (abortBeforeStep == ILAstOptimizationStep.TransformArrayInitializers) return;
                    //modified |= block.RunOptimization(TransformArrayInitializers);

                    //if (abortBeforeStep == ILAstOptimizationStep.TransformMultidimensionalArrayInitializers) return;
                    //modified |= block.RunOptimization(TransformMultidimensionalArrayInitializers);

                    //if (abortBeforeStep == ILAstOptimizationStep.TransformObjectInitializers) return;
                    //modified |= block.RunOptimization(TransformObjectInitializers);

                    if (abortBeforeStep == ILAstOptimizationStep.MakeAssignmentExpression)
                    {
                        return;
                    }
                    modified |= block.RunOptimization(MakeAssignmentExpression);
                    modified |= block.RunOptimization(MakeCompoundAssignments);

                    if (abortBeforeStep == ILAstOptimizationStep.IntroducePostIncrement)
                    {
                        return;
                    }
                    modified |= block.RunOptimization(IntroducePostIncrement);

                    if (abortBeforeStep == ILAstOptimizationStep.InlineExpressionTreeParameterDeclarations)
                    {
                        return;
                    }
                    if (context.Settings.ExpressionTrees)
                    {
                        modified |= block.RunOptimization(InlineExpressionTreeParameterDeclarations);
                    }

                    if (abortBeforeStep == ILAstOptimizationStep.InlineVariables2)
                    {
                        return;
                    }
                    modified |= new ILInlining(method).InlineAllInBlock(block);
                    new ILInlining(method).CopyPropagation();
                } while(modified);
            }

            if (abortBeforeStep == ILAstOptimizationStep.FindLoops)
            {
                return;
            }
            foreach (ILBlock block in method.GetSelfAndChildrenRecursive <ILBlock>())
            {
                new LoopsAndConditions(context).FindLoops(block);
            }

            if (abortBeforeStep == ILAstOptimizationStep.FindConditions)
            {
                return;
            }
            foreach (ILBlock block in method.GetSelfAndChildrenRecursive <ILBlock>())
            {
                new LoopsAndConditions(context).FindConditions(block);
            }

            if (abortBeforeStep == ILAstOptimizationStep.FlattenNestedMovableBlocks)
            {
                return;
            }
            FlattenBasicBlocks(method);

            if (abortBeforeStep == ILAstOptimizationStep.RemoveEndFinally)
            {
                return;
            }
            RemoveEndFinally(method);

            if (abortBeforeStep == ILAstOptimizationStep.RemoveRedundantCode2)
            {
                return;
            }
            RemoveRedundantCode(method);

            if (abortBeforeStep == ILAstOptimizationStep.GotoRemoval)
            {
                return;
            }
            new GotoRemoval().RemoveGotos(method);

            if (abortBeforeStep == ILAstOptimizationStep.DuplicateReturns)
            {
                return;
            }
            DuplicateReturnStatements(method);

            if (abortBeforeStep == ILAstOptimizationStep.GotoRemoval2)
            {
                return;
            }
            new GotoRemoval().RemoveGotos(method);

            if (abortBeforeStep == ILAstOptimizationStep.ReduceIfNesting)
            {
                return;
            }
            ReduceIfNesting(method);

            if (abortBeforeStep == ILAstOptimizationStep.InlineVariables3)
            {
                return;
            }
            // The 2nd inlining pass is necessary because DuplicateReturns and the introduction of ternary operators
            // open up additional inlining possibilities.
            new ILInlining(method).InlineAllVariables();

            if (abortBeforeStep == ILAstOptimizationStep.CachedDelegateInitialization)
            {
                return;
            }
            foreach (ILBlock block in method.GetSelfAndChildrenRecursive <ILBlock>())
            {
                for (int i = 0; i < block.Body.Count; i++)
                {
                    // TODO: Move before loops
                    CachedDelegateInitializationWithField(block, ref i);
                    CachedDelegateInitializationWithLocal(block, ref i);
                }
            }

            if (abortBeforeStep == ILAstOptimizationStep.IntroduceFixedStatements)
            {
                return;
            }
            // we need post-order traversal, not pre-order, for "fixed" to work correctly
            foreach (ILBlock block in TreeTraversal.PostOrder <ILNode>(method, n => n.GetChildren()).OfType <ILBlock>())
            {
                for (int i = block.Body.Count - 1; i >= 0; i--)
                {
                    // TODO: Move before loops
                    if (i < block.Body.Count)
                    {
                        IntroduceFixedStatements(block.Body, i);
                    }
                }
            }

            if (abortBeforeStep == ILAstOptimizationStep.RecombineVariables)
            {
                return;
            }
            RecombineVariables(method);

            if (abortBeforeStep == ILAstOptimizationStep.TypeInference2)
            {
                return;
            }
            TypeAnalysis.Reset(method);
            TypeAnalysis.Run(context, method);

            if (abortBeforeStep == ILAstOptimizationStep.RemoveRedundantCode3)
            {
                return;
            }
            GotoRemoval.RemoveRedundantCode(method);

            // ReportUnassignedILRanges(method);
        }
Beispiel #51
0
        public bool Compile(IList <Exception> thrownExceptions = null)
        {
            LogLine(1, "Compiling Xaml");
            LogLine(1, "\nAssembly: {0}", Assembly);
            if (!string.IsNullOrEmpty(DependencyPaths))
            {
                LogLine(1, "DependencyPaths: \t{0}", DependencyPaths);
            }
            if (!string.IsNullOrEmpty(ReferencePath))
            {
                LogLine(1, "ReferencePath: \t{0}", ReferencePath.Replace("//", "/"));
            }
            LogLine(3, "DebugSymbols:\"{0}\"", DebugSymbols);
            var  skipassembly = true;            //change this to false to enable XamlC by default
            bool success      = true;

            if (!File.Exists(Assembly))
            {
                LogLine(1, "Assembly file not found. Skipping XamlC.");
                return(true);
            }

            var resolver = new XamlCAssemblyResolver();

            if (!string.IsNullOrEmpty(DependencyPaths))
            {
                foreach (var dep in DependencyPaths.Split(';'))
                {
                    LogLine(3, "Adding searchpath {0}", dep);
                    resolver.AddSearchDirectory(dep);
                }
            }

            if (!string.IsNullOrEmpty(ReferencePath))
            {
                var paths = ReferencePath.Replace("//", "/").Split(';');
                foreach (var p in paths)
                {
                    var searchpath = Path.GetDirectoryName(p);
                    LogLine(3, "Adding searchpath {0}", searchpath);
                    resolver.AddSearchDirectory(searchpath);
                }
            }

            var assemblyDefinition = AssemblyDefinition.ReadAssembly(Path.GetFullPath(Assembly), new ReaderParameters
            {
                AssemblyResolver = resolver,
                ReadSymbols      = DebugSymbols
            });

            CustomAttribute xamlcAttr;

            if (assemblyDefinition.HasCustomAttributes &&
                (xamlcAttr =
                     assemblyDefinition.CustomAttributes.FirstOrDefault(
                         ca => ca.AttributeType.FullName == "Xamarin.Forms.Xaml.XamlCompilationAttribute")) != null)
            {
                var options = (XamlCompilationOptions)xamlcAttr.ConstructorArguments[0].Value;
                if ((options & XamlCompilationOptions.Skip) == XamlCompilationOptions.Skip)
                {
                    skipassembly = true;
                }
                if ((options & XamlCompilationOptions.Compile) == XamlCompilationOptions.Compile)
                {
                    skipassembly = false;
                }
            }

            foreach (var module in assemblyDefinition.Modules)
            {
                var skipmodule = skipassembly;
                if (module.HasCustomAttributes &&
                    (xamlcAttr =
                         module.CustomAttributes.FirstOrDefault(
                             ca => ca.AttributeType.FullName == "Xamarin.Forms.Xaml.XamlCompilationAttribute")) != null)
                {
                    var options = (XamlCompilationOptions)xamlcAttr.ConstructorArguments[0].Value;
                    if ((options & XamlCompilationOptions.Skip) == XamlCompilationOptions.Skip)
                    {
                        skipmodule = true;
                    }
                    if ((options & XamlCompilationOptions.Compile) == XamlCompilationOptions.Compile)
                    {
                        skipmodule = false;
                    }
                }

                LogLine(2, " Module: {0}", module.Name);
                var resourcesToPrune = new List <EmbeddedResource>();
                foreach (var resource in module.Resources.OfType <EmbeddedResource>())
                {
                    LogString(2, "  Resource: {0}... ", resource.Name);
                    string classname;
                    if (!resource.IsXaml(out classname))
                    {
                        LogLine(2, "skipped.");
                        continue;
                    }
                    TypeDefinition typeDef = module.GetType(classname);
                    if (typeDef == null)
                    {
                        LogLine(2, "no type found... skipped.");
                        continue;
                    }
                    var skiptype = skipmodule;
                    if (typeDef.HasCustomAttributes &&
                        (xamlcAttr =
                             typeDef.CustomAttributes.FirstOrDefault(
                                 ca => ca.AttributeType.FullName == "Xamarin.Forms.Xaml.XamlCompilationAttribute")) != null)
                    {
                        var options = (XamlCompilationOptions)xamlcAttr.ConstructorArguments[0].Value;
                        if ((options & XamlCompilationOptions.Skip) == XamlCompilationOptions.Skip)
                        {
                            skiptype = true;
                        }
                        if ((options & XamlCompilationOptions.Compile) == XamlCompilationOptions.Compile)
                        {
                            skiptype = false;
                        }
                    }

                    if (Type != null)
                    {
                        skiptype = !(Type == classname);
                    }

                    if (skiptype)
                    {
                        LogLine(2, "Has XamlCompilationAttribute set to Skip and not Compile... skipped");
                        continue;
                    }

                    var initComp = typeDef.Methods.FirstOrDefault(md => md.Name == "InitializeComponent");
                    if (initComp == null)
                    {
                        LogLine(2, "no InitializeComponent found... skipped.");
                        continue;
                    }
                    LogLine(2, "");

                    var initCompRuntime = typeDef.Methods.FirstOrDefault(md => md.Name == "__InitComponentRuntime");
                    if (initCompRuntime != null)
                    {
                        LogLine(2, "   __InitComponentRuntime already exists... not duplicating");
                    }
                    else
                    {
                        LogString(2, "   Duplicating {0}.InitializeComponent () into {0}.__InitComponentRuntime ... ", typeDef.Name);
                        initCompRuntime = DuplicateMethodDef(typeDef, initComp, "__InitComponentRuntime");
                        LogLine(2, "done.");
                    }

                    LogString(2, "   Parsing Xaml... ");
                    var rootnode = ParseXaml(resource.GetResourceStream(), typeDef);
                    if (rootnode == null)
                    {
                        LogLine(2, "failed.");
                        continue;
                    }
                    LogLine(2, "done.");

                    hasCompiledXamlResources = true;

                    LogString(2, "   Replacing {0}.InitializeComponent ()... ", typeDef.Name);
                    Exception e;
                    if (!TryCoreCompile(initComp, initCompRuntime, rootnode, out e))
                    {
                        success = false;
                        LogLine(2, "failed.");
                        thrownExceptions?.Add(e);
                        LogException(null, null, null, resource.Name, e);
                        LogLine(4, e.StackTrace);
                        continue;
                    }
                    LogLine(2, "done.");

                    if (OptimizeIL)
                    {
                        LogString(2, "   Optimizing IL... ");
                        initComp.Body.OptimizeMacros();
                        LogLine(2, "done");
                    }

                    if (OutputGeneratedILAsCode)
                    {
                        var filepath = Path.Combine(Path.GetDirectoryName(Assembly), typeDef.FullName + ".decompiled.cs");
                        LogString(2, "   Decompiling {0} into {1}...", typeDef.FullName, filepath);
                        var decompilerContext = new DecompilerContext(module);
                        using (var writer = new StreamWriter(filepath))
                        {
                            var output = new PlainTextOutput(writer);

                            var codeDomBuilder = new AstBuilder(decompilerContext);
                            codeDomBuilder.AddType(typeDef);
                            codeDomBuilder.GenerateCode(output);
                        }

                        LogLine(2, "done");
                    }
                    resourcesToPrune.Add(resource);
                }
                if (!KeepXamlResources)
                {
                    if (resourcesToPrune.Any())
                    {
                        LogLine(2, "  Removing compiled xaml resources");
                    }
                    foreach (var resource in resourcesToPrune)
                    {
                        LogString(2, "   Removing {0}... ", resource.Name);
                        module.Resources.Remove(resource);
                        LogLine(2, "done");
                    }
                }

                LogLine(2, "");
            }

            if (!hasCompiledXamlResources)
            {
                LogLine(1, "No compiled resources. Skipping writing assembly.");
                return(success);
            }

            LogString(1, "Writing the assembly... ");
            try
            {
                assemblyDefinition.Write(Assembly, new WriterParameters
                {
                    WriteSymbols = DebugSymbols
                });
                LogLine(1, "done.");
            }
            catch (Exception e)
            {
                LogLine(1, "failed.");
                LogException(null, null, null, null, e);
                thrownExceptions?.Add(e);
                LogLine(4, e.StackTrace);
                success = false;
            }

            return(success);
        }
 public VBTextOutputFormatter(IDecompilerOutput output, DecompilerContext context)
 {
     this.output  = output ?? throw new ArgumentNullException(nameof(output));
     this.context = context ?? throw new ArgumentNullException(nameof(context));
 }
        public static void RunTransformationsUntil(AstNode node, Predicate <IAstTransform> abortCondition, DecompilerContext context)
        {
            if (node == null)
            {
                return;
            }

            var pipeline = context.Cache.GetPipelinePool();

            try {
                foreach (var transform in pipeline)
                {
                    transform.Reset(context);
                    context.CancellationToken.ThrowIfCancellationRequested();
                    if (abortCondition != null && abortCondition(transform))
                    {
                        return;
                    }
                    transform.Run(node);
                }
            }
            finally {
                context.Cache.Return(pipeline);
            }
        }
        CodeGeneratorMemberResult GenerateCode(IMethod method, CodeGenerationOptions options)
        {
            int           bodyStartOffset = -1, bodyEndOffset = -1;
            StringBuilder result = new StringBuilder();

            AppendModifiers(result, options, method);
            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, 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));
        }
 public void Reset(DecompilerContext context)
 {
     this.context = context;
 }
Beispiel #56
0
        private bool SimplifyStackVarsExprents(List <Exprent> list, StructClass cl)
        {
            bool res   = false;
            int  index = 0;

            while (index < list.Count)
            {
                Exprent current = list[index];
                Exprent ret     = IsSimpleConstructorInvocation(current);
                if (ret != null)
                {
                    list[index] = ret;
                    res         = true;
                    continue;
                }
                // lambda expression (Java 8)
                ret = IsLambda(current, cl);
                if (ret != null)
                {
                    list[index] = ret;
                    res         = true;
                    continue;
                }
                // remove monitor exit
                if (IsMonitorExit(current))
                {
                    list.RemoveAtReturningValue(index);
                    res = true;
                    continue;
                }
                // trivial assignment of a stack variable
                if (IsTrivialStackAssignment(current))
                {
                    list.RemoveAtReturningValue(index);
                    res = true;
                    continue;
                }
                if (index == list.Count - 1)
                {
                    break;
                }
                Exprent next = list[index + 1];
                // constructor invocation
                if (IsConstructorInvocationRemote(list, index))
                {
                    list.RemoveAtReturningValue(index);
                    res = true;
                    continue;
                }
                // remove getClass() invocation, which is part of a qualified new
                if (DecompilerContext.GetOption(IFernflowerPreferences.Remove_Get_Class_New))
                {
                    if (IsQualifiedNewGetClass(current, next))
                    {
                        list.RemoveAtReturningValue(index);
                        res = true;
                        continue;
                    }
                }
                // direct initialization of an array
                int arrCount = IsArrayInitializer(list, index);
                if (arrCount > 0)
                {
                    for (int i = 0; i < arrCount; i++)
                    {
                        list.RemoveAtReturningValue(index + 1);
                    }
                    res = true;
                    continue;
                }
                // add array initializer expression
                if (AddArrayInitializer(current, next))
                {
                    list.RemoveAtReturningValue(index + 1);
                    res = true;
                    continue;
                }
                // integer ++expr and --expr  (except for vars!)
                Exprent func = IsPPIorMMI(current);
                if (func != null)
                {
                    list[index] = func;
                    res         = true;
                    continue;
                }
                // expr++ and expr--
                if (IsIPPorIMM(current, next) || IsIPPorIMM2(current, next))
                {
                    list.RemoveAtReturningValue(index + 1);
                    res = true;
                    continue;
                }
                // assignment on stack
                if (IsStackAssignment(current, next))
                {
                    list.RemoveAtReturningValue(index + 1);
                    res = true;
                    continue;
                }
                if (!firstInvocation && IsStackAssignment2(current, next))
                {
                    list.RemoveAtReturningValue(index + 1);
                    res = true;
                    continue;
                }
                index++;
            }
            return(res);
        }
Beispiel #57
0
 protected abstract void WriteResult(TextWriter writer, IEnumerable <AstNode> ast, DecompilerContext context);
Beispiel #58
0
 public IntroduceUsingDeclarations(DecompilerContext context)
 {
     this.context = context;
 }
Beispiel #59
0
 public PatternMatcher(DecompilerContext context, ICorLibTypes corLib)
 {
     this.context = context;
     this.corLib  = corLib;
 }
 public ReplaceMethodCallsWithOperators(DecompilerContext context)
 {
     this.context = context;
 }