예제 #1
0
            public override StringBuilder VisitInvocationExpression(InvocationExpression invocationExpression, int data)
            {
                var result = new StringBuilder();

                var mref = invocationExpression.Annotation <MethodReference>();
                var m    = mref != null?mref.Resolve() : invocationExpression.Annotation <MethodDefinition>();

                if (m.DeclaringType.MetadataToken.ToInt32() == typeof(ASLShader).MetadataToken)
                {
                    if (m.Name == "__output")
                    {
                        return(result.Append(ArgsToString(invocationExpression.Arguments)));
                    }
                    else
                    {
                        return(result.Append(m.Name).Append("(").Append(ArgsToString(invocationExpression.Arguments)).Append(")"));
                    }
                }

                RegisterMethod(m);
                result.Append(m.Name);
                result.Append("(").Append(ArgsToString(invocationExpression.Arguments)).Append(")");

                return(result);
            }
예제 #2
0
        /// <summary>
        ///     Translates an invocation expression, e.g. "Math.Max(10, 5)".
        /// </summary>
        public override StringBuilder VisitInvocationExpression(InvocationExpression invocationExpr)
        {
            var result = new StringBuilder();

            var methodDef = invocationExpr.Annotation <MethodDefinition>() ??
                            invocationExpr.Annotation <MethodReference>().Resolve();

            var methodName = methodDef.Name;
            var declType   = methodDef.DeclaringType.ToType();

            var args = JoinArgs(invocationExpr.Arguments).ToString();

            // map method if it's a mathematical method or
            // map method if it's a xSLShader class' method
            if (ShaderMapping.Types.ContainsKey(declType))
            {
                if (ShaderMapping.Methods.ContainsKey(methodName))
                {
                    var mappedName = ShaderMapping.Methods[methodName];
                    return(result.Method(mappedName, args));
                }
            }

            // otherwise just call the method
            if (declType != typeof(xSLShader))
            {
                RefMethods.Add(methodDef);
            }

            return(result.Method(methodDef.Name, args));
        }
예제 #3
0
        public override AstNode VisitInvocationExpression(InvocationExpression invocationExpression, ICecilArgumentsResolver argumentsResolver)
        {
            MethodReference reference = null;

            invocationExpression.Arguments.ForEach(a => a.AcceptVisitor(this, argumentsResolver));
            invocationExpression.Target.AcceptVisitor(this, argumentsResolver);
            var specification = invocationExpression.Annotation <MethodSpecification>();

            if (specification != null && specification.IsGenericInstance)
            {
                var genericMethod    = specification as GenericInstanceMethod;
                var genericArguments = genericMethod.GenericArguments.ToArray();
                var parameters       = genericMethod.Parameters.Select(p => p.ParameterType);
                reference = specification.GetElementMethod();

                reference = ResolveGenericMethod(parameters, reference, genericArguments, argumentsResolver);
                invocationExpression.RemoveAnnotations <MethodSpecification>();
                invocationExpression.AddAnnotation(reference);
            }
            else
            {
                reference = invocationExpression.Annotation <MethodReference>();

                if (reference != null)
                {
                    TypeReference returnType    = reference.ReturnType;
                    TypeReference declaringType = reference.DeclaringType;

                    if (declaringType.IsGenericInstance || returnType.IsGenericParameter)
                    {
                        if (declaringType.IsGenericInstance)
                        {
                            var genericMethod = declaringType as GenericInstanceType;
                            var parameters    = reference.Parameters.Select(p => p.ParameterType);

                            reference = ResolveGenericMethod(parameters, reference, genericMethod.GenericArguments, argumentsResolver);
                            genericMethod.GenericArguments.Clear();
                            reference.GenericParameters.ForEach(p => genericMethod.GenericArguments.Add(p));
                        }

                        if (reference.ReturnType.IsGenericParameter)
                        {
                            var genericInstanceType = declaringType as GenericInstanceType;
                            var genericParameter    = reference.ReturnType as GenericParameter;
                            var genericReturnType   = genericParameter.GetGenericActualType(genericInstanceType.GenericArguments.ToArray());

                            reference = reference.MakeGenericMethod(new TypeReference[] { }, genericReturnType);
                        }

                        invocationExpression.RemoveAnnotations <MethodReference>();
                        invocationExpression.AddAnnotation(reference);
                    }
                }
            }

            return(invocationExpression);
        }
		public static bool CouldBeExpressionTree(InvocationExpression expr)
		{
			if (expr != null && expr.Arguments.Count == 2) {
				IMethod mr = expr.Annotation<IMethod>();
				return mr != null && mr.Name == "Lambda" && mr.DeclaringType.FullName == "System.Linq.Expressions.Expression";
			}
			return false;
		}
