Example #1
0
        internal static Tuple <MethodInfo, MethodDeclaration>[] GetTestMethodsWithDecompiled(CSharpDecompiler decompiler, Tuple <Type, MethodInfo[]>[] testTypeMethods)
        {
            var testMethods = new List <Tuple <MethodInfo, MethodDeclaration> >();

            foreach ((Type testType, MethodInfo[] testMethodInfos) in testTypeMethods)
            {
                var fullTypeName = new FullTypeName(testType.FullName);
                var syntaxTree   = decompiler.DecompileType(fullTypeName);
                var astNodes     = syntaxTree.Descendants.Where(x => x.NodeType == NodeType.Member).ToArray();
                foreach (var testMethodInfo in testMethodInfos)
                {
                    foreach (var astNode in astNodes)
                    {
                        if (!(astNode is MethodDeclaration methodDeclaration))
                        {
                            continue;
                        }

                        if (!methodDeclaration.Name.Equals(testMethodInfo.Name, StringComparison.Ordinal))
                        {
                            continue;
                        }

                        testMethods.Add(new Tuple <MethodInfo, MethodDeclaration>(testMethodInfo, methodDeclaration));
                    }
                }
            }

            return(testMethods.ToArray());
        }
Example #2
0
        public IEnumerable <EcsFile> Generate(IEnumerable <TypeDefinition> types, string assemblyName)
        {
            var files = new List <EcsFile>();

            m_settings = new DecompilerSettings();
            m_settings.ShowXmlDocumentation      = false;
            m_settings.NamedArguments            = false;
            m_settings.NonTrailingNamedArguments = false;
            m_settings.OptionalArguments         = false;

            m_decompiler = CreateDecompiler(assemblyName, m_settings);
            m_decompiler.ILTransforms.Insert(0, new RefCounting());
            m_decompiler.ILTransforms.Remove(m_decompiler.ILTransforms.Single(x => x.GetType() == typeof(AssignVariableNames)));
            m_decompiler.AstTransforms.Add(new AddBaseStruct());
            m_decompiler.AstTransforms.Add(new RemoveStaticMemberAccess());

            foreach (var t in types)
            {
                var syntaxTree = new Lazy <SyntaxTree>(() => m_decompiler.DecompileType(new FullTypeName(t.FullName)));
                files.Add(GenerateCodeFile(t, syntaxTree, OutputMode.Header));
                files.Add(GenerateCodeFile(t, syntaxTree, OutputMode.Source));
            }

            return(files);
        }
Example #3
0
    public static void Main(string[] args)
    {
        using (var host = WebHost.Start((IRouteBuilder router)
                                        => router.MapGet("api/decompile/csharp", async(req, res, data) =>
        {
            if (req.Query.TryGetValue("assemblyFileName", out var assemblyFileName) &&
                req.Query.TryGetValue("typeName", out var typeName))
            {
                var decompiler = new CSharpDecompiler(assemblyFileName, new DecompilerSettings {
                    ThrowOnAssemblyResolveErrors = true
                });

                var decompiledType = decompiler.DecompileType(new FullTypeName(typeName));
                await res.WriteAsync(decompiledType.ToString());
            }
            else
            {
                res.StatusCode = 400;
                await res.WriteAsync($"Missing query string parameters: '{nameof(assemblyFileName)}', '{nameof(typeName)}'.");
            }
        })))
        {
            host.WaitForShutdown();
        }
    }
Example #4
0
        public static ICSharpCode.Decompiler.CSharp.Syntax.SyntaxTree Decompile(this Assembly assembly, string typeName)
        {
            string path       = GetPath(assembly);
            var    settings   = new DecompilerSettings();
            var    decompiler = new CSharpDecompiler(path, settings);
            var    name       = new FullTypeName(typeName);
            var    syntaxTree = decompiler.DecompileType(name);

            return(syntaxTree);
        }
Example #5
0
        private string GetStructCode(Type structInstance)
        {
            string           assemblyPath = structInstance.Assembly.Location;
            CSharpDecompiler cSharpDecompiler
                = new CSharpDecompiler(assemblyPath, new Amplifier.Decompiler.DecompilerSettings()
            {
                ThrowOnAssemblyResolveErrors = false, ForEachStatement = false
            });

            var tree = cSharpDecompiler.DecompileType(new FullTypeName(structInstance.FullName));

            string code = cSharpDecompiler.DecompileTypeAsString(new FullTypeName(structInstance.FullName));

            return(CodeTranslator.Translate(code).Trim() + ";");
        }
