/// <summary>Equality is based on the full namespace/name/generic-type-parameters of the method, and on parameter-types.</summary> public override bool Equals(Object b) { if (!(b is DotNetMethod)) { return(false); } if (object.ReferenceEquals(this, null) && object.ReferenceEquals(b, null)) { return(true); } if (object.ReferenceEquals(this, null) || object.ReferenceEquals(b, null)) { return(false); } DotNetMethod other = (b as DotNetMethod); if (this.Name != other.Name) { return(false); } if (this.MethodName.Parameters.Count != other.MethodName.Parameters.Count) { return(false); } for (int i = 0; i < this.MethodName.Parameters.Count; i++) { if (this.MethodName.Parameters[i].TypeName != other.MethodName.Parameters[i].TypeName) { return(false); } } return(true); }
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 method, 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="methodName">Name of method, local to this type.</param> public DotNetMethod FindInheritedMethod(Func <DotNetQualifiedName, DotNetType> FindType, DotNetQualifiedMethodName methodName) { DotNetMethod method = Methods.FirstOrDefault(m => m.MatchesLocalSignature(methodName)); if (method != null) { return(method); } if (BaseType != null) { DotNetType baseType = FindType(BaseType.Name); if (baseType != null) { return(baseType.FindInheritedMethod(FindType, methodName)); } } return(null); }
/// <summary> /// Parse .Net XML documentation for method signature data. /// </summary> /// <param name="memberElement">Expects tag "member".</param> /// <example><![CDATA[<member name="M:Namespace.Type.MethodName(System.Int32,System.String)"></member>]]></example> public static DotNetMethod FromVisualStudioXml(XElement memberElement) { string signature = memberElement.GetAttributeValue("name"); if (signature == null) { return(new DotNetMethod()); } DotNetQualifiedMethodName methodName = DotNetQualifiedMethodName.FromVisualStudioXml(signature); //for constructors bool isConstructor = (methodName.LocalName.EndsWith("#ctor") || methodName.LocalName.EndsWith("#cctor")); bool isStatic = methodName.LocalName.EndsWith("#cctor"); //for destructors bool isDestructor = (methodName.LocalName == "Finalize" && methodName.Parameters.Count == 0); //for operators bool isOperator = methodName.LocalName.StartsWith("op_"); DotNetMethod method = null; if (isConstructor) { method = new DotNetMethodConstructor(methodName, isStatic); } else if (isDestructor) { method = new DotNetMethodDestructor(methodName); } else if (isOperator) { method = new DotNetMethodOperator(methodName); } else { method = new DotNetMethod(methodName); } method.ParseVisualStudioXmlDocumentation(memberElement); return(method); }
/// <summary> /// Returns true if this method link and the method have matching signatures, based on the fully qualified name and the list of parameter types. /// </summary> public bool MatchesSignature(DotNetMethod method) { return(MethodName.MatchesSignature(method.MethodName)); }
/// <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(); }