예제 #1
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);
        }
예제 #2
0
		bool HandleAnonymousMethod(ObjectCreateExpression objectCreateExpression, Expression target, MethodReference methodRef)
		{
			// Anonymous methods are defined in the same assembly, so there's no need to Resolve().
			MethodDefinition method = methodRef as MethodDefinition;
			if (method == null || !method.Name.StartsWith("<", StringComparison.Ordinal))
				return false;
			if (!(method.IsCompilerGenerated() || IsPotentialClosure(method.DeclaringType)))
				return false;
			
			// Decompile the anonymous method:
			
			DecompilerContext subContext = context.Clone();
			subContext.CurrentMethod = method;
			BlockStatement body = AstMethodBodyBuilder.CreateMethodBody(method, subContext);
			TransformationPipeline.RunTransformationsUntil(body, v => v is DelegateConstruction, subContext);
			body.AcceptVisitor(this, null);
			
			AnonymousMethodExpression ame = new AnonymousMethodExpression();
			bool isLambda = false;
			if (method.Parameters.All(p => string.IsNullOrEmpty(p.Name))) {
				ame.HasParameterList = false;
			} else {
				ame.HasParameterList = true;
				ame.Parameters.AddRange(AstBuilder.MakeParameters(method.Parameters));
				if (ame.Parameters.All(p => p.ParameterModifier == ParameterModifier.None)) {
					isLambda = (body.Statements.Count == 1 && body.Statements.Single() is ReturnStatement);
				}
			}
			
			// 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;
		}
예제 #3
0
파일: CsToTs.cs 프로젝트: RReverser/Netjs
			public override void VisitObjectCreateExpression (ObjectCreateExpression objectCreateExpression)
			{
				base.VisitObjectCreateExpression (objectCreateExpression);

				var td = GetTypeDef (objectCreateExpression.Type);
				if (td == null || !IsDelegate (td) || objectCreateExpression.Arguments.Count != 1)
					return;

				var a = objectCreateExpression.Arguments.First ();
				a.Remove ();

				objectCreateExpression.ReplaceWith (a);
			}
예제 #4
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);
        }
예제 #5
0
파일: CsToTs.cs 프로젝트: RReverser/Netjs
			public override void VisitObjectCreateExpression (ObjectCreateExpression objectCreateExpression)
			{
				base.VisitObjectCreateExpression (objectCreateExpression);

				if (!IsString (objectCreateExpression.Type))
					return;

				var m = new InvocationExpression (
					new MemberReferenceExpression (new TypeReferenceExpression (new SimpleType ("NString")), "FromChars"),
					        objectCreateExpression.Arguments.Select (x => x.Clone ()));

				objectCreateExpression.ReplaceWith (m);
			}