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 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 void BuildFieldRow(XDoc html, ReflectedFieldInfo member) { var xmlDoc = GetDoc(member.Signature); html.Start("tr") .Elem("td", member.MemberAccess) .Start("td").StartSpan("member"); if(IsTypeInDocumentation(member.DeclaringType)) { html.Link(member.UriPath, member.DisplayName); } else { html.Value(member.DisplayName); } html .EndSpan() .StartSpan("description").AddNodes(xmlDoc["summary"]).EndSpan() .End() // td .End(); // tr }