예제 #1
0
        internal static object Pack(MemberInfo member)
        {
            if (member.DeclaringType == null)
            {
                return(null);
            }

            var memberName = (object)TypeNameUtils.RemoveGenericSuffix(member.Name);

            if (member is MethodBase)
            {
                var methodBase = (MethodBase)member;
                if (methodBase.IsGenericMethod)
                {
                    var typeArguments  = methodBase.GetGenericArguments();
                    var methodNameTree = new Dictionary <string, object>(3)
                    {
                        { Constants.EXPRESSION_TYPE_ATTRIBUTE, Constants.EXPRESSION_TYPE_MEMBER_REFERENCE },
                        { Constants.NAME_ATTRIBUTE, memberName },
                        { Constants.ARGUMENTS_ATTRIBUTE, Pack(typeArguments) }
                    };
                    memberName = methodNameTree;
                }

                var parameters = methodBase.GetParameters();
                var arguments  = new Dictionary <string, object>(parameters.Length);
                foreach (var parameterInfo in parameters)
                {
                    var key   = Constants.GetIndexAsString(parameterInfo.Position);
                    var value = parameterInfo.Name ?? key;
                    arguments[key] = value;
                }

                return(new Dictionary <string, object>(4)
                {
                    { Constants.EXPRESSION_TYPE_ATTRIBUTE, Constants.EXPRESSION_TYPE_MEMBER_REFERENCE },
                    { Constants.TYPE_ATTRIBUTE, Pack(methodBase.DeclaringType) },
                    { Constants.NAME_ATTRIBUTE, memberName },
                    { Constants.ARGUMENTS_ATTRIBUTE, arguments }
                });
            }
            else
            {
                return(new Dictionary <string, object>(3)
                {
                    { Constants.EXPRESSION_TYPE_ATTRIBUTE, Constants.EXPRESSION_TYPE_MEMBER_REFERENCE },
                    { Constants.TYPE_ATTRIBUTE, Pack(member.DeclaringType) },
                    { Constants.NAME_ATTRIBUTE, memberName },
                });
            }
        }
        private static TypeReference MakeTypeReference(Type type, bool fullName)
        {
            var typeNameBuilder = fullName ?
                                  TypeNameUtils.GetCSharpFullName(type, options: TypeNameFormatOptions.IncludeGenericSuffix) :
                                  TypeNameUtils.GetCSharpName(type, options: TypeNameFormatOptions.IncludeGenericSuffix);

            TypeNameUtils.RemoveGenericSuffix(typeNameBuilder, 0, typeNameBuilder.Length);

            var genericArguments = new List <TypeReference>();

            foreach (var genArgument in type.GetTypeInfo().GetGenericArguments())
            {
                genericArguments.Add(MakeTypeReference(genArgument, fullName));
            }

            return(new TypeReference(typeNameBuilder.ToString().Split('.'), genericArguments));
        }
예제 #3
0
        public MemberDescription(TypeDescription declaringType, MethodInfo method, MemberDescription genericMethodDefinition = null)
        {
            if (declaringType == null)
            {
                throw new ArgumentNullException("declaringType");
            }
            if (method == null)
            {
                throw new ArgumentNullException("method");
            }

            this.Name             = method.IsGenericMethod ? TypeNameUtils.RemoveGenericSuffix(method.Name) : method.Name;
            this.DeclaringType    = declaringType;
            this.ResultType       = method.ReturnType;
            this.member           = method;
            this.parameters       = method.GetParameters();
            this.parametersByName = this.parameters.ToDictionary(GetParameterName, StringComparer.Ordinal);
            this.returnParameter  = method.ReturnParameter;
            this.hashCode         = method.GetHashCode();
            if (method.IsGenericMethod)
            {
                this.GenericArguments      = method.GetGenericArguments();
                this.GenericArgumentsCount = this.GenericArguments.Length;
                if (method.IsGenericMethodDefinition)
                {
                    this.methodInstantiations = new Dictionary <TypeTuple, MemberDescription>();
                    this.genericDefinition    = this;
                }
                else
                {
                    if (genericMethodDefinition == null)
                    {
                        throw new ArgumentNullException("genericMethodDefinition");
                    }

                    this.methodInstantiations = genericMethodDefinition.methodInstantiations;
                    this.genericDefinition    = genericMethodDefinition;
                }
            }

            this.HasByRefLikeParameters = this.parameters.Any(parameter => TypeDescription.HasByRefLikeAttribute(parameter.ParameterType));
            this.IsMethod           = true;
            this.IsStatic           = method.IsStatic;
            this.IsImplicitOperator = method.IsSpecialName && this.Name == "op_Implicit";
        }
