/// <summary> /// Parses a .Net XML documentation type, method, or other member name. /// </summary> /// <param name="name"> /// <list> /// <item>Names starting with "T:" are parsed as Type names.</item> /// <item>Names starting with "M:" are parsed as Method names.</item> /// <item>Names starting with "F:" are parsed as Member names.</item> /// <item>Names starting with "P:" are parsed as Member names.</item> /// <item>Names starting with "E:" are parsed as Member names.</item> /// <item>All others are parsed as Member names.</item> /// </list> /// </param> public static DotNetQualifiedName FromVisualStudioXml(string name) { if (String.IsNullOrEmpty(name)) { return(new DotNetQualifiedName()); } if (name.Length < 2 || name[1] != ':') { return(MemberNameFromVisualStudioXml(name)); } switch (name[0]) { case 'T': return(DotNetQualifiedClassName.FromVisualStudioXml(name)); case 'M': return(DotNetQualifiedMethodName.FromVisualStudioXml(name)); case 'F': case 'P': case 'E': return(MemberNameFromVisualStudioXml(name)); default: return(MemberNameFromVisualStudioXml(name)); } }
/// <summary> /// Parses a .Net XML documentation type name or namespace name. /// </summary> /// <remarks> /// Does not differentiate between types and namespaces /// because a nested type will have other type names in its namespace path /// and there are no important diffences in parsing the two. /// </remarks> /// <example> /// <para> /// How .Net xml documentation formats generic types: /// Backtics are followed by integers, identifying generic types. /// </para> /// <para> /// Single backtics (such as `1) on a class declaration indicate a count of generic types for the class. /// For example, <![CDATA[MyGenericType<T,U,V>]]> is documented as <c>MyGenericType`3</c>. /// Anywhere else within this object's documentation that a single backtic appears, it indicates the zero-based index of the generic type in reference to the class declaration. /// For example, the constructor <![CDATA[MyGenericType(T,U,V)]]> is documented as <c>MyGenericType.#ctor(`0,`1,`2)</c>. /// </para> /// </example> /// <param name="name">Name may or may not start with "T:"</param> public new static DotNetQualifiedClassName FromVisualStudioXml(string name) { if (name.StartsWith("T:")) { name = name.Substring(2); } int divider = name.LastIndexOf('.'); string localName = name; string fullNamespace = null; if (divider != -1) { localName = name.Substring(divider + 1); fullNamespace = name.Substring(0, divider); } int classGenericTypeCount = 0; if (localName.Contains("`")) { Int32.TryParse(localName.Substring(localName.IndexOf('`') + 1), out classGenericTypeCount); localName = localName.Substring(0, localName.IndexOf('`')); } if (String.IsNullOrEmpty(fullNamespace)) { return(new DotNetQualifiedClassName(localName, classGenericTypeCount)); } return(new DotNetQualifiedClassName(localName, DotNetQualifiedClassName.FromVisualStudioXml(fullNamespace), classGenericTypeCount)); }
/// <summary> /// Parse .Net XML documentation for Type data. /// </summary> /// <param name="memberElement">Expects tag name "member".</param> /// <example><![CDATA[<member name="T:Namespace.Type"></member>]]></example> public static DotNetType FromVisualStudioXml(XElement memberElement) { DotNetQualifiedClassName name = DotNetQualifiedClassName.FromVisualStudioXml(memberElement.GetAttributeValue("name")); DotNetType type = new DotNetType(name); type.ParseVisualStudioXmlDocumentation(memberElement); return(type); }
/// <summary> /// Parses a .Net XML documentation member name. /// </summary> /// <remarks> /// There is no support for generic types here because .Net XMl documentation does not include member types, just the names. /// </remarks> /// <remarks> /// Does not parse method names; use DotNetQualifiedMethodName.FromVisualStudioXml(string) instead. /// </remarks> /// <example> /// Expected formats: /// - "F:NamespaceA.NamespaceB.MemberC" /// - "P:NamespaceA.NamespaceB.MemberC" /// - "E:NamespaceA.NamespaceB.MemberC" /// - "NamespaceA.NamespaceB.MemberC" /// - "NamespaceA.NamespaceB.InterfaceNamespace#Interface#MemberC" /// </example> /// <param name="name">Name may or may not start with /[FPE]:/</param> private static DotNetQualifiedName MemberNameFromVisualStudioXml(string name) { if (name.StartsWith("F:")) { name = name.Substring(2); } if (name.StartsWith("P:")) { name = name.Substring(2); } if (name.StartsWith("E:")) { name = name.Substring(2); } int divider = name.LastIndexOf('.'); string localName = name; string fullNamespace = null; if (divider != -1) { localName = name.Substring(divider + 1); fullNamespace = name.Substring(0, divider); } DotNetQualifiedName explicitInterface = null; if (localName.Contains("#")) { int lastIndex = localName.LastIndexOf("#"); string interfaceName = localName.Substring(0, lastIndex).Replace("#", "."); explicitInterface = DotNetQualifiedName.FromVisualStudioXml(interfaceName); localName = localName.Substring(lastIndex + 1); } if (String.IsNullOrEmpty(fullNamespace)) { return(new DotNetQualifiedName(localName, explicitInterface)); } return(new DotNetQualifiedName(localName, DotNetQualifiedClassName.FromVisualStudioXml(fullNamespace), explicitInterface)); }