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; }
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())); }