예제 #4
0
        public TypeDescription(Type type, TypeCache cache)
        {
            if (type == null)
            {
                throw new ArgumentNullException("type");
            }
            if (cache == null)
            {
                throw new ArgumentNullException("cache");
            }

            this.type     = type;
            this.hashCode = type.GetHashCode();
            this.Name     = TypeNameUtils.RemoveGenericSuffix(TypeNameUtils.GetCSharpName(type)).ToString();

            cache.Add(type, this);

            var typeInfo       = type.GetTypeInfo();
            var underlyingType = default(Type);

            if (typeInfo.IsEnum)
            {
                underlyingType = Enum.GetUnderlyingType(type);
            }
            else if (typeInfo.IsValueType)
            {
                underlyingType = Nullable.GetUnderlyingType(type);
            }
            else if (typeInfo.IsArray)
            {
                underlyingType = typeInfo.GetElementType();
            }

            this.BaseType = typeInfo.BaseType != null?cache.GetOrCreateTypeDescription(typeInfo.BaseType) : null;

            this.UnderlyingType = underlyingType != null?cache.GetOrCreateTypeDescription(underlyingType) : null;

            this.BaseTypes        = GetBaseTypes(this, 0);
            this.Interfaces       = typeInfo.GetImplementedInterfaces().Select(cache.GetOrCreateTypeDescription).ToArray();
            this.GenericArguments = typeInfo.IsGenericType ? ArrayUtils.ConvertAll(typeInfo.GetGenericArguments(), cache.GetOrCreateTypeDescription) : EmptyTypes;

            this.IsInterface          = typeInfo.IsInterface;
            this.IsValueType          = typeInfo.IsValueType;
            this.IsNullable           = Nullable.GetUnderlyingType(type) != null;
            this.IsNumber             = NumberUtils.IsNumber(type);
            this.CanBeNull            = this.IsNullable || typeInfo.IsValueType == false;
            this.IsEnum               = typeInfo.IsEnum;
            this.IsVoid               = type == typeof(void);
            this.IsDelegate           = typeof(Delegate).GetTypeInfo().IsAssignableFrom(typeInfo) && type != typeof(Delegate) && type != typeof(MulticastDelegate);
            this.HasGenericParameters = typeInfo.ContainsGenericParameters;
            if (this.IsVoid)
            {
                this.DefaultExpression = Expression.Constant(null, typeof(object));
            }
            else
            {
                this.DefaultExpression = Expression.Constant(typeInfo.IsValueType && this.IsNullable == false ? Activator.CreateInstance(type) : null, type);
            }
            this.TypeCode = ReflectionUtils.GetTypeCode(type);

            this.MembersByName = this.GetMembersByName(ref this.Indexers);
            this.Indexers      = this.Indexers ?? (MemberDescription[])Enumerable.Empty <MemberDescription>();

            var methods             = typeInfo.GetAllMethods().Where(m => m.IsPublic && m.IsStatic).ToList();
            var methodsDescriptions = new MemberDescription[methods.Count];

            // ReSharper disable LocalizableElement
            this.ImplicitConvertTo   = this.GetOperators(methods, methodsDescriptions, "op_Implicit", 0);
            this.ImplicitConvertFrom = this.GetOperators(methods, methodsDescriptions, "op_Implicit", -1);
            this.ExplicitConvertTo   = this.GetOperators(methods, methodsDescriptions, "op_Explicit", 0);
            this.ExplicitConvertFrom = this.GetOperators(methods, methodsDescriptions, "op_Explicit", -1);
            this.Addition            = this.GetOperators(methods, methodsDescriptions, "op_Addition");
            this.Division            = this.GetOperators(methods, methodsDescriptions, "op_Division");
            this.Equality            = this.GetOperators(methods, methodsDescriptions, "op_Equality");
            this.GreaterThan         = this.GetOperators(methods, methodsDescriptions, "op_GreaterThan");
            this.GreaterThanOrEqual  = this.GetOperators(methods, methodsDescriptions, "op_GreaterThanOrEqual");
            this.Inequality          = this.GetOperators(methods, methodsDescriptions, "op_Inequality");
            this.LessThan            = this.GetOperators(methods, methodsDescriptions, "op_LessThan");
            this.LessThanOrEqual     = this.GetOperators(methods, methodsDescriptions, "op_LessThanOrEqual");
            this.Modulus             = this.GetOperators(methods, methodsDescriptions, "op_Modulus");
            this.Multiply            = this.GetOperators(methods, methodsDescriptions, "op_Multiply");
            this.Subtraction         = this.GetOperators(methods, methodsDescriptions, "op_Subtraction");
            this.UnaryNegation       = this.GetOperators(methods, methodsDescriptions, "op_UnaryNegation");
            this.UnaryPlus           = this.GetOperators(methods, methodsDescriptions, "op_UnaryPlus");
            this.BitwiseAnd          = this.GetOperators(methods, methodsDescriptions, "op_BitwiseAnd");
            this.BitwiseOr           = this.GetOperators(methods, methodsDescriptions, "op_BitwiseOr");
            // ReSharper restore LocalizableElement
            this.Conversions  = Combine(this.ImplicitConvertTo, this.ImplicitConvertFrom, this.ExplicitConvertTo, this.ExplicitConvertFrom);
            this.Constructors = type.GetTypeInfo().GetPublicInstanceConstructors().Select(ctr => new MemberDescription(this, ctr)).ToArray();

            Array.Sort(this.Conversions);
            Array.Sort(this.Constructors);

            if (this.IsNullable && this.UnderlyingType != null)
            {
                this.UnderlyingType.nullableType = this;
            }
        }