예제 #5
0
 public static bool CouldBeExpressionTree(InvocationExpression expr)
 {
     if (expr != null && expr.Arguments.Count == 2)
     {
         IMethod mr = expr.Annotation <IMethod>();
         return(mr != null && mr.Name == "Lambda" && mr.DeclaringType != null && mr.DeclaringType.FullName == "System.Linq.Expressions.Expression");
     }
     return(false);
 }
예제 #6
0
        public override StringBuilder VisitInvocationExpression(InvocationExpression invocationExpression, int data)
        {
            var result = new StringBuilder();

            var mref = invocationExpression.Annotation <MethodReference>();
            var m    = mref != null?mref.Resolve() : invocationExpression.Annotation <MethodDefinition>();

            if (m.DeclaringType.MetadataToken.ToInt32() == typeof(ShaderDefinition).MetadataToken)
            {
                return(VisitShaderDefCall(m, invocationExpression));
            }

            RegisterMethod(m);
            result.Append(Shader.GetMethodName(m));
            result.Append("(").Append(ArgsToString(invocationExpression.Arguments)).Append(")");

            return(result);
        }
예제 #7
0
        public override bool DoMatch(INode other, Match match)
        {
            InvocationExpression ie = other as InvocationExpression;

            if (ie != null && ie.Annotation <LdTokenAnnotation>() != null && ie.Arguments.Count == 1)
            {
                return(childNode.DoMatch(ie.Arguments.Single(), match));
            }
            return(false);
        }
예제 #8
0
        private bool IsLambdaInvocation(InvocationExpression invocation)
        {
            if (invocation != null)
            {
                var methodReference = invocation.Annotation <MethodReference>();

                if (methodReference.Name.Equals("Lambda") && methodReference.DeclaringType.FullName.Equals("System.Linq.Expressions.Expression"))
                {
                    return(true);
                }
            }

            return(false);
        }
        public override object VisitConstructorDeclaration(ConstructorDeclaration constructorDeclaration, object data)
        {
            ExpressionStatement stmt = constructorDeclaration.Body.Statements.FirstOrDefault() as ExpressionStatement;

            if (stmt == null)
            {
                return(null);
            }
            InvocationExpression invocation = stmt.Expression as InvocationExpression;

            if (invocation == null)
            {
                return(null);
            }
            MemberReferenceExpression mre = invocation.Target as MemberReferenceExpression;

            if (mre != null && mre.MemberName == ".ctor")
            {
                ConstructorInitializer ci = new ConstructorInitializer();
                if (mre.Target is ThisReferenceExpression)
                {
                    ci.ConstructorInitializerType = ConstructorInitializerType.This;
                }
                else if (mre.Target is BaseReferenceExpression)
                {
                    ci.ConstructorInitializerType = ConstructorInitializerType.Base;
                }
                else
                {
                    return(null);
                }
                // Move arguments from invocation to initializer:
                invocation.Arguments.MoveTo(ci.Arguments);
                var ilRanges = stmt.GetAllRecursiveILRanges();
                // Add the initializer: (unless it is the default 'base()')
                if (!(ci.ConstructorInitializerType == ConstructorInitializerType.Base && ci.Arguments.Count == 0))
                {
                    constructorDeclaration.Initializer = ci.WithAnnotation(invocation.Annotation <IMethod>());
                    ci.AddAnnotation(ilRanges);
                }
                else
                {
                    constructorDeclaration.Body.HiddenStart = NRefactoryExtensions.CreateHidden(ilRanges, constructorDeclaration.Body.HiddenStart);
                }
                // Remove the statement:
                stmt.Remove();
            }
            return(null);
        }
