Example #1
0
        /// <summary>
        /// Resolves an extension method by arguments.
        /// </summary>
        public static MethodWrapper ResolveExtensionMethod(ExtensionMethodResolver resolver, Type type, string name, Type[] argTypes, Type[] hints, LambdaResolver lambdaResolver)
        {
            var method = resolver.ResolveExtensionMethod(type, name, argTypes);
            var args   = method.GetParameters();
            var info   = new MethodWrapper
            {
                Name = name,
                Type = method.DeclaringType,

                MethodInfo         = method,
                IsStatic           = true,
                IsVirtual          = false,
                ReturnType         = method.ReturnType,
                ArgumentTypes      = args.Select(p => p.ParameterType).ToArray(),
                IsPartiallyApplied = IsPartiallyApplied(argTypes),
                IsVariadic         = IsVariadic(method),
            };

            if (method.IsGenericMethod)
            {
                var expectedTypes = method.GetParameters().Select(p => p.ParameterType).ToArray();
                var genericDefs   = method.GetGenericArguments();

                var extMethodArgs = argTypes.ToList();
                extMethodArgs.Insert(0, type);

                var genericValues = GenericHelper.ResolveMethodGenericsByArgs(
                    expectedTypes,
                    extMethodArgs.ToArray(),
                    genericDefs,
                    hints,
                    lambdaResolver
                    );

                info.GenericArguments = genericValues;
                info.MethodInfo       = info.MethodInfo.MakeGenericMethod(genericValues);
                info.ReturnType       = GenericHelper.ApplyGenericArguments(info.ReturnType, genericDefs, genericValues);
                info.ArgumentTypes    = expectedTypes.Select(t => GenericHelper.ApplyGenericArguments(t, genericDefs, genericValues)).ToArray();
            }
            else if (hints != null)
            {
                error(CompilerMessages.GenericArgsToNonGenericMethod, name);
            }

            return(info);
        }
Example #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);
        }