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;
        }
예제 #2
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;
        }
        static Expression GetDefaultValueExpression(RefactoringContext context, AstType astType)
        {
            var type = context.ResolveType(astType);

            // array
            if (type.Kind == TypeKind.Array)
            {
                return(new ObjectCreateExpression(astType.Clone()));
            }

            // enum
            if (type.Kind == TypeKind.Enum)
            {
                var members = type.GetMembers().ToArray();
                if (members.Length == 0)
                {
                    return(new DefaultValueExpression(astType.Clone()));
                }
                return(astType.Member(members[0].Name, null).Clone());
            }

            if ((type.IsReferenceType ?? false) || type.Kind == TypeKind.Dynamic)
            {
                return(new NullReferenceExpression());
            }

            var typeDefinition = type.GetDefinition();

            if (typeDefinition != null)
            {
                switch (typeDefinition.KnownTypeCode)
                {
                case KnownTypeCode.Boolean:
                    return(new PrimitiveExpression(false));

                case KnownTypeCode.Char:
                    return(new PrimitiveExpression('\0'));

                case KnownTypeCode.SByte:
                case KnownTypeCode.Byte:
                case KnownTypeCode.Int16:
                case KnownTypeCode.UInt16:
                case KnownTypeCode.Int32:
                case KnownTypeCode.UInt32:
                case KnownTypeCode.Int64:
                case KnownTypeCode.UInt64:
                case KnownTypeCode.Single:
                case KnownTypeCode.Double:
                case KnownTypeCode.Decimal:
                    return(new PrimitiveExpression(0));

                case KnownTypeCode.NullableOfT:
                    return(new NullReferenceExpression());
                }
                if (type.Kind == TypeKind.Struct)
                {
                    return(new ObjectCreateExpression(astType.Clone()));
                }
            }
            return(new DefaultValueExpression(astType.Clone()));
        }