Пример #1
0
        internal static KeyValuePair <MethodDefinition, KeyValuePair <string, string> > CreateMethodString(TypeDefinition s, MethodDefinition m)
        {
            if (s == null)
            {
                throw new ArgumentNullException("s");
            }

            if (m == null)
            {
                throw new ArgumentNullException("m");
            }

            var ctx = new DecompilerContext(s.Module)
            {
                CurrentType       = s,
                CurrentMethod     = m,
                CancellationToken = CancellationToken.None
            };

            var d = AstMethodBodyBuilder.CreateMethodBody(m, ctx);

            var glsl = new ASLShader.GLSLVisitor(d, ctx);

            var sig  = ASLShader.GLSLVisitor.GetSignature(m);
            var code = glsl.Result;
            var desc = new KeyValuePair <MethodDefinition, KeyValuePair <string, string> >(
                m,
                new KeyValuePair <string, string>(m.Name, sig + code)
                );

            return(desc);
        }
Пример #2
0
		IEnumerable<Tuple<string, string>> WriteCodeFilesInProject(ModuleDefinition module, DecompilationOptions options, HashSet<string> directories)
		{
			var files = module.Types.Where(t => IncludeTypeWhenDecompilingProject(t, options)).GroupBy(
				delegate(TypeDefinition type) {
					string file = TextView.DecompilerTextView.CleanUpName(type.Name) + this.FileExtension;
					if (string.IsNullOrEmpty(type.Namespace)) {
						return file;
					} else {
						string dir = TextView.DecompilerTextView.CleanUpName(type.Namespace);
						if (directories.Add(dir))
							Directory.CreateDirectory(Path.Combine(options.SaveAsProjectDirectory, dir));
						return Path.Combine(dir, file);
					}
				}, StringComparer.OrdinalIgnoreCase).ToList();
			AstMethodBodyBuilder.ClearUnhandledOpcodes();
			Parallel.ForEach(
				files,
				new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount },
				delegate(IGrouping<string, TypeDefinition> file) {
					using (StreamWriter w = new StreamWriter(Path.Combine(options.SaveAsProjectDirectory, file.Key))) {
						AstBuilder codeDomBuilder = CreateAstBuilder(options, currentModule: module);
						foreach (TypeDefinition type in file) {
							codeDomBuilder.AddType(type);
						}
						RunTransformsAndGenerateCode(codeDomBuilder, new PlainTextOutput(w), options, module);
					}
				});
			AstMethodBodyBuilder.PrintNumberOfUnhandledOpcodes();
			return files.Select(f => Tuple.Create("Compile", f.Key)).Concat(WriteAssemblyInfo(module, options, directories));
		}
Пример #3
0
        IEnumerable <Tuple <string, string> > WriteCodeFilesInProject(ModuleDefinition module, DecompilationOptions options, HashSet <string> directories)
        {
            var files = module.Types.Where(t => IncludeTypeWhenDecompilingProject(t, options)).GroupBy(
                delegate(TypeDefinition type) {
                string file = TextView.DecompilerTextView.CleanUpName(type.Name) + this.FileExtension;
                // TODO Find more proper way to know root namespace?
                string rootNs = type.Module.Assembly.Name.Name;
                // Cut root namespace from sub-directory name for decompiled source files
                // TODO Control namespaces cutting with some assembly settings option?
                if (string.IsNullOrEmpty(type.Namespace) || type.Namespace.Equals(rootNs, StringComparison.Ordinal))
                {
                    return(file);
                }
                else
                {
                    string dir = type.Namespace;
                    if (dir.StartsWith(rootNs + ".", StringComparison.Ordinal))
                    {
                        dir = dir.Substring(rootNs.Length + 1);
                    }
                    // Create sub-directories for each namespace part
                    dir = TextView.DecompilerTextView.CleanUpName(dir).Replace('.', Path.DirectorySeparatorChar);
                    if (directories.Add(dir))
                    {
                        Directory.CreateDirectory(Path.Combine(options.SaveAsProjectDirectory, dir));
                    }
                    return(Path.Combine(dir, file));
                }
            }, StringComparer.OrdinalIgnoreCase).ToList();

            AstMethodBodyBuilder.ClearUnhandledOpcodes();
            Parallel.ForEach(
                files,
                new ParallelOptions {
                MaxDegreeOfParallelism = Environment.ProcessorCount
            },
                delegate(IGrouping <string, TypeDefinition> file) {
                using (StreamWriter w = new StreamWriter(Path.Combine(options.SaveAsProjectDirectory, file.Key))) {
                    AstBuilder codeDomBuilder = CreateAstBuilder(options, currentModule: module);
                    foreach (TypeDefinition type in file)
                    {
                        codeDomBuilder.AddType(type);
                    }
                    codeDomBuilder.RunTransformations(transformAbortCondition);
                    codeDomBuilder.GenerateCode(new PlainTextOutput(w));
                }
            });
            AstMethodBodyBuilder.PrintNumberOfUnhandledOpcodes();
            return(files.Select(f => Tuple.Create("Compile", f.Key)).Concat(WriteAssemblyInfo(module, options, directories)));
        }