Example #6
0
        public static string GetSourceDecompiled <T>(Predicate <T> match)
        {
            string module_path = match.Method.Module.FullyQualifiedName;

            var settings = new DecompilerSettings();

            settings.AnonymousMethods = false; //disable anonymous methods inlining

            var decompiler = new CSharpDecompiler(module_path, settings);

            //decompile type that contains method
            SyntaxTree tree = decompiler.DecompileType(
                new ICSharpCode.Decompiler.TypeSystem.FullTypeName(match.Method.DeclaringType.FullName)
                );

            //find method in syntax tree
            var     children = tree.Children.ToList();
            AstNode res      = null;

            foreach (var x in children)
            {
                res = FindNode(x, match.Method.Name);
                if (res != null)
                {
                    break;
                }
            }

            string s = "";

            if (res != null)
            {
                s = res.ToString();
            }
            return(s);
        }
        static int Main(string[] args)
        {
            var assemblyFilenameOption = new Option <FileInfo>(
                new[] { "--assembly", "-a" },
                description: "The assembly to decompile into XML.");

            var verboseOption = new Option <bool>(
                new[] { "--verbose", "-v" },
                description: "Provide output as code is running.");

            var outputOption = new Option <DirectoryInfo>(
                new[] { "--output", "-o" },
                description: "The root directory where the XML files will be written. The directory must exist.");

            var rootCommand = new RootCommand
            {
                assemblyFilenameOption,
                verboseOption,
                outputOption,
            };

            rootCommand.Description = "Command to extract C# code into XML suitable for reasoning.";

            rootCommand.SetHandler((FileInfo assemblyFile, bool verbose, DirectoryInfo outputDirectory) =>
            {
                if (assemblyFile == null)
                {
                    Console.Error.WriteLine("No assembly provided to extract");
                    return;
                }

                if (outputDirectory == null)
                {
                    Console.Error.WriteLine("No target directory provided");
                    return;
                }

                // Set up the preferences for the decompilation of the IL into source.
                var settings = new DecompilerSettings()
                {
                    AlwaysUseBraces      = true,
                    ShowXmlDocumentation = true
                };
                settings.CSharpFormattingOptions.IndentationString = "    ";

                var decompiler = new CSharpDecompiler(assemblyFile.FullName, settings);

                // Traverse all the types in the assembly
                foreach (var typeDefinition in decompiler.TypeSystem.MainModule.TopLevelTypeDefinitions)
                {
                    if (typeDefinition.Name.StartsWith("<"))
                    {
                        continue;
                    }

                    if (verbose)
                    {
                        Console.WriteLine($"Extracting {typeDefinition.FullName}.");
                    }
                    var syntaxTree = decompiler.DecompileType(typeDefinition.FullTypeName);

                    // This is needed to get the locations correctly set in the AST.
                    StringWriter w = new StringWriter();

                    var q = new TextWriterTokenWriter(w);
                    q.IndentationString = "    ";

                    TokenWriter tokenWriter = q;

                    tokenWriter = TokenWriter.WrapInWriterThatSetsLocationsInAST(tokenWriter);
                    syntaxTree.AcceptVisitor(new CSharpOutputVisitor(tokenWriter, settings.CSharpFormattingOptions));
                    var source = w.ToString();

                    var generator = new XmlGeneratorVisitor(assemblyFile.FullName, source);
                    syntaxTree.AcceptVisitor(generator);

                    File.WriteAllText(Path.Combine(outputDirectory.FullName, typeDefinition.FullTypeName.Name) + ".xml", generator.Document.ToString());
                }
            },
                                   assemblyFilenameOption, verboseOption, outputOption);

            return(rootCommand.Invoke(args));
        }
