/// <summary> /// Decompile the IL operations of this method body into a block of statements. /// </summary> protected override IBlockStatement GetBlock() { var block = new DecompiledBlock(0, this.ilMethodBody.Size, new Sublist <BasicBlock <Instruction> >(this.cdfg.AllBlocks, 0, this.cdfg.AllBlocks.Count), isLexicalScope: true); this.CreateExceptionBlocks(block); bool addDeclarations = true; if (this.localScopeProvider != null) { var scopes = new List <ILocalScope>(this.localScopeProvider.GetLocalScopes(this.ilMethodBody)); if (scopes.Count > 0) { this.CreateLexicalScopes(block, new Sublist <ILocalScope>(scopes, 0, scopes.Count)); addDeclarations = false; } } if (addDeclarations) { int counter = 0; foreach (var local in this.ilMethodBody.LocalVariables) { Contract.Assume(local != null); Contract.Assume(counter <= block.Statements.Count); block.Statements.Insert(counter++, new LocalDeclarationStatement() { LocalVariable = this.GetLocalWithSourceName(local) }); } } new InstructionParser(this).Traverse(block); new SwitchReplacer(this).Traverse(block); DeleteNops(block); DeleteLocalAssignedLocal(block); new PatternReplacer(this, block).Traverse(block); new TryCatchReplacer(this, block).Traverse(block); new RemoveNonLexicalBlocks().Traverse(block); new DeclarationUnifier(this).Traverse(block); new IfThenElseReplacer(this).Traverse(block); if ((this.options & DecompilerOptions.Loops) != 0) { new WhileLoopReplacer(this).Traverse(block); new ForLoopReplacer(this).Traverse(block); } new UnreferencedLabelRemover(this).Traverse(block); new LockReplacer(this).Traverse(block); new BlockFlattener().Traverse(block); this.RemoveRedundantFinalReturn(block); var result = new CompilationArtifactRemover(this).Rewrite(block); if ((this.options & DecompilerOptions.AnonymousDelegates) != 0) { bool didNothing; result = new AnonymousDelegateInserter(this).InsertAnonymousDelegates(result, out didNothing); if (!didNothing) { new DeclarationUnifier(this).Traverse(result); } } return(result); }
/// <summary> /// Perform different phases approppriate for normal, MoveNext, or iterator source method bodies. /// </summary> /// <param name="rootBlock"></param> /// <returns></returns> protected IBlockStatement Transform(BasicBlock rootBlock) { new TypeInferencer((INamedTypeDefinition)this.ilMethodBody.MethodDefinition.ContainingType, this.host).Traverse(rootBlock); new PatternDecompiler(this, this.predecessors).Traverse(rootBlock); new RemoveBranchConditionLocals(this).Traverse(rootBlock); new Unstacker(this).Visit(rootBlock); new TypeInferencer((INamedTypeDefinition)this.ilMethodBody.MethodDefinition.ContainingType, this.host).Traverse(rootBlock); new TryCatchDecompiler(this.host.PlatformType, this.predecessors).Traverse(rootBlock); new IfThenElseDecompiler(this.host.PlatformType, this.predecessors).Traverse(rootBlock); new SwitchDecompiler(this.host.PlatformType, this.predecessors).Traverse(rootBlock); if ((this.options & DecompilerOptions.Loops) != 0) { new WhileLoopDecompiler(this.host.PlatformType, this.predecessors).Traverse(rootBlock); new ForLoopDecompiler(this.host.PlatformType, this.predecessors).Traverse(rootBlock); } new BlockRemover().Traverse(rootBlock); new DeclarationAdder().Traverse(this, rootBlock); new EmptyStatementRemover().Traverse(rootBlock); IBlockStatement result = rootBlock; if ((this.options & DecompilerOptions.Iterators) != 0) { IMethodBody moveNextILBody = this.FindClosureMoveNext(rootBlock); if (moveNextILBody != Dummy.MethodBody) { if (this.privateHelperTypesToRemove == null) this.privateHelperTypesToRemove = new List<ITypeDefinition>(1); this.privateHelperTypesToRemove.Add(moveNextILBody.MethodDefinition.ContainingTypeDefinition); var moveNextBody = new MoveNextSourceMethodBody(this.ilMethodBody, moveNextILBody, this.host, this.sourceLocationProvider, this.localScopeProvider, this.options); result = moveNextBody.TransformedBlock; } } result = new CompilationArtifactRemover(this, (this.options & DecompilerOptions.AnonymousDelegates) != 0).RemoveCompilationArtifacts((BlockStatement)result); var bb = result as BasicBlock; if (bb != null) { new UnreferencedLabelRemover(this).Traverse(bb); new TypeInferencer((INamedTypeDefinition)this.ilMethodBody.MethodDefinition.ContainingType, this.host).Traverse(bb); } return result; }
internal CapturedLocalsFinder(CompilationArtifactRemover remover) { this.remover = remover; }
/// <summary> /// Decompile the IL operations of this method body into a block of statements. /// </summary> protected override IBlockStatement GetBlock() { var block = new DecompiledBlock(0, this.ilMethodBody.Size, new Sublist<BasicBlock<Instruction>>(this.cdfg.AllBlocks, 0, this.cdfg.AllBlocks.Count), isLexicalScope: true); this.CreateExceptionBlocks(block); bool addDeclarations = true; if (this.localScopeProvider != null) { var scopes = new List<ILocalScope>(this.localScopeProvider.GetLocalScopes(this.ilMethodBody)); if (scopes.Count > 0) { this.CreateLexicalScopes(block, new Sublist<ILocalScope>(scopes, 0, scopes.Count)); addDeclarations = false; } } if (addDeclarations) { int counter = 0; foreach (var local in this.ilMethodBody.LocalVariables) { Contract.Assume(local != null); Contract.Assume(counter <= block.Statements.Count); block.Statements.Insert(counter++, new LocalDeclarationStatement() { LocalVariable = this.GetLocalWithSourceName(local) }); } } new InstructionParser(this).Traverse(block); new SwitchReplacer(this).Traverse(block); DeleteNops(block); DeleteLocalAssignedLocal(block); new PatternReplacer(this, block).Traverse(block); new TryCatchReplacer(this, block).Traverse(block); new RemoveNonLexicalBlocks().Traverse(block); new DeclarationUnifier(this).Traverse(block); new IfThenElseReplacer(this).Traverse(block); if ((this.options & DecompilerOptions.Loops) != 0) { new WhileLoopReplacer(this).Traverse(block); new ForLoopReplacer(this).Traverse(block); } new UnreferencedLabelRemover(this).Traverse(block); new LockReplacer(this).Traverse(block); new BlockFlattener().Traverse(block); this.RemoveRedundantFinalReturn(block); var result = new CompilationArtifactRemover(this).Rewrite(block); if ((this.options & DecompilerOptions.AnonymousDelegates) != 0) { bool didNothing; result = new AnonymousDelegateInserter(this).InsertAnonymousDelegates(result, out didNothing); if (!didNothing) new DeclarationUnifier(this).Traverse(result); } return result; }