IMethod ResolveMethodDefinition(MethodDefinitionHandle methodDefHandle, bool expandVarArgs) { var method = GetDefinition(methodDefHandle); if (expandVarArgs && method.Parameters.LastOrDefault()?.Type.Kind == TypeKind.ArgList) { method = new VarArgInstanceMethod(method, EmptyList <IType> .Instance); } return(method); }
public IMethod Resolve(MethodReference methodReference) { if (methodReference == null) { throw new ArgumentNullException(nameof(methodReference)); } lock (methodLookupCache) { IMethod method; if (!methodLookupCache.TryGetValue(methodReference, out method)) { method = FindNonGenericMethod(methodReference.GetElementMethod()); if (method == null) { method = CreateFakeMethod(methodReference); } if (methodReference.CallingConvention == MethodCallingConvention.VarArg) { method = new VarArgInstanceMethod( method, methodReference.Parameters.SkipWhile(p => !p.ParameterType.IsSentinel).Select(p => Resolve(p.ParameterType)) ); } else if (methodReference.IsGenericInstance || methodReference.DeclaringType.IsGenericInstance) { IList <IType> classTypeArguments = null; IList <IType> methodTypeArguments = null; if (methodReference.IsGenericInstance) { var gim = ((GenericInstanceMethod)methodReference); methodTypeArguments = gim.GenericArguments.SelectArray(Resolve); } if (methodReference.DeclaringType.IsGenericInstance) { var git = (GenericInstanceType)methodReference.DeclaringType; classTypeArguments = git.GenericArguments.SelectArray(Resolve); } method = method.Specialize(new TypeParameterSubstitution(classTypeArguments, methodTypeArguments)); } methodLookupCache.Add(methodReference, method); } return(method); } }
/// <summary> /// Resolves a method reference. /// </summary> /// <remarks> /// Class type arguments are provided by the declaring type stored in the memberRef. /// Method type arguments are provided by the caller. /// </remarks> IMethod ResolveMethodReference(MemberReferenceHandle memberRefHandle, GenericContext context, IReadOnlyList <IType> methodTypeArguments = null, bool expandVarArgs = true) { var memberRef = metadata.GetMemberReference(memberRefHandle); Debug.Assert(memberRef.GetKind() == MemberReferenceKind.Method); MethodSignature <IType> signature; IReadOnlyList <IType> classTypeArguments = null; IMethod method; if (memberRef.Parent.Kind == HandleKind.MethodDefinition) { method = ResolveMethodDefinition((MethodDefinitionHandle)memberRef.Parent, expandVarArgs: false); signature = memberRef.DecodeMethodSignature(TypeProvider, context); } else { var declaringType = ResolveDeclaringType(memberRef.Parent, context); var declaringTypeDefinition = declaringType.GetDefinition(); if (declaringType.TypeArguments.Count > 0) { classTypeArguments = declaringType.TypeArguments; } // Note: declaringType might be parameterized, but the signature is for the original method definition. // We'll have to search the member directly on declaringTypeDefinition. string name = metadata.GetString(memberRef.Name); signature = memberRef.DecodeMethodSignature(TypeProvider, new GenericContext(declaringTypeDefinition?.TypeParameters)); if (declaringTypeDefinition != null) { // Find the set of overloads to search: IEnumerable <IMethod> methods; if (name == ".ctor") { methods = declaringTypeDefinition.GetConstructors(); } else if (name == ".cctor") { methods = declaringTypeDefinition.Methods.Where(m => m.IsConstructor && m.IsStatic); } else { methods = declaringTypeDefinition.GetMethods(m => m.Name == name, GetMemberOptions.IgnoreInheritedMembers) .Concat(declaringTypeDefinition.GetAccessors(m => m.Name == name, GetMemberOptions.IgnoreInheritedMembers)); } // Determine the expected parameters from the signature: ImmutableArray <IType> parameterTypes; if (signature.Header.CallingConvention == SignatureCallingConvention.VarArgs) { parameterTypes = signature.ParameterTypes .Take(signature.RequiredParameterCount) .Concat(new[] { SpecialType.ArgList }) .ToImmutableArray(); } else { parameterTypes = signature.ParameterTypes; } // Search for the matching method: method = null; foreach (var m in methods) { if (m.TypeParameters.Count != signature.GenericParameterCount) { continue; } if (CompareSignatures(m.Parameters, parameterTypes) && CompareTypes(m.ReturnType, signature.ReturnType)) { method = m; break; } } } else { method = null; } if (method == null) { method = CreateFakeMethod(declaringType, name, signature); } } if (classTypeArguments != null || methodTypeArguments != null) { method = method.Specialize(new TypeParameterSubstitution(classTypeArguments, methodTypeArguments)); } if (expandVarArgs && signature.Header.CallingConvention == SignatureCallingConvention.VarArgs) { method = new VarArgInstanceMethod(method, signature.ParameterTypes.Skip(signature.RequiredParameterCount)); } return(method); }
public bool Equals(IMember obj, TypeVisitor typeNormalization) { VarArgInstanceMethod other = obj as VarArgInstanceMethod; return(other != null && baseMethod.Equals(other.baseMethod, typeNormalization)); }
public override bool Equals(object obj) { VarArgInstanceMethod other = obj as VarArgInstanceMethod; return(other != null && baseMethod.Equals(other.baseMethod)); }