Example #8
0
        public string CompileGlsl()
        {
            var decompiler = new CSharpDecompiler(GetType().Assembly.Location, new DecompilerSettings());
            var td         = decompiler.TypeSystem.MainModule.Compilation.FindType(GetType()).GetDefinition();

            var usings = decompiler.DecompileType(new FullTypeName(GetType().FullName)).Members
                         .Where(x => x is UsingDeclaration).Select(x => ((UsingDeclaration)x).Namespace)
                         .Concat(new[] { GetType().Namespace }).ToList();

            GlslAst[] TransformBody(SyntaxTree func) =>
            func.Members.First(x => x.NodeType == NodeType.Member).Children
            .First(x => x.NodeType == NodeType.Statement)
            .Children.Select(x => Transform(x)).Where(x => x != null).ToArray();

            Type ToType(AstType astType)
            {
                var t = astType.ToTypeReference()
                        .Resolve(new CSharpTypeResolveContext(decompiler.TypeSystem.MainModule));

                return(new[] { t.Namespace }.Concat(usings).Select(ns => AppDomain.CurrentDomain.GetAssemblies()
                                                                   .Select(x => x.GetType(ns == null ? t.FullName : $"{ns}.{t.Name}"))
                                                                   .FirstOrDefault(x => x != null)).FirstOrDefault(x => x != null));
            }

            string Format(float value)
            {
                var str = value.ToString(CultureInfo.InvariantCulture);

                return(str.Contains(".") ? str + "f" : str + ".0f");
            }

            GlslAst ToLiteral(object value) =>
            new GlslAst.InlineExpression
            {
                Code = value switch {
                    Vec2 v => $"vec2({Format(v.x)}, {Format(v.y)})",
                    Vec3 v => $"vec3({Format(v.x)}, {Format(v.y)}, {Format(v.z)})",
                    Vec4 v => $"vec4({Format(v.x)}, {Format(v.y)}, {Format(v.z)}, {Format(v.w)})",
                         _ => throw new NotImplementedException($"Unknown type for GLSL literal {value.GetType()}: {value}")
                }
            };

            GlslAst EnsureStmt(GlslAst node) =>
            node is GlslAst.Expression expr
                                        ? new GlslAst.ExpressionStatement
            {
                Expression = expr
            }

                                        : node;

            GlslAst MatchIntrinsic(AstNode node)
            {
                GlslAst VectorStatics()
                {
                    if (!(node is MemberReferenceExpression mre))
                    {
                        return(null);
                    }
                    if (!(mre.Target is TypeReferenceExpression tre))
                    {
                        return(null);
                    }
                    var    ctype  = ToType(tre.Type);
                    var    member = ctype.GetMember(mre.MemberName).First();
                    object value;

                    if (member is FieldInfo fi)
                    {
                        if (!fi.IsStatic || !fi.IsInitOnly)
                        {
                            return(null);
                        }
                        value = fi.GetValue(null);
                    }
                    else if (member is PropertyInfo pi)
                    {
                        if (pi.SetMethod != null || !pi.GetMethod.IsStatic)
                        {
                            return(null);
                        }
                        value = pi.GetValue(null);
                    }
                    else
                    {
                        return(null);
                    }
                    return(ToLiteral(value));
                }

                GlslAst MatrixTransform()
                {
                    if (!(node is InvocationExpression ie))
                    {
                        return(null);
                    }
                    if (!(ie.Target is MemberReferenceExpression mre))
                    {
                        return(null);
                    }
                    if (mre.MemberName != "Transform" || !mre.Target.ToString().StartsWith("Vector"))
                    {
                        return(null);
                    }
                    return(new GlslAst.BinaryOperatorExpression {
                        Left = Transform(ie.Arguments.Skip(1).First()),
                        Right = Transform(ie.Arguments.First()),
                        Operator = "*"
                    });
                }

                var ifuncs = new List <Func <GlslAst> > {
                    VectorStatics, MatrixTransform
                };

                return(ifuncs.Select(x => x()).FirstOrDefault(x => x != null));
            }

            GlslAst Transform(AstNode node, bool bareExpr = false)
            {
                var intrinsic = MatchIntrinsic(node);

                if (intrinsic != null)
                {
                    return(intrinsic);
                }
                switch (node)
                {
                case DefaultValueExpression _: return(null);

                case VariableDeclarationStatement decl:
                    return(new GlslAst.DeclareStatement
                    {
                        Name = decl.Variables.First().Name, Type = ToType(decl.Type),
                        Value = Transform(decl.Variables.First().Initializer)
                    });

                case ReturnStatement ret:
                    return(new GlslAst.ReturnStatement {
                        Expression = Transform(ret.Expression)
                    });

                case IdentifierExpression id:
                    return(new GlslAst.IdentifierExpression {
                        Name = id.Identifier
                    });

                case ExpressionStatement expr:
                    var tf = Transform(expr.Expression);
                    if (bareExpr)
                    {
                        return(tf);
                    }
                    return(tf is GlslAst.Expression e ? new GlslAst.ExpressionStatement {
                        Expression = e
                    } : tf);

                case AssignmentExpression ass:
                    var right = Transform(ass.Right);
                    if (right == null)
                    {
                        return(null);
                    }
                    return(new GlslAst.AssignExpression
                    {
                        Target = Transform(ass.Left), Value = right
                    });

                case MemberReferenceExpression mre:
                    return(new GlslAst.MemberAccessExpression
                    {
                        Base = Transform(mre.Target), Member = mre.MemberName
                    });

                case PrimitiveExpression pe:
                    return(pe.Value switch {
                        int i => (GlslAst) new GlslAst.IntExpression {
                            Value = i
                        },                                                                                          // TODO: Report Rider bug
                        float f => new GlslAst.FloatExpression {
                            Value = f
                        },
                        _ => throw new NotImplementedException($"Unhandled primitive type {pe.Value.GetType()}")
                    });