예제 #10
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));
        }
예제 #11
0
        public override StringBuilder VisitInvocationExpression(InvocationExpression invocationExpression, int data)
        {
            var result = new StringBuilder();

            var mref = invocationExpression.Annotation<MethodReference>();
            var m = mref != null ? mref.Resolve() : invocationExpression.Annotation<MethodDefinition>();

            if (m.DeclaringType.MetadataToken.ToInt32() == typeof(ShaderDefinition).MetadataToken)
                return VisitShaderDefCall(m, invocationExpression);

            RegisterMethod(m);
            result.Append(Shader.GetMethodName(m));
            result.Append("(").Append(ArgsToString(invocationExpression.Arguments)).Append(")");

            return result;
        }
예제 #12
0
        public override object VisitInvocationExpression(InvocationExpression invocationExpression, object data)
        {
            base.VisitInvocationExpression(invocationExpression, data);

            MethodReference methodRef = invocationExpression.Annotation <MethodReference>();

            if (methodRef == null)
            {
                return(null);
            }
            var arguments = invocationExpression.Arguments.ToArray();

            // Reduce "String.Concat(a, b)" to "a + b"
            if (methodRef.Name == "Concat" && methodRef.DeclaringType.FullName == "System.String" && arguments.Length >= 2)
            {
                invocationExpression.Arguments.Clear();                 // detach arguments from invocationExpression
                Expression expr = arguments[0];
                for (int i = 1; i < arguments.Length; i++)
                {
                    expr = new BinaryOperatorExpression(expr, BinaryOperatorType.Add, arguments[i]);
                }
                invocationExpression.ReplaceWith(expr);
                return(null);
            }

            switch (methodRef.FullName)
            {
            case "System.Type System.Type::GetTypeFromHandle(System.RuntimeTypeHandle)":
                if (arguments.Length == 1)
                {
                    if (typeHandleOnTypeOfPattern.IsMatch(arguments[0]))
                    {
                        invocationExpression.ReplaceWith(((MemberReferenceExpression)arguments[0]).Target);
                        return(null);
                    }
                }
                break;
            }

            BinaryOperatorType?bop = GetBinaryOperatorTypeFromMetadataName(methodRef.Name);

            if (bop != null && arguments.Length == 2)
            {
                invocationExpression.Arguments.Clear();                 // detach arguments from invocationExpression
                invocationExpression.ReplaceWith(
                    new BinaryOperatorExpression(arguments[0], bop.Value, arguments[1]).WithAnnotation(methodRef)
                    );
                return(null);
            }
            UnaryOperatorType?uop = GetUnaryOperatorTypeFromMetadataName(methodRef.Name);

            if (uop != null && arguments.Length == 1)
            {
                arguments[0].Remove();                 // detach argument
                invocationExpression.ReplaceWith(
                    new UnaryOperatorExpression(uop.Value, arguments[0]).WithAnnotation(methodRef)
                    );
                return(null);
            }
            if (methodRef.Name == "op_Explicit" && arguments.Length == 1)
            {
                arguments[0].Remove();                 // detach argument
                invocationExpression.ReplaceWith(
                    arguments[0].CastTo(AstBuilder.ConvertType(methodRef.ReturnType, methodRef.MethodReturnType))
                    .WithAnnotation(methodRef)
                    );
                return(null);
            }
            if (methodRef.Name == "op_Implicit" && arguments.Length == 1)
            {
                invocationExpression.ReplaceWith(arguments[0]);
                return(null);
            }
            if (methodRef.Name == "op_True" && arguments.Length == 1 && invocationExpression.Role == AstNode.Roles.Condition)
            {
                invocationExpression.ReplaceWith(arguments[0]);
                return(null);
            }

            return(null);
        }
