예제 #1
0
        private void BuildType(Type type, ReflectedTypeInfo typeInfo)
        {
            _builtTypes.Add(type);
            _documentedTypes.Add(typeInfo);
            var typeParameterBuilder = new ParameterBuilder(typeInfo, GetType);
            if(type.IsGenericType) {
                var genericTypeArguments = type.GetGenericArguments();
                typeInfo.IsGeneric = true;
                typeInfo.GenericParameters = GetGenericParameters(genericTypeArguments, false);

                // since generic parameter constraints can refer to each other and parameterBuilder.BuildType gets these references
                // by retrieving the registered instance of the type, building the types for GenericParameters has to occur after
                // the skeleton is built and assigned to the typeInfo instance.
                for(int i = 0; i < genericTypeArguments.Length; i++) {
                    foreach(var constraintType in genericTypeArguments[i].GetGenericParameterConstraints()) {
                        if(constraintType == typeof(ValueType)) {
                            continue;
                        }
                        typeInfo.GenericParameters[i].Types.Add(typeParameterBuilder.BuildType(constraintType));
                    }
                }
            }
            typeInfo.BaseType = typeParameterBuilder.BuildType(type.BaseType);
            typeInfo.Interfaces = (from i in type.GetInterfaces()
                                   where !i.Name.StartsWith("_")
                                   select typeParameterBuilder.BuildType(i)).ToList();
            if(typeInfo.IsDelegate) {
                return;
            }

            // find constructors
            foreach(var constructor in type.GetConstructors(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static)) {
                if(constructor.IsPrivate || constructor.IsAssembly) {
                    continue;
                }
                var isProtected = constructor.IsFamily && !constructor.IsPublic && !constructor.IsPrivate;
                var constructorInfo = new ReflectedConstructorInfo() {
                    Type = typeInfo,
                    IsStatic = constructor.IsStatic,
                    MemberAccess = isProtected ? MemberAccess.Protected : MemberAccess.Public,
                    DeclaringType = GetType(constructor.DeclaringType),
                };
                constructorInfo.Parameters = GetParameters(constructor.GetParameters(), typeParameterBuilder);
                typeInfo.Constructors.Add(constructorInfo);
            }

            // find methods
            foreach(var method in type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static)) {
                if(method.IsSpecialName || method.IsPrivate || method.IsAssembly || method.Name == "Finalize") {
                    continue;
                }
                var methodInfo = BuildMethodInfo(typeInfo, method);
                typeInfo.Methods.Add(methodInfo);
            }

            // find properties
            foreach(var property in type.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static)) {
                var getMethod = property.GetGetMethod(true);
                var setMethod = property.GetSetMethod(true);
                if((getMethod == null || getMethod.IsPrivate || getMethod.IsAssembly)
                    && (setMethod == null || setMethod.IsPrivate || setMethod.IsAssembly)
                ) {
                    continue;
                }
                var accessorMethod = getMethod == null || getMethod.IsPrivate ? setMethod : getMethod;
                var methodInfo = BuildMethodInfo(typeInfo, accessorMethod);
                var propertyInfo = new ReflectedPropertyInfo() {
                    Name = property.Name,
                    IsIndexer = property.Name == "Item",
                    Type = typeInfo,
                    DeclaringType = GetType(property.DeclaringType),
                    ReturnType = typeParameterBuilder.BuildType(property.PropertyType),
                    IsOverride = methodInfo.IsOverride,
                    IsStatic = methodInfo.IsStatic,
                    IsVirtual = methodInfo.IsVirtual,
                    GetAccess = DetermineAccess(getMethod),
                    SetAccess = DetermineAccess(setMethod)
                };
                propertyInfo.MemberAccess = propertyInfo.GetAccess == MemberAccess.Public || propertyInfo.SetAccess == MemberAccess.Public
                    ? MemberAccess.Public
                    : MemberAccess.Protected;
                if(propertyInfo.IsIndexer) {
                    methodInfo.Name = "Item";
                    propertyInfo.IndexerParameters = GetParameters(property.GetIndexParameters(), typeParameterBuilder);
                }
                typeInfo.Properties.Add(propertyInfo);
            }

            // find fields
            foreach(var field in type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static)) {
                if(field.IsPrivate || field.IsAssembly) {
                    continue;
                }
                var isProtected = field.IsFamily && !field.IsPublic && !field.IsPrivate;
                var fieldInfo = new ReflectedFieldInfo() {
                    Name = field.Name,
                    Type = typeInfo,
                    IsStatic = field.IsStatic,
                    MemberAccess = isProtected ? MemberAccess.Protected : MemberAccess.Public,
                    DeclaringType = GetType(field.DeclaringType),
                    ReturnType = typeParameterBuilder.BuildType(field.FieldType)
                };
                typeInfo.Fields.Add(fieldInfo);
            }

            // find events
            foreach(var ev in type.GetEvents(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static)) {
                var addMethod = ev.GetAddMethod(true);
                var removeMethod = ev.GetRemoveMethod(true);
                if((addMethod == null || addMethod.IsPrivate || addMethod.IsAssembly)
                    && (removeMethod == null || removeMethod.IsPrivate || removeMethod.IsAssembly)
                ) {
                    continue;
                }
                var accessorMethod = addMethod == null || addMethod.IsPrivate ? removeMethod : addMethod;
                var methodInfo = BuildMethodInfo(typeInfo, accessorMethod);
                var eventInfo = new ReflectedEventInfo() {
                    Name = ev.Name,
                    Type = typeInfo,
                    DeclaringType = GetType(ev.DeclaringType),
                    ReturnType = typeParameterBuilder.BuildType(ev.EventHandlerType),
                    IsOverride = methodInfo.IsOverride,
                    IsStatic = methodInfo.IsStatic,
                    IsVirtual = methodInfo.IsVirtual,
                    AddAccess = DetermineAccess(addMethod),
                    RemoveAccess = DetermineAccess(removeMethod)
                };
                typeInfo.Events.Add(eventInfo);
            }
        }
