Beispiel #1
0
        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);
        }
Beispiel #2
0
 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);
     }
 }
Beispiel #3
0
        /// <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);
        }
Beispiel #4
0
        public bool Equals(IMember obj, TypeVisitor typeNormalization)
        {
            VarArgInstanceMethod other = obj as VarArgInstanceMethod;

            return(other != null && baseMethod.Equals(other.baseMethod, typeNormalization));
        }
Beispiel #5
0
        public override bool Equals(object obj)
        {
            VarArgInstanceMethod other = obj as VarArgInstanceMethod;

            return(other != null && baseMethod.Equals(other.baseMethod));
        }