Пример #4
0
        public override object VisitInvocationExpression(InvocationExpression invocationExpression, object data)
        {
            if (context.Settings.ExpressionTrees && ExpressionTreeConverter.CouldBeExpressionTree(invocationExpression))
            {
                Expression converted = ExpressionTreeConverter.TryConvert(context, invocationExpression);
                if (converted != null)
                {
                    invocationExpression.ReplaceWith(converted);
                    return(converted.AcceptVisitor(this, data));
                }
            }
            var definition = invocationExpression.Annotation <MethodDefinition>();

            if (definition != null)
            {
                //Handle hoisted base calls from yield return compiler generated class (can be generated by both Mono and Roslyn)
                if (definition.DeclaringType == context.CurrentType && definition.IsCompilerGenerated())
                {
                    DecompilerContext subContext = context.Clone();
                    subContext.CurrentMethod        = definition;
                    subContext.CurrentMethodIsAsync = false;
                    subContext.ReservedVariableNames.AddRange(currentlyUsedVariableNames);
                    var            parameters = AstBuilder.MakeParameters(definition, isLambda: true);
                    BlockStatement body       = AstMethodBodyBuilder.CreateMethodBody(definition, subContext, parameters);
                    TransformationPipeline.RunTransformationsUntil(body, v => v is DelegateConstruction, subContext);

                    if (body.Statements.Count == 1)
                    {
                        var        statement = body.Statements.Single();
                        Expression expr      = null;
                        if (statement is ReturnStatement)
                        {
                            expr = ((ReturnStatement)statement).Expression;
                        }
                        else if (statement is ExpressionStatement)
                        {
                            expr = ((ExpressionStatement)statement).Expression;
                        }
                        if (expr != null)
                        {
                            expr.Remove();
                            invocationExpression.ReplaceWith(expr);
                            return(expr.AcceptVisitor(this, data));
                        }
                    }
                }
            }
            return(base.VisitInvocationExpression(invocationExpression, data));
        }
Пример #5
0
        void ParserFilesInProject(ModuleDefinition module, DecompilationOptions options, HashSet <string> directories, List <TNamespace> nsList)
        {
            var files = module.Types.Where(t => IncludeTypeWhenDecompilingProject(t, options)).GroupBy(
                delegate(TypeDefinition type)
            {
                string file = CleanUpName(type.Name) + this.FileExtension;
                if (string.IsNullOrEmpty(type.Namespace))
                {
                    return(file);
                }
                else
                {
                    string dir = CleanUpName(type.Namespace);
                    if (directories.Add(dir))
                    {
                        Directory.CreateDirectory(Path.Combine(options.SaveAsProjectDirectory, dir));
                    }
                    return(Path.Combine(dir, file));
                }
            }, StringComparer.OrdinalIgnoreCase).ToList();

            AstMethodBodyBuilder.ClearUnhandledOpcodes();

            Parallel.ForEach(
                files,
                new ParallelOptions {
                MaxDegreeOfParallelism = Environment.ProcessorCount
            },
                delegate(IGrouping <string, TypeDefinition> file)
            {
                AstBuilder codeDomBuilder = CreateAstBuilder(options, currentModule: module);
                foreach (TypeDefinition type in file)
                {
                    codeDomBuilder.AddType(type);
                }
                codeDomBuilder.RunTransformations(transformAbortCondition);

                var visitor = new LuaOutputVisitor();
                codeDomBuilder.SyntaxTree.AcceptVisitor(visitor);

                lock (nsList)
                {
                    nsList.Add(visitor.ns);
                }
            });
        }
