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 override void VisitInvocationExpression(InvocationExpression invocationExpression) { base.VisitInvocationExpression(invocationExpression); if (!CanTransformToExtensionMethodCall(resolver, invocationExpression, out var memberRefExpr, out var target, out var firstArgument)) { return; } var method = (IMethod)invocationExpression.GetSymbol(); if (firstArgument is DirectionExpression dirExpr) { if (!context.Settings.RefExtensionMethods || dirExpr.FieldDirection == FieldDirection.Out) { return; } firstArgument = dirExpr.Expression; target = firstArgument.GetResolveResult(); dirExpr.Detach(); } else if (firstArgument is NullReferenceExpression) { Debug.Assert(context.RequiredNamespacesSuperset.Contains(method.Parameters[0].Type.Namespace)); firstArgument = firstArgument.ReplaceWith(expr => new CastExpression(context.TypeSystemAstBuilder.ConvertType(method.Parameters[0].Type), expr.Detach())); } if (invocationExpression.Target is IdentifierExpression identifierExpression) { identifierExpression.Detach(); memberRefExpr = new MemberReferenceExpression(firstArgument.Detach(), method.Name, identifierExpression.TypeArguments.Detach()); invocationExpression.Target = memberRefExpr; } else { memberRefExpr.Target = firstArgument.Detach(); } if (invocationExpression.GetResolveResult() is CSharpInvocationResolveResult irr) { // do not forget to update the CSharpInvocationResolveResult => set IsExtensionMethodInvocation == true invocationExpression.RemoveAnnotations <CSharpInvocationResolveResult>(); var newResolveResult = new CSharpInvocationResolveResult( irr.TargetResult, irr.Member, irr.Arguments, irr.OverloadResolutionErrors, isExtensionMethodInvocation: true, irr.IsExpandedForm, irr.IsDelegateInvocation, irr.GetArgumentToParameterMap(), irr.InitializerStatements); invocationExpression.AddAnnotation(newResolveResult); } }
public override void VisitInvocationExpression(InvocationExpression invocationExpression) { base.VisitInvocationExpression(invocationExpression); var method = invocationExpression.GetSymbol() as IMethod; if (method == null || !method.IsExtensionMethod || !invocationExpression.Arguments.Any()) { return; } IReadOnlyList <IType> typeArguments; MemberReferenceExpression memberRefExpr; switch (invocationExpression.Target) { case MemberReferenceExpression mre: typeArguments = mre.TypeArguments.Any() ? method.TypeArguments : EmptyList <IType> .Instance; memberRefExpr = mre; break; case IdentifierExpression ide: typeArguments = ide.TypeArguments.Any() ? method.TypeArguments : EmptyList <IType> .Instance; memberRefExpr = null; break; default: return; } var firstArgument = invocationExpression.Arguments.First(); if (firstArgument is NamedArgumentExpression) { return; } var target = firstArgument.GetResolveResult(); if (target is ConstantResolveResult crr && crr.ConstantValue == null) { target = new ConversionResolveResult(method.Parameters[0].Type, crr, Conversion.NullLiteralConversion); } ResolveResult[] args = new ResolveResult[invocationExpression.Arguments.Count - 1]; string[] argNames = null; int pos = 0; foreach (var arg in invocationExpression.Arguments.Skip(1)) { if (arg is NamedArgumentExpression nae) { if (argNames == null) { argNames = new string[args.Length]; } argNames[pos] = nae.Name; args[pos] = nae.Expression.GetResolveResult(); } else { args[pos] = arg.GetResolveResult(); } pos++; } if (!CanTransformToExtensionMethodCall(resolver, method, typeArguments, target, args, argNames)) { return; } if (firstArgument is DirectionExpression dirExpr) { if (!context.Settings.RefExtensionMethods || dirExpr.FieldDirection == FieldDirection.Out) { return; } firstArgument = dirExpr.Expression; target = firstArgument.GetResolveResult(); dirExpr.Detach(); } else if (firstArgument is NullReferenceExpression) { Debug.Assert(context.RequiredNamespacesSuperset.Contains(method.Parameters[0].Type.Namespace)); firstArgument = firstArgument.ReplaceWith(expr => new CastExpression(context.TypeSystemAstBuilder.ConvertType(method.Parameters[0].Type), expr.Detach())); } if (invocationExpression.Target is IdentifierExpression identifierExpression) { identifierExpression.Detach(); memberRefExpr = new MemberReferenceExpression(firstArgument.Detach(), method.Name, identifierExpression.TypeArguments.Detach()); invocationExpression.Target = memberRefExpr; } else { memberRefExpr.Target = firstArgument.Detach(); } if (invocationExpression.GetResolveResult() is CSharpInvocationResolveResult irr) { // do not forget to update the CSharpInvocationResolveResult => set IsExtensionMethodInvocation == true invocationExpression.RemoveAnnotations <CSharpInvocationResolveResult>(); var newResolveResult = new CSharpInvocationResolveResult( irr.TargetResult, irr.Member, irr.Arguments, irr.OverloadResolutionErrors, isExtensionMethodInvocation: true, irr.IsExpandedForm, irr.IsDelegateInvocation, irr.GetArgumentToParameterMap(), irr.InitializerStatements); invocationExpression.AddAnnotation(newResolveResult); } }