예제 #2
0
 private IList<ReflectedParameterInfo> GetParameters(ParameterInfo[] parameters, ParameterBuilder builder)
 {
     var parameterList = new List<ReflectedParameterInfo>();
     foreach(var parameter in parameters) {
         var param = builder.BuildParameter(parameter);
         parameterList.Add(param);
     }
     return parameterList;
 }
예제 #3
0
 private ReflectedMethodInfo BuildMethodInfo(ReflectedTypeInfo typeInfo, MethodInfo method)
 {
     var isNewSlot = ((method.Attributes & MethodAttributes.NewSlot) == MethodAttributes.NewSlot);
     var isReusedSlot = ((method.Attributes & MethodAttributes.ReuseSlot) == MethodAttributes.ReuseSlot);
     var isOverride = method.IsVirtual && !isNewSlot && isReusedSlot;
     var methodInfo = new ReflectedMethodInfo() {
         Name = method.Name,
         Type = typeInfo,
         DeclaringType = GetType(method.DeclaringType),
         IsOverride = isOverride,
         MemberAccess = DetermineAccess(method),
         IsVirtual = method.IsVirtual && !isOverride,
         IsStatic = method.IsStatic,
         IsExtensionMethod = method.GetCustomAttributes(typeof(ExtensionAttribute), false).Any()
     };
     var parameterBuilder = new ParameterBuilder(methodInfo, GetType);
     if(method.IsGenericMethod) {
         var genericArgs = method.GetGenericArguments();
         methodInfo.IsGenericMethod = true;
         methodInfo.GenericParameters = GetGenericParameters(genericArgs, true);
         for(int i = 0; i < genericArgs.Length; i++) {
             foreach(var constraintType in genericArgs[i].GetGenericParameterConstraints()) {
                 if(constraintType == typeof(ValueType)) {
                     continue;
                 }
                 methodInfo.GenericParameters[i].Types.Add(parameterBuilder.BuildType(constraintType));
             }
         }
     }
     methodInfo.ReturnType = parameterBuilder.BuildType(method.ReturnType);
     methodInfo.Parameters = GetParameters(method.GetParameters(), parameterBuilder);
     if(methodInfo.IsExtensionMethod) {
         methodInfo.Parameters[0].IsExtensionParameter = true;
     }
     return methodInfo;
 }