Пример #6
0
        /// <summary>
        /// Public translation interface.
        /// Translates the given method to GLSL
        /// </summary>
        /// <param name="s">Shader type definition.</param>
        /// <param name="m">A method representing a shader to translate.</param>
        /// <param name="attr">The shader type as attribute (either FragmentShaderAttribute or VertexShaderAttribute</param>
        /// <param name="type">The shader type as ShaderType</param>
        /// <returns>The translated GLSL shader source</returns>
        public FunctionDescription Transform(TypeDefinition s, MethodDefinition m, CustomAttribute attr,
                                             ShaderType type)
        {
            if (s == null)
            {
                throw new ArgumentNullException("s");
            }

            if (m == null)
            {
                throw new ArgumentNullException("m");
            }

            if (attr == null)
            {
                throw new ArgumentNullException("attr");
            }

            var ctx = new DecompilerContext(s.Module)
            {
                CurrentType       = s,
                CurrentMethod     = m,
                CancellationToken = CancellationToken.None
            };

            var d = AstMethodBodyBuilder.CreateMethodBody(m, ctx);

            var glsl = new GlslVisitor(d, attr, ctx);

            _functions.UnionWith(glsl.Functions);

            var sig   = GlslVisitor.GetSignature(m);
            var entry = (bool)attr.ConstructorArguments.FirstOrDefault().Value;
            var code  = glsl.Result;
            var desc  = new FunctionDescription(Shader.GetMethodName(m), sig + code, entry, type);

            _dependencies.UnionWith(glsl.Dependencies);

            return(desc);
        }
Пример #7
0
        internal void Init(MethodDefinition methodDef)
        {
            CurrentMethod = methodDef;

            var type   = methodDef.DeclaringType;
            var module = methodDef.DeclaringType.Module;

            var decContext = new DecompilerContext(module)
            {
                CurrentType   = type,
                CurrentMethod = methodDef
            };

            // create AST and run optimization operations
            TopNode = AstMethodBodyBuilder.CreateMethodBody(methodDef, decContext);

            // replaces every "!(x == 5)" by "(x != 5)"
            var transform1 = (IAstTransform) new PushNegation();

            transform1.Run(TopNode);

            // replaces (unnecessary) while loops by for loops
            var transform2 = (IAstTransform) new PatternStatementTransform(decContext);

            transform2.Run(TopNode);

            // replaces every "x = Plus(x, y)" by "x += y", etc.
            var transform3 = (IAstTransform) new ReplaceMethodCallsWithOperators(decContext);

            transform3.Run(TopNode);

            // replaces every "var x; x = 5;" by "var x = 5;"
            var transform4 = (IAstTransform) new DeclareVariables(decContext);

            transform4.Run(TopNode);
        }
Пример #8
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);
        }
Пример #9
0
        Expression ConvertNewObject(InvocationExpression invocation)
        {
            if (invocation.Arguments.Count < 1 || invocation.Arguments.Count > 3)
            {
                return(NotSupported(invocation));
            }

            Match m = newObjectCtorPattern.Match(invocation.Arguments.First());

            if (!m.Success)
            {
                return(NotSupported(invocation));
            }

            IMethod ctor = m.Get <AstNode>("ctor").Single().Annotation <IMethod>();

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

            AstType       declaringTypeNode;
            ITypeDefOrRef declaringType;

            if (m.Has("declaringType"))
            {
                declaringTypeNode = m.Get <AstType>("declaringType").Single().Clone();
                declaringType     = declaringTypeNode.Annotation <ITypeDefOrRef>();
            }
            else
            {
                declaringTypeNode = AstBuilder.ConvertType(ctor.DeclaringType, stringBuilder);
                declaringType     = ctor.DeclaringType;
            }
            if (declaringTypeNode == null)
            {
                return(null);
            }

            ObjectCreateExpression oce = new ObjectCreateExpression(declaringTypeNode);

            if (invocation.Arguments.Count >= 2)
            {
                IList <Expression> arguments = ConvertExpressionsArray(invocation.Arguments.ElementAtOrDefault(1));
                if (arguments == null)
                {
                    return(null);
                }
                oce.Arguments.AddRange(arguments);
            }
            if (invocation.Arguments.Count >= 3 && declaringType.IsAnonymousType())
            {
                MethodDef resolvedCtor = ctor.Resolve();
                if (resolvedCtor == null)
                {
                    return(null);
                }
                int skip = resolvedCtor.Parameters.GetParametersSkip();
                if (resolvedCtor.Parameters.Count - skip != oce.Arguments.Count)
                {
                    return(null);
                }
                AnonymousTypeCreateExpression atce = new AnonymousTypeCreateExpression();
                var arguments = oce.Arguments.ToArray();
                if (AstMethodBodyBuilder.CanInferAnonymousTypePropertyNamesFromArguments(arguments, resolvedCtor.Parameters))
                {
                    oce.Arguments.MoveTo(atce.Initializers);
                }
                else
                {
                    for (int i = 0; i < resolvedCtor.Parameters.Count - skip; i++)
                    {
                        atce.Initializers.Add(
                            new NamedExpression {
                            NameToken  = Identifier.Create(resolvedCtor.Parameters[i + skip].Name).WithAnnotation(resolvedCtor.Parameters[i + skip]),
                            Expression = arguments[i].Detach()
                        });
                    }
                }
                return(atce);
            }

            return(oce);
        }
