Exemple #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)
                });
            }
        }
Exemple #2
0
        /// <summary>
        /// Resolves a group of methods by name.
        /// Only non-generic methods are returned!
        /// </summary>
        public static IEnumerable <MethodWrapper> ResolveMethodGroup(Type type, string name)
        {
            try
            {
                return(getMethodsByName(type, name).Where(m => !m.IsGenericMethod).Select(m => new MethodWrapper(m)));
            }
            catch (NotSupportedException)
            {
                if (!type.IsGenericType)
                {
                    throw;
                }

                var genType        = type.GetGenericTypeDefinition();
                var genericMethods = getMethodsByName(genType, name).Where(m => !m.IsGenericMethod).ToArray();

                return(genericMethods.Select(
                           m =>
                {
                    var declType = resolveActualDeclaringType(type, m.DeclaringType);
                    return new MethodWrapper
                    {
                        Name = name,
                        Type = type,

                        MethodInfo = getMethodVersionForType(declType, m),
                        IsStatic = m.IsStatic,
                        IsVirtual = m.IsVirtual,
                        ArgumentTypes = m.GetParameters().Select(p => GenericHelper.ApplyGenericArguments(p.ParameterType, declType)).ToArray(),
                        ReturnType = GenericHelper.ApplyGenericArguments(m.ReturnType, declType)
                    };
                }
                           ));
            }
        }
Exemple #3
0
        /// <summary>
        /// Resolves a property from a type by its name.
        /// </summary>
        public static PropertyWrapper ResolveProperty(Type type, string name)
        {
            try
            {
                var pty = type.GetProperty(name);
                if (pty == null)
                {
                    throw new KeyNotFoundException();
                }

                var getter = pty.GetGetMethod();
                var setter = pty.GetSetMethod();
                return(new PropertyWrapper
                {
                    Name = name,
                    Type = type,

                    Getter = getter,
                    Setter = setter,
                    IsStatic = (getter ?? setter).IsStatic,
                    PropertyType = pty.PropertyType,
                    IsVirtual = (getter ?? setter).IsVirtual
                });
            }
            catch (NotSupportedException)
            {
                if (!type.IsGenericType)
                {
                    throw new KeyNotFoundException();
                }

                var genType = type.GetGenericTypeDefinition();
                var genPty  = genType.GetProperty(name);

                if (genPty == null)
                {
                    throw new KeyNotFoundException();
                }

                var getter = genPty.GetGetMethod();
                var setter = genPty.GetSetMethod();

                var declType = ResolveActualDeclaringType(type, genPty.DeclaringType);

                return(new PropertyWrapper
                {
                    Name = name,
                    Type = type,

                    Getter = GetMethodVersionForType(declType, getter),
                    Setter = GetMethodVersionForType(declType, setter),
                    IsStatic = (getter ?? setter).IsStatic,
                    PropertyType = GenericHelper.ApplyGenericArguments(genPty.PropertyType, type),
                });
            }
        }
Exemple #4
0
        /// <summary>
        /// Resolves an event by its name.
        /// </summary>
        public static EventWrapper ResolveEvent(Type type, string name)
        {
            try
            {
                var evt = type.GetEvent(name);
                if (evt == null)
                {
                    throw new KeyNotFoundException();
                }

                return(new EventWrapper
                {
                    Name = name,
                    Type = type,

                    IsStatic = evt.GetRemoveMethod().IsStatic,

                    AddMethod = evt.GetAddMethod(),
                    RemoveMethod = evt.GetRemoveMethod(),
                    EventHandlerType = evt.EventHandlerType
                });
            }
            catch (NotSupportedException)
            {
                if (!type.IsGenericType)
                {
                    throw new KeyNotFoundException();
                }

                var genType = type.GetGenericTypeDefinition();
                var genEvt  = genType.GetEvent(name);

                if (genEvt == null)
                {
                    throw new KeyNotFoundException();
                }

                var adder   = genEvt.GetAddMethod();
                var remover = genEvt.GetRemoveMethod();

                var declType = resolveActualDeclaringType(type, genEvt.DeclaringType);

                return(new EventWrapper
                {
                    Name = name,
                    Type = type,

                    AddMethod = getMethodVersionForType(declType, adder),
                    RemoveMethod = getMethodVersionForType(declType, remover),
                    IsStatic = adder.IsStatic,
                    EventHandlerType = GenericHelper.ApplyGenericArguments(genEvt.EventHandlerType, type)
                });
            }
        }
