Exemplo n.º 1
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;
        }