Пример #10
0
        Expression ConvertCall(InvocationExpression invocation)
        {
            if (invocation.Arguments.Count < 2)
            {
                return(NotSupported(invocation));
            }

            Expression target;
            int        firstArgumentPosition;

            Match m = getMethodFromHandlePattern.Match(invocation.Arguments.ElementAt(0));

            if (m.Success)
            {
                target = null;
                firstArgumentPosition = 1;
            }
            else
            {
                m = getMethodFromHandlePattern.Match(invocation.Arguments.ElementAt(1));
                if (!m.Success)
                {
                    return(NotSupported(invocation));
                }
                target = invocation.Arguments.ElementAt(0);
                firstArgumentPosition = 2;
            }

            IMethod mr = m.Get <AstNode>("method").Single().Annotation <IMethod>();

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

            Expression convertedTarget;

            if (target == null || target is NullReferenceExpression)
            {
                // static method
                if (m.Has("declaringType"))
                {
                    convertedTarget = new TypeReferenceExpression(m.Get <AstType>("declaringType").Single().Clone());
                }
                else
                {
                    convertedTarget = new TypeReferenceExpression(AstBuilder.ConvertType(mr.DeclaringType, stringBuilder));
                }
            }
            else
            {
                convertedTarget = Convert(target);
                if (convertedTarget == null)
                {
                    return(null);
                }
            }

            MemberReferenceExpression mre = convertedTarget.Member(mr.Name, mr);
            MethodSpec gim = mr as MethodSpec;

            if (gim != null && gim.GenericInstMethodSig != null)
            {
                foreach (TypeSig tr in gim.GenericInstMethodSig.GenericArguments)
                {
                    mre.TypeArguments.Add(AstBuilder.ConvertType(tr, stringBuilder));
                }
            }
            IList <Expression> arguments = null;

            if (invocation.Arguments.Count == firstArgumentPosition + 1)
            {
                Expression argumentArray = invocation.Arguments.ElementAt(firstArgumentPosition);
                arguments = ConvertExpressionsArray(argumentArray);
            }
            if (arguments == null)
            {
                arguments = new List <Expression>();
                foreach (Expression argument in invocation.Arguments.Skip(firstArgumentPosition))
                {
                    Expression convertedArgument = Convert(argument);
                    if (convertedArgument == null)
                    {
                        return(null);
                    }
                    arguments.Add(convertedArgument);
                }
            }
            MethodDef methodDef = mr.Resolve();

            if (methodDef != null && methodDef.IsGetter)
            {
                PropertyDef indexer = AstMethodBodyBuilder.GetIndexer(methodDef);
                if (indexer != null)
                {
                    return(new IndexerExpression(mre.Target.Detach(), arguments).WithAnnotation(indexer));
                }
            }
            return(new InvocationExpression(mre, arguments).WithAnnotation(mr));
        }
Пример #11
0
 public void Return(AstMethodBodyBuilder builder)
 {
     astMethodBodyBuilderPool.Free(builder);
 }
