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(); } }
public BlockStatement CreateMethodBody() { if (methodDef.Body == null) return null; context.CancellationToken.ThrowIfCancellationRequested(); ILBlock ilMethod = new ILBlock(); ILAstBuilder astBuilder = new ILAstBuilder(); ilMethod.Body = astBuilder.Build(methodDef, true); context.CancellationToken.ThrowIfCancellationRequested(); ILAstOptimizer bodyGraph = new ILAstOptimizer(); bodyGraph.Optimize(context, ilMethod); context.CancellationToken.ThrowIfCancellationRequested(); NameVariables.AssignNamesToVariables(methodDef.Parameters.Select(p => p.Name), astBuilder.Variables, ilMethod); context.CancellationToken.ThrowIfCancellationRequested(); Ast.BlockStatement astBlock = TransformBlock(ilMethod); CommentStatement.ReplaceAll(astBlock); // convert CommentStatements to Comments foreach (ILVariable v in localVariablesToDefine) { DeclareVariableInSmallestScope.DeclareVariable(astBlock, AstBuilder.ConvertType(v.Type), v.Name); } return astBlock; }
public BlockStatement CreateMethodBody() { Ast.BlockStatement astBlock = new Ast.BlockStatement(); if (methodDef.Body == null) return astBlock; List<ILNode> body = new ILAstBuilder().Build(methodDef); MethodBodyGraph bodyGraph = new MethodBodyGraph(body); bodyGraph.Optimize(); List<string> intNames = new List<string>(new string[] {"i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t"}); Dictionary<string, int> typeNames = new Dictionary<string, int>(); foreach(VariableDefinition varDef in methodDef.Body.Variables) { if (string.IsNullOrEmpty(varDef.Name)) { if (varDef.VariableType.FullName == Constants.Int32 && intNames.Count > 0) { varDef.Name = intNames[0]; intNames.RemoveAt(0); } else { string name; if (varDef.VariableType.IsArray) { name = "array"; } else if (!typeNameToVariableNameDict.TryGetValue(varDef.VariableType.FullName, out name)) { name = varDef.VariableType.Name; // remove the 'I' for interfaces if (name.Length >= 3 && name[0] == 'I' && char.IsUpper(name[1]) && char.IsLower(name[2])) name = name.Substring(1); // remove the backtick (generics) int pos = name.IndexOf('`'); if (pos >= 0) name = name.Substring(0, pos); if (name.Length == 0) name = "obj"; else name = char.ToLower(name[0]) + name.Substring(1); } if (!typeNames.ContainsKey(name)) { typeNames.Add(name, 0); } int count = typeNames[name]; if (count > 0) { name += count.ToString(); } varDef.Name = name; } } localVarTypes[varDef.Name] = varDef.VariableType; localVarDefined[varDef.Name] = false; // Ast.VariableDeclaration astVar = new Ast.VariableDeclaration(varDef.Name); // Ast.LocalVariableDeclaration astLocalVar = new Ast.LocalVariableDeclaration(astVar); // astLocalVar.TypeReference = new Ast.TypeReference(varDef.VariableType.FullName); // astBlock.Children.Add(astLocalVar); } astBlock.Children.AddRange(TransformNodes(bodyGraph.Childs)); return astBlock; }
public BlockStatement CreateMethodBody() { if (methodDef.Body == null) return null; ILBlock ilMethod = new ILBlock(); ILAstBuilder astBuilder = new ILAstBuilder(); ilMethod.Body = astBuilder.Build(methodDef, true); ILAstOptimizer bodyGraph = new ILAstOptimizer(); bodyGraph.Optimize(ilMethod); List<string> intNames = new List<string>(new string[] {"i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t"}); Dictionary<string, int> typeNames = new Dictionary<string, int>(); foreach(ILVariable varDef in astBuilder.Variables) { if (varDef.Type.FullName == Constants.Int32 && intNames.Count > 0) { varDef.Name = intNames[0]; intNames.RemoveAt(0); } else { string name; if (varDef.Type.IsArray) { name = "array"; } else if (!typeNameToVariableNameDict.TryGetValue(varDef.Type.FullName, out name)) { name = varDef.Type.Name; // remove the 'I' for interfaces if (name.Length >= 3 && name[0] == 'I' && char.IsUpper(name[1]) && char.IsLower(name[2])) name = name.Substring(1); // remove the backtick (generics) int pos = name.IndexOf('`'); if (pos >= 0) name = name.Substring(0, pos); if (name.Length == 0) name = "obj"; else name = char.ToLower(name[0]) + name.Substring(1); } if (!typeNames.ContainsKey(name)) { typeNames.Add(name, 0); } int count = ++(typeNames[name]); if (count > 1) { name += count.ToString(); } varDef.Name = name; } // Ast.VariableDeclaration astVar = new Ast.VariableDeclaration(varDef.Name); // Ast.LocalVariableDeclaration astLocalVar = new Ast.LocalVariableDeclaration(astVar); // astLocalVar.TypeReference = new Ast.TypeReference(varDef.VariableType.FullName); // astBlock.Children.Add(astLocalVar); } Ast.BlockStatement astBlock = TransformBlock(ilMethod); CommentStatement.ReplaceAll(astBlock); // convert CommentStatements to Comments return astBlock; }