예제 #13
0
        Expression Convert(Expression expr)
        {
            InvocationExpression invocation = expr as InvocationExpression;

            if (invocation != null)
            {
                IMethod mr = invocation.Annotation <IMethod>();
                if (mr != null && mr.DeclaringType != null && mr.DeclaringType.FullName == "System.Linq.Expressions.Expression")
                {
                    switch (mr.Name)
                    {
                    case "Add":
                        return(ConvertBinaryOperator(invocation, BinaryOperatorType.Add, false));

                    case "AddChecked":
                        return(ConvertBinaryOperator(invocation, BinaryOperatorType.Add, true));

                    case "AddAssign":
                        return(ConvertAssignmentOperator(invocation, AssignmentOperatorType.Add, false));

                    case "AddAssignChecked":
                        return(ConvertAssignmentOperator(invocation, AssignmentOperatorType.Add, true));

                    case "And":
                        return(ConvertBinaryOperator(invocation, BinaryOperatorType.BitwiseAnd));

                    case "AndAlso":
                        return(ConvertBinaryOperator(invocation, BinaryOperatorType.ConditionalAnd));

                    case "AndAssign":
                        return(ConvertAssignmentOperator(invocation, AssignmentOperatorType.BitwiseAnd));

                    case "ArrayAccess":
                    case "ArrayIndex":
                        return(ConvertArrayIndex(invocation));

                    case "ArrayLength":
                        return(ConvertArrayLength(invocation));

                    case "Assign":
                        return(ConvertAssignmentOperator(invocation, AssignmentOperatorType.Assign));

                    case "Call":
                        return(ConvertCall(invocation));

                    case "Coalesce":
                        return(ConvertBinaryOperator(invocation, BinaryOperatorType.NullCoalescing));

                    case "Condition":
                        return(ConvertCondition(invocation));

                    case "Constant":
                        if (invocation.Arguments.Count >= 1)
                        {
                            return(invocation.Arguments.First().Clone());
                        }
                        else
                        {
                            return(NotSupported(expr));
                        }

                    case "Convert":
                        return(ConvertCast(invocation, false));

                    case "ConvertChecked":
                        return(ConvertCast(invocation, true));

                    case "Divide":
                        return(ConvertBinaryOperator(invocation, BinaryOperatorType.Divide));

                    case "DivideAssign":
                        return(ConvertAssignmentOperator(invocation, AssignmentOperatorType.Divide));

                    case "Equal":
                        return(ConvertBinaryOperator(invocation, BinaryOperatorType.Equality));

                    case "ExclusiveOr":
                        return(ConvertBinaryOperator(invocation, BinaryOperatorType.ExclusiveOr));

                    case "ExclusiveOrAssign":
                        return(ConvertAssignmentOperator(invocation, AssignmentOperatorType.ExclusiveOr));

                    case "Field":
                        return(ConvertField(invocation));

                    case "GreaterThan":
                        return(ConvertBinaryOperator(invocation, BinaryOperatorType.GreaterThan));

                    case "GreaterThanOrEqual":
                        return(ConvertBinaryOperator(invocation, BinaryOperatorType.GreaterThanOrEqual));

                    case "Invoke":
                        return(ConvertInvoke(invocation));

                    case "Lambda":
                        return(ConvertLambda(invocation));

                    case "LeftShift":
                        return(ConvertBinaryOperator(invocation, BinaryOperatorType.ShiftLeft));

                    case "LeftShiftAssign":
                        return(ConvertAssignmentOperator(invocation, AssignmentOperatorType.ShiftLeft));

                    case "LessThan":
                        return(ConvertBinaryOperator(invocation, BinaryOperatorType.LessThan));

                    case "LessThanOrEqual":
                        return(ConvertBinaryOperator(invocation, BinaryOperatorType.LessThanOrEqual));

                    case "ListInit":
                        return(ConvertListInit(invocation));

                    case "MemberInit":
                        return(ConvertMemberInit(invocation));

                    case "Modulo":
                        return(ConvertBinaryOperator(invocation, BinaryOperatorType.Modulus));

                    case "ModuloAssign":
                        return(ConvertAssignmentOperator(invocation, AssignmentOperatorType.Modulus));

                    case "Multiply":
                        return(ConvertBinaryOperator(invocation, BinaryOperatorType.Multiply, false));

                    case "MultiplyChecked":
                        return(ConvertBinaryOperator(invocation, BinaryOperatorType.Multiply, true));

                    case "MultiplyAssign":
                        return(ConvertAssignmentOperator(invocation, AssignmentOperatorType.Multiply, false));

                    case "MultiplyAssignChecked":
                        return(ConvertAssignmentOperator(invocation, AssignmentOperatorType.Multiply, true));

                    case "Negate":
                        return(ConvertUnaryOperator(invocation, UnaryOperatorType.Minus, false));

                    case "NegateChecked":
                        return(ConvertUnaryOperator(invocation, UnaryOperatorType.Minus, true));

                    case "New":
                        return(ConvertNewObject(invocation));

                    case "NewArrayBounds":
                        return(ConvertNewArrayBounds(invocation));

                    case "NewArrayInit":
                        return(ConvertNewArrayInit(invocation));

                    case "Not":
                        return(ConvertUnaryOperator(invocation, UnaryOperatorType.Not));

                    case "NotEqual":
                        return(ConvertBinaryOperator(invocation, BinaryOperatorType.InEquality));

                    case "OnesComplement":
                        return(ConvertUnaryOperator(invocation, UnaryOperatorType.BitNot));

                    case "Or":
                        return(ConvertBinaryOperator(invocation, BinaryOperatorType.BitwiseOr));

                    case "OrAssign":
                        return(ConvertAssignmentOperator(invocation, AssignmentOperatorType.BitwiseOr));

                    case "OrElse":
                        return(ConvertBinaryOperator(invocation, BinaryOperatorType.ConditionalOr));

                    case "Property":
                        return(ConvertProperty(invocation));

                    case "Quote":
                        if (invocation.Arguments.Count == 1)
                        {
                            return(Convert(invocation.Arguments.Single()));
                        }
                        else
                        {
                            return(NotSupported(invocation));
                        }

                    case "RightShift":
                        return(ConvertBinaryOperator(invocation, BinaryOperatorType.ShiftRight));

                    case "RightShiftAssign":
                        return(ConvertAssignmentOperator(invocation, AssignmentOperatorType.ShiftRight));

                    case "Subtract":
                        return(ConvertBinaryOperator(invocation, BinaryOperatorType.Subtract, false));

                    case "SubtractChecked":
                        return(ConvertBinaryOperator(invocation, BinaryOperatorType.Subtract, true));

                    case "SubtractAssign":
                        return(ConvertAssignmentOperator(invocation, AssignmentOperatorType.Subtract, false));

                    case "SubtractAssignChecked":
                        return(ConvertAssignmentOperator(invocation, AssignmentOperatorType.Subtract, true));

                    case "TypeAs":
                        return(ConvertTypeAs(invocation));

                    case "TypeIs":
                        return(ConvertTypeIs(invocation));
                    }
                }
            }
            IdentifierExpression ident = expr as IdentifierExpression;

            if (ident != null)
            {
                ILVariable v = ident.Annotation <ILVariable>();
                if (v != null)
                {
                    foreach (LambdaExpression lambda in activeLambdas)
                    {
                        foreach (ParameterDeclaration p in lambda.Parameters)
                        {
                            if (p.Annotation <ILVariable>() == v)
                            {
                                return(IdentifierExpression.Create(p.Name, v.IsParameter ? TextTokenKind.Parameter : TextTokenKind.Local).WithAnnotation(v));
                            }
                        }
                    }
                }
            }
            return(NotSupported(expr));
        }