Пример #12
0
        /// <summary>
        /// Public translation interface.
        /// Translates the given method to HLSL
        /// </summary>
        /// <param name="s">Shader type definition.</param>
        /// <param name="m">A method representing a shader to translate.</param>
        /// <param name="attr">The shader type as attribute (either FragmentShaderAttribute or VertexShaderAttribute</param>
        /// <param name="type">The shader type as ShaderType</param>
        /// <returns>The translated GLSL shader source</returns>
        public FunctionDescription Transform(TypeDefinition s, MethodDefinition m, CustomAttribute attr,
                                             ShaderType type)
        {
            if (s == null)
            {
                throw new ArgumentNullException("s");
            }

            if (m == null)
            {
                throw new ArgumentNullException("m");
            }

            if (attr == null)
            {
                throw new ArgumentNullException("attr");
            }

            var sbase = s.BaseType.Resolve();

            while (sbase.MetadataToken.ToInt32() != typeof(Shader).MetadataToken)
            {
                sbase = sbase.BaseType.Resolve();
            }

            var dctx = new DecompilerContext(s.Module)
            {
                CurrentType       = s,
                CurrentMethod     = m,
                CancellationToken = CancellationToken.None
            };
            var d = AstMethodBodyBuilder.CreateMethodBody(m, dctx);

            //var ctx = new CecilTypeResolveContext(sbase.Module);

            var loader   = new CecilLoader();
            var mscorlib = loader.LoadAssemblyFile(typeof(object).Assembly.Location);
            var slsharp  = loader.LoadAssembly(sbase.Module.Assembly);
            var project  = loader.LoadAssembly(s.Module.Assembly);

            var ctx      = new CompositeTypeResolveContext(new[] { project, slsharp, mscorlib });
            var resolver = new CSharpResolver(ctx, CancellationToken.None)
            {
                UsingScope = new UsingScope(project)
            };

            /*
             * foreach (var v in m.Body.Variables)
             * {
             *  resolver.AddVariable(v.VariableType, null, v.Name)
             * }*/

            //resolver.AddVariable()

            //resolver.LocalVariables = m.Body.Variables;


            // TODO: need a more sane way to get the correct class + member
            var ss = ctx.GetAllTypes().First(c => c.FullName == s.FullName);

            resolver.CurrentTypeDefinition = ss;
            resolver.CurrentMember         = ss.Methods.First(n => SameMethod(m, n, ctx));

            var rv = new ResolveVisitor(resolver, new ParsedFile("memory", resolver.UsingScope), null);

            var glsl = new HlslVisitor(d, attr, rv, dctx);

            _functions.UnionWith(glsl.Functions);

            var entry = (bool)attr.ConstructorArguments.FirstOrDefault().Value;
            var sig   = HlslVisitor.GetSignature(m);

            var code = glsl.Result;
            var desc = new FunctionDescription(Shader.GetMethodName(m), sig + code, entry, type);

            _dependencies.UnionWith(glsl.Dependencies);

            return(desc);
        }
Пример #13
0
        bool HandleAnonymousMethod(ObjectCreateExpression objectCreateExpression, Expression target, MethodReference methodRef)
        {
            if (!context.Settings.AnonymousMethods)
            {
                return(false);                // anonymous method decompilation is disabled
            }
            // 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.Parameters.AddRange(AstBuilder.MakeParameters(method.Parameters));
            ame.HasParameterList = true;

            // Decompile the anonymous method:

            DecompilerContext subContext = context.Clone();

            subContext.CurrentMethod = method;
            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());
                }
            }
            if (isLambda)
            {
                LambdaExpression lambda = new LambdaExpression();
                ame.Parameters.MoveTo(lambda.Parameters);
                Expression returnExpr = ((ReturnStatement)body.Statements.Single()).Expression;
                returnExpr.Remove();
                lambda.Body = returnExpr;
                objectCreateExpression.ReplaceWith(lambda);
            }
            else
            {
                ame.Body = body;
                objectCreateExpression.ReplaceWith(ame);
            }
            return(true);
        }
