/// <summary> /// Parse .Net XML documentation for Field data. /// </summary> /// <param name="memberElement">Expects tag name "member".</param> /// <example><![CDATA[<member name="F:Namespace.Type.FieldName"></member>]]></example> public static DotNetField FromVisualStudioXml(XElement memberElement) { DotNetQualifiedName name = DotNetQualifiedName.FromVisualStudioXml(memberElement.GetAttributeValue("name")); DotNetField field = new DotNetField(name); field.ParseVisualStudioXmlDocumentation(memberElement); return(field); }
private void LoadMembersInfoFromXml(XDocument document) { XElement membersElement = document.Root.Elements("members").FirstOrDefault(); if (membersElement == null) { return; } foreach (XElement memberElement in membersElement.Elements("member")) { XAttribute nameAttribute = memberElement.Attribute("name"); if (nameAttribute == null) { continue; } switch (nameAttribute.Value.Substring(0, 2)) { case "T:": DotNetType type = DotNetType.FromVisualStudioXml(memberElement); if (IsNestedType(type)) { AddMemberToType(type); } else { Types.Add(type); } break; case "M:": DotNetMethod method = DotNetMethod.FromVisualStudioXml(memberElement); AddMemberToType(method); break; case "F:": DotNetField field = DotNetField.FromVisualStudioXml(memberElement); AddMemberToType(field); break; case "P:": DotNetProperty property = DotNetProperty.FromVisualStudioXml(memberElement); AddMemberToType(property); break; case "E:": DotNetEvent eventMember = DotNetEvent.FromVisualStudioXml(memberElement); AddMemberToType(eventMember); break; } } }
/// <summary> /// Returns the selected field, if it exists in this type. /// </summary> /// <param name="FindType">Function that returns the selected type from all known types in the assembly.</param> /// <param name="localName">Name of field, local to this type.</param> public DotNetField FindInheritedField(Func <DotNetQualifiedName, DotNetType> FindType, string localName) { DotNetField field = Fields.FirstOrDefault(f => f.Name.LocalName == localName); if (field != null) { return(field); } if (BaseType != null) { DotNetType baseType = FindType(BaseType.Name); if (baseType != null) { return(baseType.FindInheritedField(FindType, localName)); } } return(null); }
/// <summary> /// For all "inheritdoc" comments, replace the inheritance comment with the inherited comments. /// </summary> /// <remarks> /// Classes can inherit from their base class (or the base class's base, etc). /// Interfaces can inherit from interfaces. /// Class members can inherit from their base class or from interfaces. /// </remarks> /// <param name="FindType">Function that returns the selected type from all known types in the assembly.</param> /// <param name="inheritancePath">List of types or members inheriting from each other, from top level to bottom level. Used to avoid loops.</param> public void ResolveInheritedComments(Func <DotNetQualifiedName, DotNetType> FindType, List <DotNetQualifiedName> inheritancePath = null) { if (inheritancePath == null) { inheritancePath = new List <DotNetQualifiedName>(); } if (inheritancePath.Contains(this.Name)) { return; //inheritance loop } DotNetType baseType = null; if (BaseType != null) { baseType = FindType(BaseType.Name); if (baseType != null && baseType.InheritsDocumentation) { List <DotNetQualifiedName> copiedInheritancePath = inheritancePath.Select(x => x).ToList(); copiedInheritancePath.Add(this.Name); baseType.ResolveInheritedComments(FindType, copiedInheritancePath); } } List <DotNetType> baseInterfaces = new List <DotNetType>(); foreach (DotNetBaseType implementedInterface in ImplementedInterfaces) { DotNetType baseInterface = FindType(implementedInterface.Name); if (baseInterface != null) { baseInterfaces.Add(baseInterface); if (baseInterface.InheritsDocumentation) { List <DotNetQualifiedName> copiedInheritancePath = inheritancePath.Select(x => x).ToList(); copiedInheritancePath.Add(this.Name); baseInterface.ResolveInheritedComments(FindType, copiedInheritancePath); } } } if (this.InheritsDocumentation && baseType != null) { this.CopyComments(baseType); } if (baseType != null) { foreach (DotNetField field in Fields) { if (!field.InheritsDocumentation) { continue; } DotNetField baseField = baseType.FindInheritedField(FindType, field.Name.LocalName); if (baseField != null) { field.CopyComments(baseField); } } } foreach (DotNetProperty property in Properties) { if (!property.InheritsDocumentation) { continue; } if (baseType != null) { DotNetProperty baseProperty = baseType.FindInheritedProperty(FindType, property.Name.LocalName); if (baseProperty != null) { property.CopyComments(baseProperty); continue; } } foreach (DotNetType baseInterface in baseInterfaces) { if (property.Name.ExplicitInterface != null && property.Name.ExplicitInterface != baseInterface.Name) { continue; } DotNetProperty baseProperty = baseInterface.FindInheritedProperty(FindType, property.Name.LocalName); if (baseProperty != null) { property.CopyComments(baseProperty); break; } } } foreach (DotNetEvent _event in Events) { if (!_event.InheritsDocumentation) { continue; } if (baseType != null) { DotNetEvent baseEvent = baseType.FindInheritedEvent(FindType, _event.Name.LocalName); if (baseEvent != null) { _event.CopyComments(baseEvent); continue; } } } foreach (DotNetMethod method in Methods) { if (!method.InheritsDocumentation) { continue; } if (baseType != null) { DotNetMethod baseMethod = baseType.FindInheritedMethod(FindType, method.MethodName); if (baseMethod != null) { method.CopyComments(baseMethod); continue; } } foreach (DotNetType baseInterface in baseInterfaces) { if (method.Name.ExplicitInterface != null && method.Name.ExplicitInterface != baseInterface.Name) { continue; } DotNetMethod baseMethod = baseInterface.FindInheritedMethod(FindType, method.MethodName); if (baseMethod != null) { method.CopyComments(baseMethod); break; } } } foreach (DotNetType nestedType in NestedTypes) { nestedType.ResolveInheritedComments(FindType); } }
/// <summary> /// Load additional information from the assembly for this type. /// </summary> private void AddAssemblyInfo(Type type) { if (type.Attributes.IsAbstract()) { Category = TypeCategory.Abstract; } if (type.Attributes.IsStatic()) { Category = TypeCategory.Static; } if (type.Attributes.IsInterface()) { Category = TypeCategory.Interface; } if (type.IsEnum()) { Category = TypeCategory.Enum; } if (type.IsException()) { Category = TypeCategory.Exception; } if (type.IsValueType && !type.IsEnum()) { Category = TypeCategory.Struct; } if (Category == TypeCategory.Unknown) { Category = TypeCategory.Normal; } IsSealed = type.IsSealed; ClassName.AddAssemblyInfo(type); if (type.BaseType != null) { BaseType = new DotNetBaseType(type.BaseType); } Type[] implementedInterfaces = type.GetInterfaces(); if (implementedInterfaces != null) { foreach (Type interfaceType in implementedInterfaces) { ImplementedInterfaces.Add(new DotNetBaseType(interfaceType)); } } foreach (FieldInfo fieldInfo in type.GetDeclaredFields()) { DotNetField field = Fields.FirstOrDefault(f => fieldInfo.Name == f.Name.LocalName); if (field == null) { continue; } field.AddAssemblyInfo(fieldInfo); } foreach (PropertyInfo propertyInfo in type.GetDeclaredProperties().Where(x => x.GetGetMethod() == null || x.GetGetMethod().GetParameters().Count() == 0)) { DotNetProperty property = Properties.FirstOrDefault(p => propertyInfo.Name == DotNetQualifiedName.Combine(p.Name.ExplicitInterface, p.Name.LocalName)); if (property == null) { continue; } property.AddAssemblyInfo(propertyInfo); } foreach (PropertyInfo propertyInfo in type.GetDeclaredProperties().Where(x => x.GetGetMethod() != null && x.GetGetMethod().GetParameters().Count() > 0)) { DotNetIndexer indexer = Properties.OfType <DotNetIndexer>().Cast <DotNetIndexer>().FirstOrDefault(i => i.MatchesSignature(propertyInfo.GetGetMethod())); if (indexer == null) { continue; } indexer.AddAssemblyInfo(propertyInfo); } foreach (MethodInfo methodInfo in type.GetDeclaredMethods()) { DotNetMethod method = Methods.FirstOrDefault(m => m.MatchesSignature(methodInfo)); if (method == null) { continue; } if (methodInfo.Attributes.IsPrivate() && method.Name.ExplicitInterface == null) { Methods.Remove(method); continue; } method.AddAssemblyInfo(methodInfo); } foreach (ConstructorInfo constructorInfo in type.GetDeclaredConstructors()) { DotNetMethodConstructor method = Methods.OfType <DotNetMethodConstructor>().Cast <DotNetMethodConstructor>().FirstOrDefault(m => m.MatchesArguments(constructorInfo.GetParameters())); if (method == null) { continue; } method.AddAssemblyInfo(constructorInfo); } foreach (EventInfo eventInfo in type.GetDeclaredEvents()) { DotNetEvent e = Events.FirstOrDefault(m => m.Name.LocalName == eventInfo.Name); if (e == null) { continue; } e.AddAssemblyInfo(eventInfo); } foreach (Type nestedType in type.GetDeclaredNestedTypes()) { DotNetQualifiedName qualifiedName = DotNetQualifiedName.FromAssemblyInfo(nestedType); DotNetType dotNetNestedType = NestedTypes.FirstOrDefault(x => x.Owns(qualifiedName)); if (dotNetNestedType == null) { continue; } dotNetNestedType.AddAssemblyInfo(type, qualifiedName); } PushGenericTypes(); }