private void GetNameSignatures(ReflectedTypeInfo type, StringBuilder builder, Queue<ReflectedParameterTypeInfo> parameterQueue) { if(type == null) { return; } GetNameSignatures(type.DeclaringType, builder, parameterQueue); builder.Append("."); builder.Append(type.Name); if(IsGenericType) { var paramCount = type.LocalGenericParameters.Count(); if(paramCount > 0) { builder.Append("{"); bool first = true; for(int i = 0; i < paramCount; i++) { if(!first) { builder.Append(","); } var param = parameterQueue.Dequeue(); builder.Append(param.Signature); first = false; } builder.Append("}"); } } }
private ReflectedTypeInfo GetType(Type type, bool build) { if(type == null) { return null; } var qualifiedName = type.ToString(); if(type.IsGenericType) { qualifiedName = type.GetGenericTypeDefinition().ToString(); } ReflectedTypeInfo typeInfo = null; if(!_seenTypes.TryGetValue(qualifiedName, out typeInfo)) { if(!type.IsArray) { if(type.IsGenericType) { _typesToBuild.Enqueue(type.GetGenericTypeDefinition()); } else { _typesToBuild.Enqueue(type); } } var simpleName = type.Name; if(type.IsGenericType) { var tickIndex = type.Name.IndexOf('`'); if(tickIndex > 0) { simpleName = type.Name.Substring(0, tickIndex); } } typeInfo = new ReflectedTypeInfo() { Assembly = type.Assembly.GetName().Name, Name = simpleName, Namespace = type.Namespace, IsDelegate = typeof(Delegate).IsAssignableFrom(type), Kind = type.IsInterface ? TypeKind.Interface : (type.IsValueType && !type.IsClass) ? TypeKind.Struct : type.IsEnum ? TypeKind.Enum : TypeKind.Class, IsAbstract = type.IsAbstract && !type.IsSealed, IsStatic = type.IsAbstract && type.IsSealed, IsSealed = type.IsSealed && !type.IsAbstract }; if(type.DeclaringType != null) { typeInfo.DeclaringType = GetType(type.DeclaringType); } _seenTypes[qualifiedName] = typeInfo; } if(build) { BuildType(type, typeInfo); } return typeInfo; }
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); } }
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; }
private void GetParametrizedNames(ReflectedTypeInfo type, StringBuilder builder, Queue<ReflectedParameterTypeInfo> parameterQueue, bool isEntry) { if(type == null) { return; } GetParametrizedNames(type.DeclaringType, builder, parameterQueue,false); builder.Append(type.AliasedName); if(IsGenericType) { var paramCount = type.LocalGenericParameters.Count(); if(paramCount > 0) { builder.Append("<"); bool first = true; for(int i = 0; i < paramCount; i++) { if(!first) { builder.Append(","); } var param = parameterQueue.Dequeue(); builder.Append(param.DisplayName); first = false; } builder.Append(">"); } } if(!isEntry) { builder.Append("."); } }