Пример #14
0
        IEnumerable <Tuple <string, string> > WriteCodeFilesInProject(ModuleDefinition module, DecompilationOptions options, HashSet <string> directories)
        {
            var files = module.Types.Where(t => IncludeTypeWhenDecompilingProject(t, options)).GroupBy(
                delegate(TypeDefinition type)
            {
                string file = CleanUpName(type.Name);
                if (string.IsNullOrEmpty(type.Namespace))
                {
                    return(file);
                }
                else
                {
                    return(file);

                    /*string dir = CleanUpName(type.Namespace);
                     * if (OnlyIncludeNameSpace == null || OnlyIncludeNameSpace == type.Namespace)
                     * {
                     *  if (directories.Add(dir))
                     *      Directory.CreateDirectory(Path.Combine(options.SaveAsProjectDirectory, dir));
                     * }*/
                    //return Path.Combine(dir, file);
                }
            }, StringComparer.OrdinalIgnoreCase).ToList();

            AstMethodBodyBuilder.ClearUnhandledOpcodes();
            Parallel.ForEach(
                files,
                new ParallelOptions {
                MaxDegreeOfParallelism = Environment.ProcessorCount
            },
                delegate(IGrouping <string, TypeDefinition> file)
            {
                var path     = options.SaveAsProjectDirectory;
                var t        = file.First <TypeDefinition>();
                string fname = file.Key;
                if (IsNeedWriteHpp(t, OnlyIncludeNameSpace))
                {
                    var HppPath = Path.Combine(path, "include");
                    HppPath     = Path.Combine(HppPath, "QuantKit");
                    Directory.CreateDirectory(HppPath);
                    using (StreamWriter w = new StreamWriter(Path.Combine(HppPath, file.Key + HppFileExtension)))
                    {
/*                            AstBuilder codeDomBuilder = CreateAstBuilder(options, currentModule: module);
 *                          foreach (TypeDefinition type in file)
 *                          {
 *                              codeDomBuilder.AddType(type);
 *                          }
 *                          PreProcess(module);
 *                          codeDomBuilder.RunTransformations(transformAbortCondition);*/
                        //WriteHppCode(t, FindDeclaration(t, codeDomBuilder), new PlainTextOutput(w));
                        WriteHppCode(t, new PlainTextOutput(w));
                    }
                }

                if (IsNeedWriteHxx(t, OnlyIncludeNameSpace))
                {
                    var HxxPath = Path.Combine(path, "src");
                    Directory.CreateDirectory(HxxPath);
                    using (StreamWriter w = new StreamWriter(Path.Combine(HxxPath, file.Key + HxxFileExtension)))
                    {
                        AstBuilder codeDomBuilder = CreateAstBuilder(options, currentModule: module);
                        foreach (TypeDefinition type in file)
                        {
                            codeDomBuilder.AddType(type);
                        }
                        PreProcess(module);
                        codeDomBuilder.RunTransformations(transformAbortCondition);
                        WriteHxxCode(t, new PlainTextOutput(w));
                    }
                }
                if (IsNeedWriteCpp(t, OnlyIncludeNameSpace))
                {
                    var CppPath = Path.Combine(path, "src");
                    Directory.CreateDirectory(CppPath);
                    using (StreamWriter w = new StreamWriter(Path.Combine(CppPath, file.Key + CppFileExtension)))
                    {
                        AstBuilder codeDomBuilder = CreateAstBuilder(options, currentModule: module);
                        foreach (TypeDefinition type in file)
                        {
                            codeDomBuilder.AddType(type);
                        }
                        PreProcess(module);
                        codeDomBuilder.RunTransformations(transformAbortCondition);
                        WriteCppCode(t, new PlainTextOutput(w));
                    }
                }

                /*using (StreamWriter w = new StreamWriter(Path.Combine(options.SaveAsProjectDirectory, file.Key)))
                 * {
                 *  AstBuilder codeDomBuilder = CreateAstBuilder(options, currentModule: module);
                 *  foreach (TypeDefinition type in file)
                 *  {
                 *      codeDomBuilder.AddType(type);
                 *  }
                 *  PreProcess(module);
                 *  codeDomBuilder.RunTransformations(transformAbortCondition);
                 *  GenerateCplusplusCode(codeDomBuilder, new PlainTextOutput(w), "SmartQuant");
                 * }*/
            });
            AstMethodBodyBuilder.PrintNumberOfUnhandledOpcodes();
            return(files.Select(f => Tuple.Create("Compile", f.Key)));
        }