예제 #14
0
파일: CsToTs.cs 프로젝트: RReverser/Netjs
			public override void VisitInvocationExpression (InvocationExpression invocationExpression)
			{
				base.VisitInvocationExpression (invocationExpression);

				var mr = invocationExpression.Target as MemberReferenceExpression;
				if (mr == null)
					return;

				if (mr.MemberName != "Equals")
					return;

				var m = invocationExpression.Annotation<MemberReference> ();
				if (m.DeclaringType.FullName != "System.Object")
					return;

				var i = new InvocationExpression (
					        new MemberReferenceExpression (new TypeReferenceExpression (new SimpleType ("NObject")), "GenericEquals"),
					mr.Target.Clone (), invocationExpression.Arguments.First ().Clone ());

				invocationExpression.ReplaceWith (i);
			}
        internal static void ProcessInvocationExpression(InvocationExpression invocationExpression)
        {
            MethodReference methodRef = invocationExpression.Annotation <MethodReference>();

            if (methodRef == null)
            {
                return;
            }
            var arguments = invocationExpression.Arguments.ToArray();

            // Reduce "String.Concat(a, b)" to "a + b"
            if (methodRef.Name == "Concat" && methodRef.DeclaringType.FullName == "System.String" && arguments.Length >= 2)
            {
                invocationExpression.Arguments.Clear(); // detach arguments from invocationExpression
                Expression expr = arguments[0];
                for (int i = 1; i < arguments.Length; i++)
                {
                    expr = new BinaryOperatorExpression(expr, BinaryOperatorType.Add, arguments[i]);
                }
                invocationExpression.ReplaceWith(expr);
                return;
            }

            switch (methodRef.FullName)
            {
            case "System.Type System.Type::GetTypeFromHandle(System.RuntimeTypeHandle)":
                if (arguments.Length == 1)
                {
                    if (typeHandleOnTypeOfPattern.IsMatch(arguments[0]))
                    {
                        invocationExpression.ReplaceWith(((MemberReferenceExpression)arguments[0]).Target);
                        return;
                    }
                }
                break;

            case "System.Reflection.FieldInfo System.Reflection.FieldInfo::GetFieldFromHandle(System.RuntimeFieldHandle)":
                if (arguments.Length == 1)
                {
                    MemberReferenceExpression mre = arguments[0] as MemberReferenceExpression;
                    if (mre != null && mre.MemberName == "FieldHandle" && mre.Target.Annotation <LdTokenAnnotation>() != null)
                    {
                        invocationExpression.ReplaceWith(mre.Target);
                        return;
                    }
                }
                break;

            case "System.Reflection.FieldInfo System.Reflection.FieldInfo::GetFieldFromHandle(System.RuntimeFieldHandle,System.RuntimeTypeHandle)":
                if (arguments.Length == 2)
                {
                    MemberReferenceExpression mre1 = arguments[0] as MemberReferenceExpression;
                    MemberReferenceExpression mre2 = arguments[1] as MemberReferenceExpression;
                    if (mre1 != null && mre1.MemberName == "FieldHandle" && mre1.Target.Annotation <LdTokenAnnotation>() != null)
                    {
                        if (mre2 != null && mre2.MemberName == "TypeHandle" && mre2.Target is TypeOfExpression)
                        {
                            Expression     oldArg = ((InvocationExpression)mre1.Target).Arguments.Single();
                            FieldReference field  = oldArg.Annotation <FieldReference>();
                            if (field != null)
                            {
                                AstType declaringType = ((TypeOfExpression)mre2.Target).Type.Detach();
                                oldArg.ReplaceWith(declaringType.Member(field.Name).WithAnnotation(field));
                                invocationExpression.ReplaceWith(mre1.Target);
                                return;
                            }
                        }
                    }
                }
                break;
            }

            BinaryOperatorType?bop = GetBinaryOperatorTypeFromMetadataName(methodRef.Name);

            if (bop != null && arguments.Length == 2)
            {
                invocationExpression.Arguments.Clear(); // detach arguments from invocationExpression
                invocationExpression.ReplaceWith(
                    new BinaryOperatorExpression(arguments[0], bop.Value, arguments[1]).WithAnnotation(methodRef)
                    );
                return;
            }
            UnaryOperatorType?uop = GetUnaryOperatorTypeFromMetadataName(methodRef.Name);

            if (uop != null && arguments.Length == 1)
            {
                arguments[0].Remove(); // detach argument
                invocationExpression.ReplaceWith(
                    new UnaryOperatorExpression(uop.Value, arguments[0]).WithAnnotation(methodRef)
                    );
                return;
            }
            if (methodRef.Name == "op_Explicit" && arguments.Length == 1)
            {
                arguments[0].Remove(); // detach argument
                invocationExpression.ReplaceWith(
                    arguments[0].CastTo(AstBuilder.ConvertType(methodRef.ReturnType, methodRef.MethodReturnType))
                    .WithAnnotation(methodRef)
                    );
                return;
            }
            if (methodRef.Name == "op_Implicit" && arguments.Length == 1)
            {
                invocationExpression.ReplaceWith(arguments[0]);
                return;
            }
            if (methodRef.Name == "op_True" && arguments.Length == 1 && invocationExpression.Role == Roles.Condition)
            {
                invocationExpression.ReplaceWith(arguments[0]);
                return;
            }

            return;
        }