Exemple #5
0
        /// <summary>
        /// Get interfaces of a possibly generic type.
        /// </summary>
        public static Type[] ResolveInterfaces(this Type type)
        {
            if (m_InterfaceCache.ContainsKey(type))
            {
                return(m_InterfaceCache[type].ToArray());
            }

            Type[] ifaces;
            try
            {
                ifaces = type.GetInterfaces();
            }
            catch (NotSupportedException)
            {
                if (type.IsGenericType)
                {
                    ifaces = type.GetGenericTypeDefinition().GetInterfaces();
                    for (var idx = 0; idx < ifaces.Length; idx++)
                    {
                        var curr = ifaces[idx];
                        if (curr.IsGenericType)
                        {
                            ifaces[idx] = GenericHelper.ApplyGenericArguments(curr, type);
                        }
                    }
                }

                else if (type.IsArray)
                {
                    // replace interfaces of any array with element type
                    var elem = type.GetElementType();
                    ifaces = typeof(int[]).GetInterfaces();
                    for (var idx = 0; idx < ifaces.Length; idx++)
                    {
                        var curr = ifaces[idx];
                        if (curr.IsGenericType)
                        {
                            ifaces[idx] = curr.GetGenericTypeDefinition().MakeGenericType(elem);
                        }
                    }
                }

                // just a built-in type : no interfaces
                else
                {
                    ifaces = Type.EmptyTypes;
                }
            }

            m_InterfaceCache.Add(type, ifaces);
            return(ifaces.ToArray());
        }
Exemple #6
0
        /// <summary>
        /// Resolves a field from a type by its name.
        /// </summary>
        public static FieldWrapper ResolveField(Type type, string name)
        {
            try
            {
                var field = type.GetField(name);
                if (field == null)
                {
                    throw new KeyNotFoundException();
                }

                return(new FieldWrapper
                {
                    Name = name,
                    Type = type,

                    FieldInfo = field,
                    IsStatic = field.IsStatic,
                    IsLiteral = field.IsLiteral,
                    FieldType = field.FieldType
                });
            }
            catch (NotSupportedException)
            {
                if (!type.IsGenericType)
                {
                    throw new KeyNotFoundException();
                }

                var genType  = type.GetGenericTypeDefinition();
                var genField = genType.GetField(name);

                if (genField == null)
                {
                    throw new KeyNotFoundException();
                }

                return(new FieldWrapper
                {
                    Name = name,
                    Type = type,

                    FieldInfo = TypeBuilder.GetField(type, genField),
                    IsStatic = genField.IsStatic,
                    IsLiteral = genField.IsLiteral,
                    FieldType = GenericHelper.ApplyGenericArguments(genField.FieldType, type)
                });
            }
        }
Exemple #7
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);
        }
Exemple #8
0
        /// <summary>
        /// Resolves a constructor from a type by the list of arguments.
        /// </summary>
        public static ConstructorWrapper ResolveConstructor(Type type, Type[] argTypes)
        {
            try
            {
                var ctor = ResolveMethodByArgs(
                    type.GetConstructors(),
                    c => c.GetParameters().Select(p => p.ParameterType).ToArray(),
                    IsVariadic,
                    argTypes
                    );

                return(new ConstructorWrapper
                {
                    Type = type,
                    ConstructorInfo = ctor.Method,
                    ArgumentTypes = ctor.ArgumentTypes,
                    IsPartiallyApplied = IsPartiallyApplied(argTypes),
                    IsVariadic = IsVariadic(ctor.Method)
                });
            }
            catch (NotSupportedException)
            {
                if (!type.IsGenericType)
                {
                    throw new KeyNotFoundException();
                }

                var genType = type.GetGenericTypeDefinition();
                var genCtor = ResolveMethodByArgs(
                    genType.GetConstructors(),
                    c => c.GetParameters().Select(p => GenericHelper.ApplyGenericArguments(p.ParameterType, type)).ToArray(),
                    IsVariadic,
                    argTypes
                    );

                return(new ConstructorWrapper
                {
                    Type = type,
                    ConstructorInfo = TypeBuilder.GetConstructor(type, genCtor.Method),
                    ArgumentTypes = genCtor.ArgumentTypes,
                    IsPartiallyApplied = IsPartiallyApplied(argTypes),
                    IsVariadic = IsVariadic(genCtor.Method)
                });
            }
        }
Exemple #9
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);
        }