Exemplo n.º 1
0
        /// <summary>
        /// Resolves an indexer property from a type by its argument.
        /// </summary>
        public static MethodWrapper ResolveIndexer(Type type, Type idxType, bool isGetter)
        {
            if (type is TypeBuilder)
            {
                throw new NotSupportedException();
            }

            try
            {
                var indexer = resolveIndexerProperty(type, idxType, isGetter, p => p);
                return(new MethodWrapper(indexer));
            }
            catch (NotSupportedException)
            {
                if (!type.IsGenericType)
                {
                    throw;
                }

                var genType  = type.GetGenericTypeDefinition();
                var indexer  = resolveIndexerProperty(genType, idxType, isGetter, p => GenericHelper.ApplyGenericArguments(p, type));
                var declType = resolveActualDeclaringType(type, indexer.DeclaringType);

                return(new MethodWrapper
                {
                    Type = type,

                    MethodInfo = getMethodVersionForType(declType, indexer),
                    IsStatic = false,
                    IsVirtual = indexer.IsVirtual,
                    ArgumentTypes = indexer.GetParameters().Select(p => GenericHelper.ApplyGenericArguments(p.ParameterType, type)).ToArray(),
                    ReturnType = GenericHelper.ApplyGenericArguments(indexer.ReturnType, type)
                });
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Resolves a method by its name and argument types. If generic arguments are passed, they are also applied.
        /// Generic arguments whose values can be inferred from argument types can be skipped.
        /// </summary>
        public static MethodWrapper ResolveMethod(Type type, string name, Type[] argTypes, Type[] hints, LambdaResolver lambdaResolver)
        {
            var mw = new MethodWrapper {
                Name = name, Type = type
            };

            try
            {
                var method = ResolveMethodByArgs(
                    getMethodsByName(type, name),
                    m => m.GetParameters().Select(p => p.ParameterType).ToArray(),
                    IsVariadic,
                    argTypes
                    );

                var mInfo = method.Method;

                if (mInfo.IsGenericMethod)
                {
                    var genericDefs   = mInfo.GetGenericArguments();
                    var genericValues = GenericHelper.ResolveMethodGenericsByArgs(method.ArgumentTypes, argTypes, genericDefs, hints);

                    mInfo = mInfo.MakeGenericMethod(genericValues);
                    mw.GenericArguments = genericValues;
                }
                else if (hints != null)
                {
                    error(CompilerMessages.GenericArgsToNonGenericMethod, name);
                }

                mw.MethodInfo         = mInfo;
                mw.IsStatic           = mInfo.IsStatic;
                mw.IsVirtual          = mInfo.IsVirtual;
                mw.ArgumentTypes      = method.ArgumentTypes;
                mw.ReturnType         = mInfo.ReturnType;
                mw.IsPartiallyApplied = IsPartiallyApplied(argTypes);
                mw.IsVariadic         = IsVariadic(mInfo);

                return(mw);
            }
            catch (NotSupportedException)
            {
                if (!type.IsGenericType)
                {
                    throw new KeyNotFoundException();
                }

                var genType   = type.GetGenericTypeDefinition();
                var genMethod = ResolveMethodByArgs(
                    getMethodsByName(genType, name),
                    m => m.GetParameters().Select(p => GenericHelper.ApplyGenericArguments(p.ParameterType, type, false)).ToArray(),
                    IsVariadic,
                    argTypes
                    );

                var mInfoOriginal = genMethod.Method;
                var declType      = resolveActualDeclaringType(type, mInfoOriginal.DeclaringType);
                var mInfo         = getMethodVersionForType(declType, mInfoOriginal);

                if (mInfoOriginal.IsGenericMethod)
                {
                    var genericDefs   = mInfoOriginal.GetGenericArguments();
                    var genericValues = GenericHelper.ResolveMethodGenericsByArgs(genMethod.ArgumentTypes, argTypes, genericDefs, hints, lambdaResolver);

                    mInfo = mInfo.MakeGenericMethod(genericValues);

                    var totalGenericDefs   = genericDefs.Union(genType.GetGenericTypeDefinition().GetGenericArguments()).ToArray();
                    var totalGenericValues = genericValues.Union(type.GetGenericArguments()).ToArray();

                    mw.GenericArguments = genericValues;
                    mw.ReturnType       = GenericHelper.ApplyGenericArguments(mInfoOriginal.ReturnType, totalGenericDefs, totalGenericValues);
                    mw.ArgumentTypes    = mInfoOriginal.GetParameters().Select(p => GenericHelper.ApplyGenericArguments(p.ParameterType, totalGenericDefs, totalGenericValues)).ToArray();
                }
                else
                {
                    if (hints != null)
                    {
                        error(CompilerMessages.GenericArgsToNonGenericMethod, name);
                    }

                    mw.ArgumentTypes = mInfoOriginal.GetParameters().Select(p => GenericHelper.ApplyGenericArguments(p.ParameterType, type)).ToArray();
                    mw.ReturnType    = GenericHelper.ApplyGenericArguments(mInfoOriginal.ReturnType, type, false);
                }

                mw.MethodInfo         = mInfo;
                mw.IsStatic           = mInfoOriginal.IsStatic;
                mw.IsVirtual          = mInfoOriginal.IsVirtual;
                mw.IsPartiallyApplied = IsPartiallyApplied(argTypes);
                mw.IsVariadic         = IsVariadic(mInfoOriginal);
            }

            return(mw);
        }