예제 #16
0
        internal static void ProcessInvocationExpression(InvocationExpression invocationExpression, StringBuilder sb)
        {
            IMethod methodRef = invocationExpression.Annotation <IMethod>();

            if (methodRef == null)
            {
                return;
            }
            var arguments = invocationExpression.Arguments.ToArray();

            // Reduce "String.Concat(a, b)" to "a + b"
            if (methodRef.Name == "Concat" && methodRef.DeclaringType != null && arguments.Length >= 2 && methodRef.DeclaringType.FullName == "System.String")
            {
                invocationExpression.Arguments.Clear();                 // detach arguments from invocationExpression
                Expression expr = arguments[0];
                for (int i = 1; i < arguments.Length; i++)
                {
                    expr = new BinaryOperatorExpression(expr, BinaryOperatorType.Add, arguments[i]);
                }
                invocationExpression.ReplaceWith(expr);
                expr.AddAnnotation(invocationExpression.GetAllRecursiveILRanges());
                return;
            }

            bool isSupportedType = CheckType(methodRef.DeclaringType, systemString, typeString) ||
                                   CheckType(methodRef.DeclaringType, systemReflectionString, fieldInfoString);

            switch (isSupportedType ? methodRef.Name.String : string.Empty)
            {
            case "GetTypeFromHandle":
                if (arguments.Length == 1 && methodRef.FullName == "System.Type System.Type::GetTypeFromHandle(System.RuntimeTypeHandle)")
                {
                    if (typeHandleOnTypeOfPattern.IsMatch(arguments[0]))
                    {
                        invocationExpression.ReplaceWith(((MemberReferenceExpression)arguments[0]).Target
                                                         .WithAnnotation(invocationExpression.GetAllRecursiveILRanges()));
                        return;
                    }
                }
                break;

            case "GetFieldFromHandle":
                if (arguments.Length == 1 && methodRef.FullName == "System.Reflection.FieldInfo System.Reflection.FieldInfo::GetFieldFromHandle(System.RuntimeFieldHandle)")
                {
                    MemberReferenceExpression mre = arguments[0] as MemberReferenceExpression;
                    if (mre != null && mre.MemberName == "FieldHandle" && mre.Target.Annotation <LdTokenAnnotation>() != null)
                    {
                        invocationExpression.ReplaceWith(mre.Target
                                                         .WithAnnotation(invocationExpression.GetAllRecursiveILRanges()));
                        return;
                    }
                }
                else if (arguments.Length == 2 && methodRef.FullName == "System.Reflection.FieldInfo System.Reflection.FieldInfo::GetFieldFromHandle(System.RuntimeFieldHandle,System.RuntimeTypeHandle)")
                {
                    MemberReferenceExpression mre1 = arguments[0] as MemberReferenceExpression;
                    MemberReferenceExpression mre2 = arguments[1] as MemberReferenceExpression;
                    if (mre1 != null && mre1.MemberName == "FieldHandle" && mre1.Target.Annotation <LdTokenAnnotation>() != null)
                    {
                        if (mre2 != null && mre2.MemberName == "TypeHandle" && mre2.Target is TypeOfExpression)
                        {
                            Expression oldArg = ((InvocationExpression)mre1.Target).Arguments.Single();
                            IField     field  = oldArg.Annotation <IField>();
                            if (field != null)
                            {
                                var     ilRanges      = invocationExpression.GetAllRecursiveILRanges();
                                AstType declaringType = ((TypeOfExpression)mre2.Target).Type.Detach();
                                oldArg.ReplaceWith(declaringType.Member(field.Name, field).WithAnnotation(field));
                                invocationExpression.ReplaceWith(mre1.Target.WithAnnotation(ilRanges));
                                return;
                            }
                        }
                    }
                }
                break;
            }

            BinaryOperatorType?bop = GetBinaryOperatorTypeFromMetadataName(methodRef.Name);

            if (bop != null && arguments.Length == 2)
            {
                invocationExpression.Arguments.Clear();                 // detach arguments from invocationExpression
                invocationExpression.ReplaceWith(
                    new BinaryOperatorExpression(arguments[0], bop.Value, arguments[1]).WithAnnotation(methodRef)
                    .WithAnnotation(invocationExpression.GetAllRecursiveILRanges())
                    );
                return;
            }
            UnaryOperatorType?uop = GetUnaryOperatorTypeFromMetadataName(methodRef.Name);

            if (uop != null && arguments.Length == 1)
            {
                arguments[0].Remove();                 // detach argument
                invocationExpression.ReplaceWith(
                    new UnaryOperatorExpression(uop.Value, arguments[0]).WithAnnotation(methodRef)
                    .WithAnnotation(invocationExpression.GetAllRecursiveILRanges())
                    );
                return;
            }
            if (methodRef.Name == "op_Explicit" && arguments.Length == 1)
            {
                arguments[0].Remove();                 // detach argument
                invocationExpression.ReplaceWith(
                    arguments[0].CastTo(AstBuilder.ConvertType(methodRef.MethodSig.GetRetType(), sb))
                    .WithAnnotation(methodRef)
                    .WithAnnotation(invocationExpression.GetAllRecursiveILRanges())
                    );
                return;
            }
            if (methodRef.Name == "op_Implicit" && arguments.Length == 1)
            {
                invocationExpression.ReplaceWith(arguments[0].WithAnnotation(invocationExpression.GetAllRecursiveILRanges()));
                return;
            }
            if (methodRef.Name == "op_True" && arguments.Length == 1 && invocationExpression.Role == Roles.Condition)
            {
                invocationExpression.ReplaceWith(arguments[0].WithAnnotation(invocationExpression.GetAllRecursiveILRanges()));
                return;
            }

            return;
        }
