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