예제 #17
0
        public override void VisitInvocationExpression(InvocationExpression e)
        {
            var md = e.Annotation<MethodDefinition>();
            if (md != null && (md.IsGetter || md.IsSetter))
            {
                var p = md.DeclaringType.Properties.FirstOrDefault(x => x.GetMethod == md || x.SetMethod == md);
                if (p != null)
                {
                    // 转换为属性访问
                    var target = (e.Target as MemberReferenceExpression).Target;
                    if (p.IsIndexer())
                    {
                        IndexerExpression ie = new IndexerExpression(target.Detach()).WithAnnotation(p);
                        e.Arguments.MoveTo(ie.Arguments);
                        e.ReplaceWith(ie);
                    }
                    else
                    {
                        //MemberReferenceExpression mre = new MemberReferenceExpression(target.Detach(), p.Name).WithAnnotation(p);

                    }
                }
            }

            //[CompilerGenerated]
            //private sealed class C_e_5
            //{
            //    public Action f_1_E2DC5B04;
            //    public void M_1_void(object x)
            //    {
            //        this.f_1_E2DC5B04();
            //    }
            //}
            //
            //public ActionCommand(Action execute)
            //{
            //    Action<object> action = null;
            //    ActionCommand.C_e_5 c_e_ = new ActionCommand.C_e_5();
            //    c_e_.f_1_E2DC5B04 = execute;
            //    if (action == null)
            //    {
            //        action = new Action<object>(c_e_.M_1_void);
            //    }
            //    base..ctor(action);
            //}
            //
            //====>
            //public ActionCommand(Action execute) : base(x=>execute())
            //{
            //}



            base.VisitInvocationExpression(e);
        }