/* Copyright (c) Eric Ledoux. All rights reserved. */ /* See http://www.dwell.net/terms for code sharing information. */ // Topic.cs // // Implements class Topic and related types. // using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.IO; using System.Text; using System.Text.RegularExpressions; using System.Web.UI; using System.Xml; using DwellNet.CodeDoc; using CodeDocApi.Properties; namespace DwellNet.CodeDoc {
Topic Class
A documentation topic. |
[DebuggerDisplay("{DebuggerDisplay}")] public class Topic : IComparable<Topic> { ////////////////////////////////////////////////////////////////////////// // Private Fields //
Topic.s_nonFileNameCharRegex Field
Matches a character that we don't want to include in a file name returned by e.g. MakeValidFileName. |
static readonly Regex s_nonFileNameCharRegex = new Regex(@"[^a-zA-Z0-9_~\[\],.]");
Topic.s_insignificantWhiteSpaceRegex Field
Matches what would be considered insignificant white space in HTML. |
static readonly Regex s_insignificantWhiteSpaceRegex = new Regex(@"[ \r\n\t]+");
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
DocumentationSet m_docSet;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
string m_name;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
int m_id;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
TopicKind m_topicKind;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
Topic m_parentTopic;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
SourceFile m_sourceFile;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
XmlCommentToken m_xmlCommentToken;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
string m_xml;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
Token m_startOfDeclaration;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
TokenList m_modifiers;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
TokenList m_namespaceName;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
NamespaceTopic m_namespaceTopic;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
TokenList m_memberType;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
TokenList m_explicitPrefix;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
string m_memberName;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
TokenList[] m_typeParameters;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
TokenList[] m_baseTypes;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
Topic m_baseClassTopic;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
TokenList m_constraints;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
List<Parameter> m_parameters;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
MethodKind m_methodKind;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
PropertyKind m_propertyKind;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
List<string> m_enumValueNames;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
List<TokenList> m_attributes;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
Accessor m_getAccessor;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
Accessor m_setAccessor;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
UsingContext m_usingContext;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
List<Topic> m_childTopics;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
bool m_isTypeTopic;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
bool m_isDocumented;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
OverloadListTopic m_overloadListTopic;
Topic.m_xmlSectionsHtml Field
Holds the HTML for each top-level section (e.g. "<summary>" or "<param>" of the value of the XML documentation associated with this topic. Element n corresponds to the XmlCommentSectionKind enumeration value equal to n; the value is a list since there can be multiple sections of the same kind (e.g. one "<param>" section per parameter). |
List<XmlCommentSection>[] m_xmlSectionsHtml; ////////////////////////////////////////////////////////////////////////// // Private Properties // #if DEBUG /// <summary> /// Gets a string displayed in the debugger. /// </summary> public string DebuggerDisplay { get { TokenList nameList = QualifiedMemberName; if (nameList == null) return TopicKind.ToString(); string name = nameList.ToString(); if (name == null) return TopicKind.ToString(); else { string moreInfo; if (TopicKind == TopicKind.MethodTopic) { if (MethodKind != MethodKind.Normal) moreInfo = String.Format(" ({0})", MethodKind); else moreInfo = ""; } else if (TopicKind == TopicKind.PropertyTopic) { if (PropertyKind != PropertyKind.Normal) moreInfo = String.Format(" ({0})", PropertyKind); else moreInfo = ""; } else moreInfo = ""; return String.Format("{0} {1}{2}", TopicKind, QualifiedMemberName, moreInfo); } } } #endif ////////////////////////////////////////////////////////////////////////// // Public Properties //
Topic.DocumentationSet Property
The documentation set that contains this topic. |
public DocumentationSet DocumentationSet { [DebuggerStepThrough] get { return m_docSet; } [DebuggerStepThrough] internal set { m_docSet = value; } }
public TopicKind TopicKind { [DebuggerStepThrough] get { return m_topicKind; } [DebuggerStepThrough] internal set { m_topicKind = value; } }
Topic.ParentTopic Property
The topic of the type specified by ParentTypeName. null if none or not applicable. Note that TopicKind.NamespaceTopic topics have no parent topic. |
public Topic ParentTopic { [DebuggerStepThrough] get { return m_parentTopic; } [DebuggerStepThrough] internal set { m_parentTopic = value; } }
Topic.SourceFile Property
The source file containing this topic; null if none. |
public SourceFile SourceFile { [DebuggerStepThrough] get { return m_sourceFile; } [DebuggerStepThrough] internal set { m_sourceFile = value; } }
Topic.FirstXmlComment Property
The XML comment associated with this topic; null if none. |
public XmlCommentToken FirstXmlComment { [DebuggerStepThrough] get { return m_xmlCommentToken; } [DebuggerStepThrough] internal set { m_xmlCommentToken = value; // do nothing if there is no array of } }
Topic.Xml Property
The XML markup from XML comment token(s) starting at FirstXmlComment; null if none. |
public string Xml { [DebuggerStepThrough] get { return m_xml; } [DebuggerStepThrough] internal set { m_xml = value; } }
Topic.StartOfDeclaration Property
The beginning of the declaration following the XML comment(s) associated with this topic; null if none. |
public Token StartOfDeclaration { [DebuggerStepThrough] get { return m_startOfDeclaration; } [DebuggerStepThrough] internal set { m_startOfDeclaration = value; // do nothing if there is no array of } }
Topic.Modifiers Property
The modifiers of the member documented by this topic, if applicable; for example, "public static". null if none or not applicable. |
public TokenList Modifiers { [DebuggerStepThrough] get { return m_modifiers; } [DebuggerStepThrough] internal set { m_modifiers = value; } }
Topic.NamespaceName Property
The namespace that contains the member documented by this topic, if applicable; for example, "Abc.Def". null if none or not applicable. null for TopicKind.NamespaceTopic topics; MemberName is the namespace name of a namespace topic (String.Empty for the global namespace). |
public TokenList NamespaceName { [DebuggerStepThrough] get { return m_namespaceName; } [DebuggerStepThrough] internal set { m_namespaceName = value; } }
Topic.NamespaceTopic Property
The TopicKind.NamespaceTopic topic that refers to the namespace that contains the member documented by this topic, if applicable. null if none or not applicable. null for TopicKind.NamespaceTopic topics. |
public NamespaceTopic NamespaceTopic { [DebuggerStepThrough] get { return m_namespaceTopic; } [DebuggerStepThrough] internal set { m_namespaceTopic = value; } }
Topic.ParentTypeName Property
Gets the name of the class, struct, or enum that contains the member documented by this topic, if applicable; for example, "Abc.Def" in the case of enum "Def" nested within "Abc". Includes type parameters for each ancestor type. null if none or not applicable. |
public TokenList ParentTypeName { get { if ((ParentTopic == null) || (TopicKind == TopicKind.NamespaceTopic)) return null; TokenList tokenList = new TokenList(); if (ParentTopic.CopyTypeName(tokenList)) return tokenList; else return null; } }
Topic.MemberType Property
The type of the member documented by this topic, if applicable; for example, "Ghi" (in the case of constant, field, etc. named "Ghi"). For method topics, this is the return type. For namespace topics, this is the fully-qualified namespace name. null if none or not applicable (for example, for Topic objects that document a type). |
public TokenList MemberType { [DebuggerStepThrough] get { return m_memberType; } [DebuggerStepThrough] internal set { m_memberType = value; } }
Topic.ExplicitPrefix Property
For members that are explicit interface implementations (e.g. "IDisposable.Dispose"), this is the prefix before the member name (e.g. "IDisposable."). For other members, this is null. |
public TokenList ExplicitPrefix { [DebuggerStepThrough] get { return m_explicitPrefix; } [DebuggerStepThrough] internal set { m_explicitPrefix = value; } }
Topic.MemberName Property
The name of the member documented by this topic, if applicable; examples: "Ghi" (in the case of class, struct, interface, event, delegate, enum, method, property, etc. named "Ghi"); "operator +" (in the case of an operator). null if none or not applicable.
Remarks
For members that are explicit interface implementations (e.g. "IDisposable.Dispose"), only the actual member name (e.g. "Dispose") is MemberName) -- the rest is ExplicitPrefix. |
public string MemberName { [DebuggerStepThrough] get { return m_memberName; } [DebuggerStepThrough] internal set { m_memberName = value; } }
Topic.TypeParameters Property
The type parameters of the member documented by this topic, if applicable; for example, "T" and "U" for type parameter declaration "<T,U>", and "string" and "List<int>" for the type parameter declaration "<string, List<int>>". null if none or not applicable. |
public TokenList[] TypeParameters { [DebuggerStepThrough] get { return m_typeParameters; } [DebuggerStepThrough] internal set { m_typeParameters = value; } }
Topic.BaseTypes Property
The base types of the member documented by this topic, if applicable; for example, "List<T>" and "IDisposable" in class declaration "class Abc : List<T>, IDisposable { ... }". null if none or not applicable. |
public TokenList[] BaseTypes { [DebuggerStepThrough] get { return m_baseTypes; } [DebuggerStepThrough] internal set { m_baseTypes = value; } }
Topic.BaseClassTopic Property
The |
public Topic BaseClassTopic { [DebuggerStepThrough] get { return m_baseClassTopic; } [DebuggerStepThrough] internal set { m_baseClassTopic = value; } }
Topic.Constraints Property
The "where" clause list of the member documented by this topic, if applicable; for example, "where T : IDisposable where U : struct { ... }". null if none or not applicable. |
public TokenList Constraints { [DebuggerStepThrough] get { return m_constraints; } [DebuggerStepThrough] internal set { m_constraints = value; } }
Topic.Parameters Property
Gets the parameters of the member documented by this topic, if applicable, i.e. if the member is a method or indexer; null if none or not applicable. Note that if this member has a parameter list but that parameter list is empty then an empty collection is returned. |
public IList<Parameter> Parameters { [DebuggerStepThrough] get { if (m_parameters == null) return null; else return new ReadOnlyCollection<Parameter>(m_parameters); } }
Topic.ParametersArray Property
Gets a copy of Parameters as an array. null if none or not applicable. |
public Parameter[] ParametersArray { get { if ((m_parameters == null) || (m_parameters.Count == 0)) return null; else return m_parameters.ToArray(); } }
internal List<Parameter> ParametersList { [DebuggerStepThrough] get { return m_parameters; } [DebuggerStepThrough] set { m_parameters = value; } }
Topic.MethodKind Property
What kind of method this is (if any). MethodKind.NotAMethod if none or not applicable. |
public MethodKind MethodKind { [DebuggerStepThrough] get { return m_methodKind; } [DebuggerStepThrough] internal set { m_methodKind = value; } }
Topic.PropertyKind Property
What kind of property this is (if any). PropertyKind.NotAProperty if none or not applicable. |
public PropertyKind PropertyKind { [DebuggerStepThrough] get { return m_propertyKind; } [DebuggerStepThrough] internal set { m_propertyKind = value; } }
Topic.EnumValueNames Property
Gets the names of the values declared in this enum, if this is an enum; for example, "Yes" and "No" in "enum Answer { Yes, No }". null if none or not applicable. |
public IList<string> EnumValueNames { [DebuggerStepThrough] get { if ((m_enumValueNames == null) || (m_enumValueNames.Count == 0)) return null; else return new ReadOnlyCollection<string>(m_enumValueNames); } }
Topic.EnumValueNamesArray Property
Gets a copy of EnumValueNames as an array. null if none or not applicable. |
public string[] EnumValueNamesArray { get { if ((m_enumValueNames == null) || (m_enumValueNames.Count == 0)) return null; else return m_enumValueNames.ToArray(); } }
internal List<string> EnumValueNamesList { [DebuggerStepThrough] get { return m_enumValueNames; } [DebuggerStepThrough] set { m_enumValueNames = value; } }
Topic.Attributes Property
Gets a list of attributes, such as "Bar(X=15, Y=67)" within "[Foo(123), Bar(X=45, Y=67)]", of this member. null if none or not applicable. |
public IList<TokenList> Attributes { [DebuggerStepThrough] get { if ((m_attributes == null) || (m_attributes.Count == 0)) return null; else return new ReadOnlyCollection<TokenList>(m_attributes); } }
Topic.GetAccessor Property
Gets information about the "get" accessor if this the declaration of a property that has a "get" accessor. null if none or not applicable. |
public Accessor GetAccessor { [DebuggerStepThrough] get { return m_getAccessor; } [DebuggerStepThrough] internal set { m_getAccessor = value; } }
Topic.SetAccessor Property
Gets information about the "set" accessor if this the declaration of a property that has a "set" accessor. null if none or not applicable. |
public Accessor SetAccessor { [DebuggerStepThrough] get { return m_setAccessor; } [DebuggerStepThrough] internal set { m_setAccessor = value; } }
Topic.UsingContext Property
Gets the "using" directive information associated with this topic. |
public UsingContext UsingContext { [DebuggerStepThrough] get { return m_usingContext; } [DebuggerStepThrough] internal set { m_usingContext = value; } }
Topic.ChildTopics Property
Gets the list of topics for which this topic is specified as the ParentTopic. Returns an empty collection if there are no child topics. |
public IList<Topic> ChildTopics { [DebuggerStepThrough] get { if (m_childTopics == null) return new ReadOnlyCollection<Topic>(new List<Topic>()); else return new ReadOnlyCollection<Topic>(m_childTopics); } }
Topic.MemberTopics Property
Enumerates the topics which should appear in this topics list of member topics. If this topic is a TopicKind.ClassTopic, the enumeration includes members of the base class, and that class's base class, and so on, including only documented classes (not System.Object, for example). An ancestor class member is not included if it is overridden by a descendent up to and including this class.
Remarks
Classes are searched for inherited members, but structs are not (since structs don't support inheritance), and interfaces are not (since conventionally inherited members are not documented for interfaces). |
public IEnumerable<MemberInfo> MemberTopics { get { // first, yield all documented non-overload-list topics that are // children of this topic; keep track of the signature of yielded // topics in <signatures> Dictionary<string, bool> signatures; if (TopicKind == TopicKind.ClassTopic) signatures = new Dictionary<string, bool>(20); else signatures = null; foreach (Topic memberTopic in ChildTopics) { if (!memberTopic.IsDocumented || (memberTopic is OverloadListTopic)) continue; yield return new MemberInfo(memberTopic, null); if (TopicKind == TopicKind.ClassTopic) { string signature = memberTopic.GetOverloadingSignature(); if (signature != null) signatures[signature] = true; } } // if this topic isn't a class topic, we're done if (TopicKind != TopicKind.ClassTopic) yield break; // loop once for each ancestor class Topic baseClassTopic = BaseClassTopic; int inherited = 0; while (baseClassTopic != null) { // yield topics that should be added to the list of member // topics, i.e. documented non-overload-list property or method // topics (excluding constructors and destructors) that are // public or protected and which don't have a signature of a // topic we've already yielded foreach (Topic memberTopic in baseClassTopic.ChildTopics) { if (!memberTopic.IsDocumented) continue; // not a documented topic if (memberTopic is OverloadListTopic) continue; // skip overload list topics if (!memberTopic.HasModifier("public", "protected")) continue; // not public or protected string signature = memberTopic.GetOverloadingSignature(); if (signature == null) continue; // not an overloadable property or method bool unused; if (signatures.TryGetValue(signature, out unused)) continue; // overridden yield return new MemberInfo(memberTopic, baseClassTopic); signatures.Add(signature, true); inherited++; } // continue up the inheritance tree baseClassTopic = baseClassTopic.BaseClassTopic; } // for debugging purposes: display the number of inherited members #if false && DEBUG if (inherited > 0) { Console.WriteLine("{0}: inherited {1} members", this, inherited); } #endif } }
Topic.DescendentTopics Property
Enumerates the topics for which this topic is specified as the ParentTopic or the Topic.ParentTopic and so on. Returns an empty enumeration if there are no descendent topics. Note that "decendent" here refers to nesting, not derivation. |
public IEnumerable<Topic> DescendentTopics { get { foreach (Topic childTopic in ChildTopics) { yield return childTopic; foreach (Topic descendentTopic in childTopic.DescendentTopics) yield return descendentTopic; } } }
Topic.IsTypeTopic Property
Returns true if this is a type topic, i.e. a topic that is listed in NamespaceTopic.TypeTopics. |
public bool IsTypeTopic { [DebuggerStepThrough] get { return m_isTypeTopic; } [DebuggerStepThrough] internal set { m_isTypeTopic = value; } }
Topic.IsDocumented Property
Gets or sets a value indicating if this is a documented topic, i.e. a topic for which documentation is supposed to be generated. |
public bool IsDocumented { [DebuggerStepThrough] get { return m_isDocumented; } [DebuggerStepThrough] set { m_isDocumented = value; } }
Topic.CanLinkTo Property
Returns true if this topic can be hyperlinked to. Topics that have IsDocumented equal to true or that are enumeration value topics with documented parent enumeration topics can be linked to. (In the latter case, no documenation is generated for the enumeration value topic -- hyperlinks are directed to the parent enumeration topic.) |
public bool CanLinkTo { get { return IsDocumented || ((TopicKind == TopicKind.EnumValueTopic) && (ParentTopic != null) && (ParentTopic.TopicKind == TopicKind.EnumTopic) && ParentTopic.IsDocumented); } }
Topic.OverloadListTopic Property
Returns the OverloadListTopic for this topic, if this topic is an overload, i.e. if there are other topics with the same BaseName. Returns null otherwise. |
public OverloadListTopic OverloadListTopic { [DebuggerStepThrough] get { return m_overloadListTopic; } [DebuggerStepThrough] internal set { m_overloadListTopic = value; } }
Topic.AttributesArray Property
Gets a copy of Attributes as an array. null if none or not applicable. |
public TokenList[] AttributesArray { get { if ((m_attributes == null) || (m_attributes.Count == 0)) return null; else return m_attributes.ToArray(); } }
internal List<TokenList> AttributesList { [DebuggerStepThrough] get { return m_attributes; } [DebuggerStepThrough] set { m_attributes = value; } }
Topic.TopicKindCSharpKeyword Property
Returns the C# declaration term (e.g. "class") corresponding to TopicKind (e.g. TopicKind.ClassTopic). |
public string TopicKindCSharpKeyword { get { switch (TopicKind) { case TopicKind.NamespaceTopic: return "namespace"; case TopicKind.ClassTopic: return "class"; case TopicKind.StructTopic: return "struct"; case TopicKind.InterfaceTopic: return "interface"; case TopicKind.EventTopic: return "event"; case TopicKind.DelegateTopic: return "delegate"; case TopicKind.EnumTopic: return "enum"; case TopicKind.UnknownTopic: return "unknown"; default: return TopicKind.ToString(); } } }
Topic.TopicKindTitle Property
Returns a title-case label (for example, "Class" or "Structure") corresponding to a given TopicKind. |
public string TopicKindTitle { get { switch (TopicKind) { case TopicKind.NamespaceTopic: return Resources.NamespaceTopicTitle; case TopicKind.ClassTopic: return Resources.ClassTopicTitle; case TopicKind.StructTopic: return Resources.StructTopicTitle; case TopicKind.InterfaceTopic: return Resources.InterfaceTopicTitle; case TopicKind.EventTopic: return Resources.EventTopicTitle; case TopicKind.DelegateTopic: return Resources.DelegateTopicTitle; case TopicKind.EnumTopic: return Resources.EnumTopicTitle; case TopicKind.EnumValueTopic: return Resources.EnumValueTopicTitle; case TopicKind.MethodTopic: return Resources.MethodTopicTitle; case TopicKind.PropertyTopic: return Resources.PropertyTopicTitle; case TopicKind.FieldTopic: return Resources.FieldTopicTitle; default: return Resources.UnknownTopicTitle; } } }
Topic.QualifiedMemberName Property
Gets the member name with the namespace name and parent class name (if any) prepended. |
public TokenList QualifiedMemberName { get { TokenList result = new TokenList(); ConstructQualifiedMemberName(result, true, true, false); if (result.IsEmpty) return null; else return result; } }
Topic.QualifiedMemberNameWithoutNamespace Property
Gets the member name with the parent class name (if any) prepended, but without the parent namespace name prepended. |
public TokenList QualifiedMemberNameWithoutNamespace { get { TokenList result = new TokenList(); ConstructQualifiedMemberName(result, false, true, false); if (result.IsEmpty) return null; else return result; } }
Topic.CanonicalName Property
Gets the canonical name of this topic. CanonicalName is the same as QualifiedMemberName except that type parameter names are removed from the name. For example, if QualifiedMemberName is "Foo<T,U>.Bar", CanonicalName is "Foo<,>.Bar".
Remarks
Consider a class As shown in the example above, the canonical name of a type with type parameters includes the type parameters (except with type parameter names removed). However, the canonical name of a method with type parameters does not include the type parameters. For example, a method While a method's type parameters are excluded from the method's canonical name, the type parameters of the type of the method are not. For example, method CanonicalizeMemberName can be used to convert a type name (e.g. "Outer<T>.Inner<U,V>.Inner2") or type reference (e.g. "Outer<MyList>.Inner<MyPoint<bool>?,int[,]>.Inner2") to its canonical form (e.g. "Outer<>.Inner<,>.Inner2"). The DocumentationSet.DuplicateCanonicalName event is fired if it's discovered that two topics have the same canonical name. |
public TokenList CanonicalName { get { // set <result> to the canonicalized version of // <QualifiedMemberName> TokenList result = CanonicalizeMemberName( QualifiedMemberName, !IsTypeTopic); // if this is a type with type parameters, append their // canonicalized representation, e.g. "<,,>" if (IsTypeTopic && (m_typeParameters != null)) { result.Append(new Token(SourceFile.LAngle)); for (int i = 0; i < m_typeParameters.Length - 1; i++) result.Append(new Token(',')); result.Append(new Token(SourceFile.RAngle)); } return result; } }
Topic.BaseName Property
Gets the base porton of the Name property, i.e. the part that is not necessarily unique among all topics. BaseName is based on QualifiedMemberName -- two topics with the same QualifiedMemberName and the same TopicKind will have the same BaseName.
Remarks
For example, "MyNamespace.Foo.Bar", i.e. method "Bar" in class "Foo" in namespace "MyNamespace", might be a QualifiedMemberName; "MyNamespace.Foo.Bar.Method" would be the corresponding BaseName. |
public string BaseName { get { return String.Format("{0}.{1}", MakeValidFileName(QualifiedMemberName.ToString()), TopicKindTitle.Replace(" ", "")); } }
Topic.Name Property
Gets the name of this topic which is unique among all topics in the documentation set. Since Name is unique, it can be used in a file name. Name is only valid after DocumentationSet.BeginUsingSources has been called (either directly or indirectly).
Remarks
Name is the same as BaseName, except that if two topics would have the same BaseName then a numeric suffix, e.g. ".1", ".2", and so on, is appended to Name to make Name unique. Since DocumentationSet.BeginUsingSources is the method that checks for uniqueness, DocumentationSet.BeginUsingSources must be called in order to initialize Name. |
public string Name { [DebuggerStepThrough] get { return m_name; } [DebuggerStepThrough] internal set { m_name = value; } }
Topic.Id Property
Gets the integer identifier of this topic which is unique among all topics in the documentation set. Id is only valid after DocumentationSet.BeginUsingSources has been called (either directly or indirectly). |
public int Id { [DebuggerStepThrough] get { return m_id; } [DebuggerStepThrough] internal set { m_id = value; } }
Topic.DocHtmlFileName Property
Gets the name of the HTML file that contains, or will contain, the documentation for this topic.
Remarks
|
public string DocHtmlFileName { get { return Name + ".htm"; } }
Topic.CodeHtmlBlockBookmark Property
Gets the HTML bookmark name of this topic, used as the HTML anchor name when this topic is embedded in formatted code; for example, "Topic123" (based on Id). |
public string CodeHtmlBlockBookmark { get { return String.Format("Topic{0}", Id); } }
Topic.CodeHtmlUrl Property
Gets the URL to the documentation block (i.e. documentation embedded in formatted code HTML) of this topic, relative to the formatted code directory; for example, "Foo!Bar.cs.htm#Topic123". Returns null if there is no SourceFile associated with this topic. |
public string CodeHtmlUrl { get { if (TopicKind == TopicKind.NamespaceTopic) return CodeNamespaceHtmlFileName; else if (this is OverloadListTopic) return CodeOverloadListHtmlFileName; else if (TopicKind == TopicKind.NamespaceTopic) return CodeNamespaceHtmlFileName; else if (SourceFile == null) return null; else { return String.Format("{0}#{1}", SourceFile.CodeHtmlFileName, CodeHtmlBlockBookmark); } } }
Topic.CodeNamespaceHtmlFileName Property
If this is an namespace topic, this property returns the name of the code namespace HTML file, i.e. the HTML document that lists the contents of the namespace and provides links to the formatted source code files. Returns null if this is not an namespace topic. |
public string CodeNamespaceHtmlFileName { get { if (this is NamespaceTopic) return String.Format("{0}.CodeNamespace.htm", Name); else return null; } }
Topic.CodeOverloadListHtmlFileName Property
If this is an overload list topic, this property returns the name of the code overload list HTML file, i.e. the HTML document that lists the overloads and provides links to the documentation block of each overload. Returns null if this is not an overload list topic. |
public string CodeOverloadListHtmlFileName { get { if (this is OverloadListTopic) return String.Format("{0}.CodeOverload.htm", Name); else return null; } }
Topic.IsGlobalNamespace Property
Returns true if this topic refers to the global namespace, false if not. |
public bool IsGlobalNamespace { get { return (TopicKind == TopicKind.NamespaceTopic) && (MemberName.Length == 0); } }
Topic.VeryShortTitleNoKind Property
Returns a short title for this topic, not including the class name, parent class name, or parent namespace name (if any), and not including the topic kind (e.g. "Method"). Type parameters and regular parameters are included if this is an overload topic (i.e. a topic for which there are other topics with the same BaseName). |
public string VeryShortTitleNoKind { get { if (IsGlobalNamespace) return Resources.GlobalNamespace; TokenList name = new TokenList(); ConstructQualifiedMemberName(name, false, false, true); if (name.IsEmpty) return TopicKindTitle; else return GetTitle(name.ToString(), false); } }
Topic.VeryShortTitle Property
Returns a short title for this topic, not including the class name, parent class name, or parent namespace name (if any). Type parameters and regular parameters are included if this is an overload topic (i.e. a topic for which there are other topics with the same BaseName). |
public string VeryShortTitle { get { if (IsGlobalNamespace) return Resources.GlobalNamespace; TokenList name = new TokenList(); ConstructQualifiedMemberName(name, false, false, true); if (name.IsEmpty) return TopicKindTitle; else return GetTitle(name.ToString(), true); } }
Topic.ShortTitle Property
Returns a short title for this topic, including the class name and parent class names, if any, but not including the parent namespace name. Type parameters and regular parameters are included if this is an overload topic (i.e. a topic for which there are other topics with the same BaseName). |
public string ShortTitle { get { if (IsGlobalNamespace) return Resources.GlobalNamespace; TokenList name = new TokenList(); bool includeParentType = ((TopicKind != TopicKind.MethodTopic) || !((MethodKind == MethodKind.Constructor) || (MethodKind == MethodKind.Destructor))); ConstructQualifiedMemberName(name, false, includeParentType, true); if (name.IsEmpty) return TopicKindTitle; else return GetTitle(name.ToString(), true); } }
Topic.LongTitle Property
Returns a title for this topic, including the class name and fully qualified parent class names, if any, including the parent namespace name. Type parameters and regular parameters are included if this is an overload topic (i.e. a topic for which there are other topics with the same BaseName). |
public string LongTitle { get { if (IsGlobalNamespace) return Resources.GlobalNamespace; TokenList name = new TokenList(); ConstructQualifiedMemberName(name, true, true, true); if (name.IsEmpty) return TopicKindTitle; else return GetTitle(name.ToString(), true); } }
Topic.ShortSignature Property
Returns a short signature for this topic, including the class name and parent class names, if any, but not including the parent namespace name. Does not include the topic kind, e.g. "Method". Type parameters and regular parameters are included if this is an overload topic (i.e. a topic for which there are other topics with the same BaseName). |
public string ShortSignature { get { TokenList name = new TokenList(); ConstructQualifiedMemberName(name, false, true, true); if (name.IsEmpty) return TopicKindTitle; else return GetTitle(name.ToString(), false); } }
Topic.LongSignature Property
Returns a signature for this topic, including the class name and fully qualified parent class names, if any, including the parent namespace name. Does not include the topic kind, e.g. "Method". Type parameters and regular parameters are included if this is an overload topic (i.e. a topic for which there are other topics with the same BaseName). |
public string LongSignature { get { TokenList name = new TokenList(); ConstructQualifiedMemberName(name, true, true, true); if (name.IsEmpty) return TopicKindTitle; else return GetTitle(name.ToString(), false); } }
Topic.Location Property
Return a human-readable string describing where this topic is within source code. |
public string Location { get { if (SourceFile != null) { return String.Format("{0}({1})", SourceFile.SourceFileAbsolutePath, GetDeclarationLineNumber()); } else if (Name != null) return Name; else return BaseName; } }
Topic.XmlCommentSections Property
Enumerates through the top-level sections (for example, "<summary>" and "<param>") of the contents of the Xml property. |
public IEnumerable<XmlCommentSection> XmlCommentSections { get { if (Xml == null) yield break; XmlReaderSettings settings = new XmlReaderSettings(); settings.IgnoreComments = true; settings.ConformanceLevel = ConformanceLevel.Fragment; settings.LineNumberOffset = FirstXmlComment.GetLineNumber() - 1; using (StringReader stringReader = new StringReader(Xml)) { using (XmlReader xmlReader = XmlReader.Create(stringReader, settings)) { while (true) { try { if (!xmlReader.Read()) break; } catch (XmlException ex) { throw NewParsingException( Resources.InvalidXmlComment, ex.Message); } if (xmlReader.NodeType == XmlNodeType.Element) { // this XML element should be an XML comment // section start element such as "<summary>" or // "<param>" XmlCommentSection section = new XmlCommentSection(this, xmlReader); yield return section; try { section.ReadToEnd(); } catch (XmlException ex) { throw NewParsingException( Resources.InvalidXmlComment, ex.Message); } } else if (xmlReader.NodeType == XmlNodeType.Text) { // there shouldn't be any text outside of XML // comment sections throw NewParsingException(xmlReader, Resources.TextOutsideXmlCommentSection, SourceFile.Ellipsis(xmlReader.Value, 50)); } } } } } }
Topic.HasSummaryHtml Property
Returns true if this topic has a "<summary>" section for which HTML has been generated. |
public bool HasSummaryHtml { get { return HasXmlCommentSectionHtml(XmlCommentSectionKind.Summary); } }
Topic.HasReturnsHtml Property
Returns true if this topic has a "<returns>" section for which HTML has been generated. |
public bool HasReturnsHtml { get { return HasXmlCommentSectionHtml(XmlCommentSectionKind.Returns); } }
Topic.HasValueHtml Property
Returns true if this topic has a "<value>" section for which HTML has been generated. |
public bool HasValueHtml { get { return HasXmlCommentSectionHtml(XmlCommentSectionKind.Value); } }
Topic.HasExceptionsHtml Property
Returns true if this topic has "<exceptons>" section(s) for which HTML has been generated. |
public bool HasExceptionsHtml { get { return HasXmlCommentSectionHtml(XmlCommentSectionKind.Exception); } }
Topic.HasPermissionsHtml Property
Returns true if this topic has "<permission>" section(s) for which HTML has been generated. |
public bool HasPermissionsHtml { get { return HasXmlCommentSectionHtml(XmlCommentSectionKind.Permission); } }
Topic.HasRemarksHtml Property
Returns true if this topic has "<remarks>" section(s) for which HTML has been generated. |
public bool HasRemarksHtml { get { return HasXmlCommentSectionHtml(XmlCommentSectionKind.Remarks); } }
Topic.HasExampleHtml Property
Returns true if this topic has "<example>" section(s) for which HTML has been generated. |
public bool HasExampleHtml { get { return HasXmlCommentSectionHtml(XmlCommentSectionKind.Example); } }
Topic.HasSeeAlsoHtml Property
Returns true if this topic has "<seealso>" section(s) for which HTML has been generated. |
public bool HasSeeAlsoHtml { get { return HasXmlCommentSectionHtml(XmlCommentSectionKind.SeeAlso); } }
Topic.IsExternallyAccessible Property
Returns true if the member defined by this topic is accessible outside of this program or library. |
public bool IsExternallyAccessible { get { OverloadListTopic overloadListTopic; if ((overloadListTopic = this as OverloadListTopic) != null) { // overload list topics are accessible if at least one of their // overload topics are accessible foreach (Topic topic in overloadListTopic.OverloadTopics) { if (topic.IsExternallyAccessible) return true; } return false; } else { // regular topics are accessible based on their modifiers and // their ancestors' modifiers Topic topic = this; while (true) { bool isInterfaceMember = ((topic.ParentTopic != null) && (topic.ParentTopic.TopicKind == TopicKind.InterfaceTopic)); if (!topic.HasModifier("public", "protected") && !isInterfaceMember) return false; topic = topic.ParentTopic; if (topic == null) break; if (topic.TopicKind == TopicKind.NamespaceTopic) break; } return true; } } } ////////////////////////////////////////////////////////////////////////// // Public Methods //
public void SortChildTopics() { if (m_childTopics != null) m_childTopics.Sort(); }
Topic.GetDeclarationLineNumber Method
Returns the line number that the declaration begins on. |
public int GetDeclarationLineNumber() { Debug.Assert(StartOfDeclaration != null); if (StartOfDeclaration == null) // just in case return 0; else return StartOfDeclaration.GetLineNumber(); }
public override string ToString() { return QualifiedMemberName.ToString(); }
Topic.CanonicalizeMemberName Method (TokenList, bool)
Converts a qualified member name (i.e. the same value used in Topic.QualifiedMemberName) into a canonicalized member name, which is the same except that type parameter names are removed. For example, "Foo<T,U>.Bar" is converted to "Foo<,>.Bar".
Parameters
memberName The input qualified member name. removeTrailingTypeParameters If true, type parameters of the member are removed. This only applies to type parameters of the member itself, not type(s) the member is nested within. For example, input member name "Foo<T,U>.Bar<V>" is canonicalized as "Foo<,>.Bar" if removeTrailingTypeParameters is true.
Remarks
Type parameter names are removed from all type parameters in memberName. Additionally, if removeTrailingTypeParameters is true, any "trailing type parameters" are removed entirely -- see the Remarks section of QualifiedMemberName for an explanation. |
public static TokenList CanonicalizeMemberName( TokenList memberName, bool removeTrailingTypeParameters) { // do nothing if <memberName> is null if (memberName == null) return null; // if <memberName> doesn't contain type parameters, return it // as-is if (memberName.HeadToken.Next.FindCharacterToken( SourceFile.LAngle) == null) return memberName; // set <result> to a copy of <memberName> with type parameter // names removed TokenList result = new TokenList(); int angleNesting = 0; // in "<...>" int squareNesting = 0; // in "[...]" -- ignore arrays, e.g. "[,]" Token trailingTypeParameter = null; foreach (Token token in memberName) { if (token.IsCharacter(SourceFile.LAngle)) { if (angleNesting == 0) { Token newToken = new Token(SourceFile.LAngle); trailingTypeParameter = newToken; result.Append(newToken); } angleNesting++; } else if (token.IsCharacter(SourceFile.RAngle)) { angleNesting--; if (angleNesting == 0) result.Append(new Token(SourceFile.RAngle)); } else if (token.IsCharacter(SourceFile.LSquare)) squareNesting++; else if (token.IsCharacter(SourceFile.RSquare)) squareNesting--; else if (angleNesting == 0) { result.Append(token.Clone()); trailingTypeParameter = null; } else if (token.IsCharacter(',') && (squareNesting == 0) && (angleNesting == 1)) result.Append(token.Clone()); } Debug.Assert(angleNesting == 0); Debug.Assert(squareNesting == 0); // remove trailing type parameters, if any (if specified) if (removeTrailingTypeParameters && (trailingTypeParameter != null) && !trailingTypeParameter.Next.IsTail) { TokenList.ExtractTokens(trailingTypeParameter, result.TailToken.Previous); } return result; }
Topic.CanonicalizeMemberName Method (string, bool)
Converts a member name into a canonicalized member name, which is the same except that type parameter names, square brackets, etc. are removed. For example, "Foo<T,U>.Bar" is converted to "Foo<,>.Bar".
Parameters
memberName The input qualified member name. removeTrailingTypeParameters If true, type parameters of the member are removed. This only applies to type parameters of the member itself, not type(s) the member is nested within. For example, input member name "Foo<T,U>.Bar<V>" is canonicalized as "Foo<,>.Bar" if removeTrailingTypeParameters is true.
Remarks
Type parameter names are removed from all type parameters in memberName. Additionally, if removeTrailingTypeParameters is true, any "trailing type parameters" are removed entirely -- see the Remarks section of QualifiedMemberName for an explanation. |
public static string CanonicalizeMemberName( string memberName, bool removeTrailingTypeParameters) { // do nothing if <memberName> is null if (memberName == null) return null; #if false // if <memberName> doesn't contain type parameters, return it // as-is if (memberName.IndexOf(SourceFile.LAngle) < 0) return memberName; #endif // set <result> to a copy of <memberName> with type parameter // names removed StringBuilder result = new StringBuilder(memberName.Length); int angleNesting = 0; // in "<...>" int squareNesting = 0; // in "[...]" -- ignore arrays, e.g. "[,]" int trailingTypeParameterIndex = -1; foreach (char ch in memberName) { if (ch == SourceFile.LAngle) { if (angleNesting == 0) { trailingTypeParameterIndex = result.Length; result.Append(ch); } angleNesting++; } else if (ch == SourceFile.RAngle) { angleNesting--; if (angleNesting == 0) result.Append(ch); } else if (ch == SourceFile.LSquare) squareNesting++; else if (ch == SourceFile.RSquare) squareNesting--; else if (angleNesting == 0) { result.Append(ch); trailingTypeParameterIndex = -1; } else if ((ch == ',') && (squareNesting == 0) && (angleNesting == 1)) result.Append(ch); } Debug.Assert(angleNesting == 0); Debug.Assert(squareNesting == 0); // remove trailing type parameters, if any (and if specified); return // the result string resultString = result.ToString(); if (removeTrailingTypeParameters) { if (trailingTypeParameterIndex >= 0) return resultString.Substring(0, trailingTypeParameterIndex); else return resultString; } else return resultString; }
Topic.EnumerateDescendentNonTypes Method
Enumerates the topics for which a given topic is specified as the ParentTopic or the Topic.ParentTopic and so on, excluding type topics (i.e. topics for which IsTypeTopic is true). Returns an empty enumeration if there are no descendent topics.
Parameters
topic The given topic. |
public static IEnumerable<Topic> EnumerateDescendentNonTypes(Topic topic) { // yield members of this type topic, but skip type topics // since we're already enumerating through all type topics foreach (Topic childTopic in topic.ChildTopics) { if (!childTopic.IsTypeTopic) { yield return childTopic; EnumerateDescendentNonTypes(topic); } } }
Topic.HasModifier Method
Returns true if this topic has one of a given set of modifiers (such as "public"), false if not.
Parameters
modifiers The modifiers to search for. Matching is performed in a case-sensitive manner. |
public bool HasModifier(params string[] modifiers) { if (m_modifiers == null) return false; foreach (Token token in m_modifiers) { foreach (string modifier in modifiers) { if (token.IsWordOrReservedWord(modifier)) return true; } } return false; }
Topic.HasParameter Method
Returns true if this topic has a parameter with a given name, false if not.
Parameters
parameterName The name of the type parameter to search for; for example, "fileName". Matching is performed in a case-sensitive manner. |
public bool HasParameter(string parameterName) { if (Parameters == null) return false; return (m_parameters.Find(delegate(Parameter parameter) { return (parameter.ParameterName == parameterName); }) != null); }
Topic.GetParameter Method
Returns the Parameter object corresponding to a given parameter name, or null if there is no parameter with that name.
Parameters
parameterName The name of the parameter to search for. Matching is performed in a case-sensitive manner. |
public Parameter GetParameter(string parameterName) { if (m_parameters == null) return null; return m_parameters.Find(delegate(Parameter parameter) { return (parameter.ParameterName == parameterName); }); }
Topic.GetParameterHtml Method
Gets the HTML corresponding to the "<param>" section of the Xml of this topic corresponding to a given parameter name, or null if none.
Parameters
parameterName The name of the parameter to search for. Matching is performed in a case-sensitive manner. |
public string GetParameterHtml(string parameterName) { // do nothing if there is no HTML for any XML comment section if (m_xmlSectionsHtml == null) return null; // set <paramSection> to the "<param>" XmlCommentSection that has a // "name" attribute equal to <parameterName>, or null if none List<XmlCommentSection> paramSections = m_xmlSectionsHtml[(int) XmlCommentSectionKind.Param]; if (paramSections == null) return null; XmlCommentSection paramSection = paramSections.Find( delegate(XmlCommentSection section) { return (section.NameAttribute == parameterName); }); // return the HTML of <paramSection>, if any if (paramSection != null) return paramSection.Html.Trim(); else return null; }
Topic.HasTypeParameter Method
Returns true if this topic has a type parameter with a given name, false if not.
Parameters
typeParameterName The name of the type parameter to search for; for example, "T". Matching is performed in a case-sensitive manner. |
public bool HasTypeParameter(string typeParameterName) { if (TypeParameters == null) return false; return (Array.Find(TypeParameters, delegate(TokenList typeParameter) { return (typeParameter.ToString() == typeParameterName); }) != null); }
Topic.GetTypeParameterHtml Method
Gets the HTML corresponding to the "<typeparam>" section of the Xml of this topic corresponding to a given type parameter name, or null if none.
Parameters
typeParameterName The name of the type parameter to search for. Matching is performed in a case-sensitive manner. |
public string GetTypeParameterHtml(string typeParameterName) { // do nothing if there is no HTML for any XML comment section if (m_xmlSectionsHtml == null) return null; // set <typeParamSection> to the "<typeparam>" XmlCommentSection that // has a "name" attribute equal to <typeParameterName>, or null if none List<XmlCommentSection> typeParamSections = m_xmlSectionsHtml[(int) XmlCommentSectionKind.TypeParam]; if (typeParamSections == null) return null; XmlCommentSection typeParamSection = typeParamSections.Find( delegate(XmlCommentSection section) { return (section.NameAttribute == typeParameterName); }); // return the HTML of <typeParamSection>, if any if (typeParamSection != null) return typeParamSection.Html.Trim(); else return null; }
Topic.AddXmlSectionHtml Method
Stores HTML corresponding to a given XML comment section (e.g. "<summary>") of this topic, for later access by methods such as WriteSummaryHtml.
Parameters
section The XML comment section. html The string of HTML to store.
Remarks
This method should only be called by a renderer assembly. |
public void AddXmlSectionHtml(XmlCommentSection section, string html) { // store <html> in section> section.Html = html; // create <m_xmlSectionsHtml> if it hasn't been created yet if (m_xmlSectionsHtml == null) { m_xmlSectionsHtml = new List<XmlCommentSection>[(int) XmlCommentSectionKind.Length]; } // create the appropriate element of <m_xmlSectionsHtml> if it hasn't // been created yet int sectionKindInt = (int) section.SectionKind; List<XmlCommentSection> list = m_xmlSectionsHtml[sectionKindInt]; if (list == null) { list = new List<XmlCommentSection>(); m_xmlSectionsHtml[sectionKindInt] = list; } // add <section> to the list section.Enumerating = false; list.Add(section); }
Topic.WriteSummaryHtml Method (HtmlTextWriter)
Writes the HTML corresponding to the "<summary>" section of the Xml property of this topic. Does nothing if there is no "<summary>" section.
Parameters
htmlWriter Where to write the HTML. |
public void WriteSummaryHtml(HtmlTextWriter htmlWriter) { WriteXmlCommentSectionHtml(XmlCommentSectionKind.Summary, htmlWriter, null); }
Topic.WriteReturnsHtml Method
Writes the HTML corresponding to the "<returns>" section of the Xml property of this topic. Does nothing if there is no "<returns>" section.
Parameters
htmlWriter Where to write the HTML. |
public void WriteReturnsHtml(HtmlTextWriter htmlWriter) { WriteXmlCommentSectionHtml(XmlCommentSectionKind.Returns, htmlWriter, null); }
Topic.WriteValueHtml Method
Writes the HTML corresponding to the "<value>" section of the Xml property of this topic. Does nothing if there is no "<value>" section.
Parameters
htmlWriter Where to write the HTML. |
public void WriteValueHtml(HtmlTextWriter htmlWriter) { WriteXmlCommentSectionHtml(XmlCommentSectionKind.Value, htmlWriter, null); }
Topic.WriteSummaryHtml Method (HtmlTextWriter, HtmlTextWriterDelegate)
Writes the HTML corresponding to the "<summary>" section of the Xml property of this topic. Does nothing if there is no "<summary>" section. Allows the caller to append additional HTML.
Parameters
htmlWriter Where to write the HTML. htmlWriterDelegate If not null, this delegate is called after the comment section HTML is written, but before the closing paragraph tag is written. This allows the caller to append text. |
public void WriteSummaryHtml(HtmlTextWriter htmlWriter, HtmlTextWriterDelegate htmlWriterDelegate) { WriteXmlCommentSectionHtml(XmlCommentSectionKind.Summary, htmlWriter, htmlWriterDelegate); }
Topic.WriteRemarksHtml Method
Writes the HTML corresponding to the "<remarks>" section of the Xml property of this topic. Does nothing if there is no "<remarks>" section.
Parameters
htmlWriter Where to write the HTML. |
public void WriteRemarksHtml(HtmlTextWriter htmlWriter) { WriteXmlCommentSectionHtml(XmlCommentSectionKind.Remarks, htmlWriter, null); }
Topic.WriteExampleHtml Method
Writes the HTML corresponding to the "<example>" section of the Xml property of this topic. Does nothing if there is no "<example>" section.
Parameters
htmlWriter Where to write the HTML. |
public void WriteExampleHtml(HtmlTextWriter htmlWriter) { WriteXmlCommentSectionHtml(XmlCommentSectionKind.Example, htmlWriter, null); }
Topic.HasXmlCommentSectionHtml Method
Returns true if this topic has a specified XML comment section (for example, "<summary>") for which HTML has been generated.
Parameters
sectionKind Identifies the top-level section; for example, "<summary>" or "<remarks>"). |
public bool HasXmlCommentSectionHtml(XmlCommentSectionKind sectionKind) { if (m_xmlSectionsHtml == null) return false; List<XmlCommentSection> sections = m_xmlSectionsHtml[(int) sectionKind]; return (sections != null) && (sections.Count > 0); }
Topic.GetRenderedXmlCommentSections Method
Enumerates through the top-level sections of a given section kind (for example, "<summary>" or "<param>") of this topic, among sections that were previously added using AddXmlSectionHtml.
Parameters
sectionKind Identifies the top-level section; for example, "<summary>" or "<remarks>"). |
public IEnumerable<XmlCommentSection> GetRenderedXmlCommentSections( XmlCommentSectionKind sectionKind) { // do nothing if there is no array of XML comment section HTML if (m_xmlSectionsHtml == null) yield break; // set <sections> to the list of sections of this type; do nothing if // there is none List<XmlCommentSection> sections = m_xmlSectionsHtml[(int) sectionKind]; if ((sections == null) || (sections.Count == 0)) yield break; // yield each section foreach (XmlCommentSection section in sections) yield return section; }
Topic.WriteXmlCommentSectionHtml Method
Writes the HTML corresponding to an XML comment section (for example, "<summary>") of the Xml property of this topic. All HTML blocks for this section are concatenated into a series of paragraphs. Does nothing if the specified XML comment section doesn't exist.
Parameters
sectionKind Identifies the top-level section (for example, "<summary>" or "<remarks>") to write the HTML of. htmlWriter Where to write the HTML. htmlWriterDelegate If not null, this delegate is called after the comment section HTML is written, but before the closing paragraph tag is written. This allows the caller to append text. |
public void WriteXmlCommentSectionHtml(XmlCommentSectionKind sectionKind, HtmlTextWriter htmlWriter, HtmlTextWriterDelegate htmlWriterDelegate) { foreach (XmlCommentSection section in GetRenderedXmlCommentSections(sectionKind)) { htmlWriter.RenderBeginTag("p"); string innerHtml = section.Html.Trim(); htmlWriter.Write(innerHtml); if (htmlWriterDelegate != null) htmlWriterDelegate(htmlWriter); htmlWriter.RenderEndTag(); htmlWriter.WriteLine(); } } #if DEBUG /// <summary> /// Returns debugging information about this topic. /// </summary> /// /// <param name="maxDataLength">Each piece of output data is truncated to /// approximately this length.</param> /// public string Dump(int maxDataLength) { StringBuilder result = new StringBuilder(1000); result.AppendFormat("----- {0} {1} -----\r\n", TopicKind, QualifiedMemberName); if (MethodKind != MethodKind.NotAMethod) result.AppendFormat("MethodKind: {0}\r\n", MethodKind); if (PropertyKind != PropertyKind.NotAProperty) result.AppendFormat("PropertyKind: {0}\r\n", PropertyKind); if (Attributes != null) { result.Append("Attributes: "); int length = 0; foreach (TokenList attribute in Attributes) { string str = "[" + attribute.ToString() + "]"; int newLength = length + str.Length; if (newLength > maxDataLength) { result.AppendFormat("{0}...", str.Substring(0, maxDataLength - length)); break; } else result.Append(str); length = newLength; } result.Append("\r\n"); } if (Modifiers != null) { result.AppendFormat("Modifiers: {0}\r\n", TokenList.ToString(Modifiers, maxDataLength, false)); } if (MemberType != null) { result.AppendFormat("MemberType: {0}\r\n", TokenList.ToString(MemberType, maxDataLength, false)); } if (NamespaceName != null) result.AppendFormat("NamespaceName: {0}\r\n", NamespaceName); if (ParentTypeName != null) result.AppendFormat("ParentTypeName: {0}\r\n", ParentTypeName); if (ExplicitPrefix != null) { result.AppendFormat("ExplicitPrefix: {0}\r\n", TokenList.ToString(ExplicitPrefix, maxDataLength, false)); } result.AppendFormat("MemberName: {0}\r\n", MemberName); if (TypeParameters != null) { result.AppendFormat("TypeParameters: <{0}>\r\n", TokenList.Join(',', TypeParameters) .ToString(maxDataLength, false, false)); } if (BaseTypes != null) { TokenList separator = new TokenList(); separator.Append(new Token(',')); separator.Append(new Token(TokenType.WhiteSpace, " ")); result.AppendFormat("BaseTypes: {0}\r\n", TokenList.JoinWithSeparator(separator, BaseTypes) .ToString(maxDataLength, false, false)); } if (BaseClassTopic != null) result.AppendFormat("BaseClassTopic: {0}\r\n", BaseClassTopic); if (Parameters != null) { StringBuilder data = new StringBuilder(200); foreach (Parameter parameter in Parameters) { if (data.Length == 0) data.Append(parameter.ToString()); else data.AppendFormat(", {0}", parameter); if (data.Length > maxDataLength) break; } result.Append("Parameters: "); if (data.Length > maxDataLength) { result.AppendFormat("{0}...", data.ToString().Substring(0, maxDataLength - data.Length)); } else result.Append(data.ToString()); result.Append("\r\n"); } if (Constraints != null) { result.AppendFormat("Constraints: {0}\r\n", TokenList.ToString(Constraints, maxDataLength, false)); } if (GetAccessor != null) result.AppendFormat("GetAccessor: {0}\r\n", GetAccessor); if (SetAccessor != null) result.AppendFormat("SetAccessor: {0}\r\n", SetAccessor); if (EnumValueNamesArray != null) { result.AppendFormat("EnumValueNames: {0}\r\n", SourceFile.Ellipsis(String.Join( ", ", EnumValueNamesArray), maxDataLength)); } result.AppendFormat("Xml: {0}\r\n", SourceFile.Ellipsis(Xml, maxDataLength)); #if false result.Append(UsingContext.Dump()); #endif return result.ToString(); } #endif ////////////////////////////////////////////////////////////////////////// // Internal Methods //
Topic Constructor
Initializes an instance of this class.
Parameters
sourceFile The source file containing this topic; null for a TopicKind.NamespaceTopic. |
internal Topic(SourceFile sourceFile)
{
m_sourceFile = sourceFile;
}
Topic.AddChildTopic Method
Adds a given topic to ChildTopics.
Parameters
childTopic The topic to add. |
internal void AddChildTopic(Topic childTopic) { if (m_childTopics == null) m_childTopics = new List<Topic>(20); m_childTopics.Add(childTopic); }
internal new Topic MemberwiseClone() { return (Topic) base.MemberwiseClone(); }
Topic.PrevalidateXmlComment Method
Performs a quick validation pass through the contents of the Xml property to check for basic structural problems such as an unknown top-level XML section type. Does not perform full validation of the documentation XML.
Exceptions
|
internal void PrevalidateXmlComment() { foreach (XmlCommentSection section in XmlCommentSections) { using (XmlReader xmlReader = section.GetXmlReader()) { while (xmlReader.Read()) ; } } }
Topic.NewParsingException Method (string, params object[])
Constructs and returns a new ParsingException referring to the current source file and the line number of the XML comment of this topic.
Parameters
format A formatting string for an error message to include with the exception. args Formatting arguments for the error message. |
internal ParsingException NewParsingException( string format, params object[] args) { return new ParsingException(SourceFile.SourceFileAbsolutePath, FirstXmlComment.GetLineNumber(), format, args); }
Topic.NewParsingException Method (XmlReader, string, params object[])
Constructs and returns a new ParsingException referring to the source file of this topic and the line number of a given XmlReader.
Parameters
xmlReader The XmlReader to get the line number of (to include in the exception text). format A formatting string for an error message to include with the exception. args Formatting arguments for the error message. |
internal ParsingException NewParsingException( XmlReader xmlReader, string format, params object[] args) { return new ParsingException(SourceFile.SourceFileAbsolutePath, ((IXmlLineInfo) xmlReader).LineNumber, format, args); }
Topic.MakeValidFileName Method
Creates a file name from a given string. For example, "A B" is converted to "A$20B".
Parameters
name The string to convert to a file name. |
internal static string MakeValidFileName(string name) { name = name.Replace(SourceFile.LAngle, SourceFile.LSquare) .Replace(SourceFile.RAngle, SourceFile.RSquare); return s_nonFileNameCharRegex.Replace(name, delegate(Match match) { Debug.Assert(match.Value.Length == 1); char ch = match.Value[0]; if (ch < 0x100) { // replace ASCII characters with "$xx" (2-byte hex value) return String.Format("${0:X2}", (int) ch); } else { // replace non-ASCII Unicode characters with "$uXXXX" (4-byte // hex value) return String.Format("$u{0:X4}", (int) ch); } }); } ////////////////////////////////////////////////////////////////////////// // Private Methods //
Topic.CopyTypeName Method
Assuming this topic is a type topic, this method copies the type name represented by this topic, including ancestor types but not including the namespace, to a given token list. For example, if this topic is nested class "Ghi" within class "Def" within namespace "Abc", this method appends "Def.Ghi" to the given token list.
Parameters
tokenList The TokenList to append to.
Return Value
true if anything was written to tokenList, false if not. |
public bool CopyTypeName(TokenList tokenList) { // do nothing if this isn't a type topic if (TopicKind == TopicKind.NamespaceTopic) return false; // recurse to add the ancesor types to <tokenList> if (ParentTopic != null) { if (ParentTopic.CopyTypeName(tokenList)) tokenList.Append(new Token('.')); } // add the member name to <tokenList> tokenList.Append(new Token(TokenType.Word, MemberName)); // add type parameters, if any if (TypeParameters != null) { tokenList.Append(new Token(SourceFile.LAngle)); bool first = true; foreach (TokenList typeParameter in TypeParameters) { if (first) first = false; else tokenList.Append(new Token(',')); tokenList.AppendCopy(typeParameter); } tokenList.Append(new Token(SourceFile.RAngle)); } return true; }
Topic.ConstructQualifiedMemberName Method
Constructs the member name, with or without the namespace name (if any) and parent type name (if any) prepended.
Parameters
result Where to write the result. includeNamespace true to include the parent namespace name in the result. includeParentType true to include the parent type name in the result. includeExplicitPrefix true to include the Topic.ExplicitPrefix in the result. |
void ConstructQualifiedMemberName(TokenList result, bool includeNamespace, bool includeParentType, bool includeExplicitPrefix) { if ((m_namespaceName != null) && includeNamespace) { foreach (Token token in m_namespaceName) result.Append(token.Clone()); } if (includeParentType) { TokenList parentTypeName = ParentTypeName; if (parentTypeName != null) { if (!result.IsEmpty) result.Append(new Token('.')); foreach (Token token in parentTypeName) result.Append(token.Clone()); } } if (m_memberName != null) { if (!result.IsEmpty) result.Append(new Token('.')); if (includeExplicitPrefix && (ExplicitPrefix != null)) result.AppendCopy(ExplicitPrefix); result.Append(new Token(TokenType.Word, m_memberName)); } }
Topic.GetTitle Method
Returns a title for this topic, based on a given member name. Type parameters and regular parameters are included if this is an overload topic (i.e. a topic for which there are other topics with the same BaseName).
Parameters
memberName The member name to use in the title. This should be either QualifiedMemberName (for a long title) or QualifiedMemberNameWithoutNamespace (for a shorter title). includeTopicKind true to include the topic kind (e.g. "Method"), false if not. |
string GetTitle(string memberName, bool includeTopicKind) { StringBuilder result = new StringBuilder(200); result.Append(memberName); if ((TypeParameters != null) && (OverloadListTopic != null)) { result.AppendFormat("<{0}>", TokenList.Join(',', TypeParameters) .ToString(int.MaxValue, false, false)); } if (includeTopicKind) { if (TopicKind == TopicKind.MethodTopic) { if (MethodKind == MethodKind.Constructor) result.AppendFormat(" {0}", Resources.Constructor); else if (MethodKind == MethodKind.Destructor) result.AppendFormat(" {0}", Resources.Destructor); else result.AppendFormat(" {0}", TopicKindTitle); } else result.AppendFormat(" {0}", TopicKindTitle); } if ((Parameters != null) && (OverloadListTopic != null)) { result.Append(" ("); bool firstParameter = true; foreach (Parameter parameter in Parameters) { if (firstParameter) firstParameter = false; else result.Append(", "); string kind = parameter.CSharpKind; if (kind != null) result.AppendFormat("{0} ", kind); result.Append(parameter.ParameterType.ToString()); } result.Append(")"); } return result.ToString(); }
Topic.GetOverloadingSignature Method
Returns a string that can be used to compare the member documented by this topic with another member to see if one overrides the other. Returns null if the member is not overloadable (e.g. a property, method, or event, excluding constructors and destructors).
Remarks
As described in sections 3.6 and 10.6.3 of the C# Language Specification 1.2 and section 20.6.1 of the C# Language Specification 2.0, the following are included in the returned signature:
A limitation of CodeDoc is that two parameter types are considered equivalent for the purpose of overloading if they are spelled identically. So, for example, Another limitation of CodeDoc is that the names of type parameters are also included in the returned string. So, for example, if a method is overridden by a second method and the second method uses different type parameter names, it will be considered to be a new method rather than an override. To work around this limitation, use consistent naming for method type parameters. |
string GetOverloadingSignature() { // return null if this topic isn't an overloadable member if (TopicKind == TopicKind.PropertyTopic) { // all properties are overloadable } else if (TopicKind == TopicKind.MethodTopic) { // methods are overloadable except constructors and destructors if ((MethodKind == MethodKind.Constructor) || (MethodKind == MethodKind.Destructor)) return null; } else if (TopicKind == TopicKind.EventTopic) { // all events are overloadable } else return null; // not overloadable // the return value will be accumulated into <result> StringBuilder result = new StringBuilder(500); // append the member name if (MemberName != null) result.Append(MemberName); // append type parameters, if any if (TypeParameters != null) { result.AppendFormat("<{0}>", TokenList.Join(',', TypeParameters) .ToString(int.MaxValue, false, false)); } // append regular parameters, if any; don't include "params" // declarations if (Parameters != null) { result.Append(SourceFile.LParen); bool first = true; foreach (Parameter parameter in Parameters) { if (first) first = false; else result.Append(", "); if ((parameter.ParameterKind != ParameterKind.Unknown) && (parameter.ParameterKind != ParameterKind.Normal) && (parameter.ParameterKind != ParameterKind.Params)) result.AppendFormat("{0} ", parameter.CSharpKind); result.Append(parameter.ParameterType); } result.Append(SourceFile.RParen); } // done return result.ToString(); } ////////////////////////////////////////////////////////////////////////// // IComparable Implementation // int IComparable<Topic>.CompareTo(Topic other) { return String.Compare(LongSignature, other.LongSignature, true); } }
[DebuggerDisplay("{DebuggerDisplay}")] public class NamespaceTopic : Topic { ////////////////////////////////////////////////////////////////////////// // Private Fields //
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
List<Topic> m_typeTopics = new List<Topic>(20);
//////////////////////////////////////////////////////////////////////////
// Public Properties
//
NamespaceTopic.TypeTopics Property
Gets the list of type topics (i.e. TopicKind.ClassTopic, TopicKind.StructTopic, TopicKind.InterfaceTopic, TopicKind.DelegateTopic or TopicKind.EnumTopic) documented in this namespace by this documentation set. |
public IList<Topic> TypeTopics { [DebuggerStepThrough] get { return new ReadOnlyCollection<Topic>(m_typeTopics); } } ////////////////////////////////////////////////////////////////////////// // Public Methods //
public void SortTypeTopics() { if (m_typeTopics != null) m_typeTopics.Sort(); } ////////////////////////////////////////////////////////////////////////// // Internal Methods //
NamespaceTopic Constructor
Initializes an instance of this class.
Parameters
namespaceName The fully-qualified name of the namespace; for example, "Foo.Bar". This becomes the value of the Topic.MemberName property of the new NamespaceTopic. |
internal NamespaceTopic(string namespaceName) : base(null) { MemberName = namespaceName; }
NamespaceTopic.AddTypeTopic Method
Adds a topic to the TypeTopics collection, and sets the topic's Topic.IsTypeTopic property to true. This type must belong to this namespace, but it's permissible for the type to be nested within another type in this namespace.
Parameters
typeTopic The topic to add. |
internal void AddTypeTopic(Topic typeTopic) { Debug.Assert(TokenList.ToString(typeTopic.NamespaceName) == MemberName); m_typeTopics.Add(typeTopic); typeTopic.IsTypeTopic = true; } }
OverloadListTopic Class
A documentation topic that lists multiple versions, or "overloads", of topics that all have the same Topic.BaseName property value, i.e. the same Topic.QualifiedMemberName and the same TopicKind.
Remarks
An overload list topic is a topic you can link to (from references within CodeDoc-generated documentation or external documentation) when you don't know the type parameters or regular parameters of one or more components of the fully-qualified path of the target topic. For example, if you want to link to method "Bar" in class "Foo" but there are two "Bar" methods (with different parameter signatures), the "Foo.Bar method" overload list topic will list both methods and provide links to them. (If there was only one "Bar" method, then the link to "Foo.Bar method" would link directly to that topic. Overload list topics are only generated when there are multiple overloads with a single Topic.QualifiedMemberName and TopicKind.) Usually, an overload list topic contains overload topics that belong to the same parent type (if any). Example:
|
[DebuggerDisplay("{DebuggerDisplay}")] public class OverloadListTopic : Topic { ////////////////////////////////////////////////////////////////////////// // Private Fields //
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
List<Topic> m_overloadTopics = new List<Topic>();
//////////////////////////////////////////////////////////////////////////
// Public Properties
//
OverloadListTopic.OverloadTopics Property
Gets the list of overload topics, i.e. the topics that this OverloadListTopic collects together. |
public IList<Topic> OverloadTopics { [DebuggerStepThrough] get { return new ReadOnlyCollection<Topic>(m_overloadTopics); } } ////////////////////////////////////////////////////////////////////////// // Public Methods //
public void SortOverloadTopics() { if (m_overloadTopics != null) m_overloadTopics.Sort(); } ////////////////////////////////////////////////////////////////////////// // Internal Methods //
OverloadListTopic Constructor
Initializes an instance of this class. |
internal OverloadListTopic() : base(null) { }
OverloadListTopic.AddOverloadTopic Method
Adds a topic to the OverloadTopics collection.
Parameters
overloadTopic The topic to add. |
internal void AddOverloadTopic(Topic overloadTopic) { Debug.Assert(overloadTopic.TopicKind == TopicKind); Debug.Assert(overloadTopic.NamespaceName == NamespaceName); Debug.Assert(overloadTopic.ParentTypeName == ParentTypeName); Debug.Assert(overloadTopic.MemberName == MemberName); m_overloadTopics.Add(overloadTopic); } }
TopicKind Enumeration
Which kind of topic a Topic is.
Members
|
public enum TopicKind {
TopicKind.UnknownTopic Enumeration Value
The topic kind is not yet known. |
UnknownTopic,
TopicKind.NamespaceTopic Enumeration Value
Topic is a namespace declaration. |
NamespaceTopic,
TopicKind.ClassTopic Enumeration Value
Topic is a class declaration. |
ClassTopic,
TopicKind.StructTopic Enumeration Value
Topic is a struct declaration. |
StructTopic,
TopicKind.InterfaceTopic Enumeration Value
Topic is a interface declaration. |
InterfaceTopic,
TopicKind.EventTopic Enumeration Value
Topic is a event declaration. |
EventTopic,
TopicKind.DelegateTopic Enumeration Value
Topic is a delegate declaration. |
DelegateTopic,
TopicKind.EnumTopic Enumeration Value
Topic is a enum declaration. |
EnumTopic,
TopicKind.EnumValueTopic Enumeration Value
Topic is a enum value declaration, i.e. a value within an enum declaration. |
EnumValueTopic,
TopicKind.MethodTopic Enumeration Value
Topic is a method declaration. |
MethodTopic,
TopicKind.PropertyTopic Enumeration Value
Topic is a property declaration. |
PropertyTopic,
TopicKind.FieldTopic Enumeration Value
Topic is a field declaration. |
FieldTopic, }
MethodKind Enumeration
Which kind of method (if any) a Topic is.
Members
|
public enum MethodKind {
MethodKind.NotAMethod Enumeration Value
Not a method. operator). |
NotAMethod = 0,
MethodKind.Normal Enumeration Value
Method is a normal method (not a constructor, destructor, or operator). |
Normal,
MethodKind.Constructor Enumeration Value
Method is a constructor. |
Constructor,
MethodKind.Destructor Enumeration Value
Method is a destructor. |
Destructor,
MethodKind.Operator Enumeration Value
Method is an operator. |
Operator, }
PropertyKind Enumeration
Which kind of property (if any) a Topic is.
Members
|
public enum PropertyKind {
PropertyKind.NotAProperty Enumeration Value
Not a property. |
NotAProperty = 0,
PropertyKind.Normal Enumeration Value
Property is a normal property (not an indexer). |
Normal,
PropertyKind.Indexer Enumeration Value
Property is an indexer. |
Indexer, }
Parameter Class
A parameter within a method or indexer declaration. |
[DebuggerDisplay("{DebuggerDisplay}")] public class Parameter { ////////////////////////////////////////////////////////////////////////// // Private Fields //
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
ParameterKind m_parameterKind;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
TokenList m_parameterType;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
string m_parameterName;
//////////////////////////////////////////////////////////////////////////
// Private Properties
//
#if DEBUG
/// <summary>
/// Gets a string displayed in the debugger.
/// </summary>
public string DebuggerDisplay
{
get
{
return ToString();
}
}
#endif
//////////////////////////////////////////////////////////////////////////
// Public Properties
//
Parameter.ParameterKind Property
Gets which kind of parameter this is: |
public ParameterKind ParameterKind { [DebuggerStepThrough] get { return m_parameterKind; } [DebuggerStepThrough] internal set { m_parameterKind = value; } }
Parameter.ParameterType Property
Gets the type of this parameter. |
public TokenList ParameterType { [DebuggerStepThrough] get { return m_parameterType; } [DebuggerStepThrough] internal set { m_parameterType = value; } }
Parameter.ParameterName Property
Gets the name of this parameter. |
public string ParameterName { [DebuggerStepThrough] get { return m_parameterName; } [DebuggerStepThrough] internal set { m_parameterName = value; } }
Parameter.CSharpKind Property
Gets the C# keyword equivalent of the ParameterKind value: "out", "ref", etc. Returns null for ParameterKind.Normal and ParameterKind.Unknown. |
public string CSharpKind { get { switch (m_parameterKind) { case ParameterKind.Out: return "out"; case ParameterKind.Ref: return "ref"; case ParameterKind.Params: return "params"; default: return null; } } } ////////////////////////////////////////////////////////////////////////// // Public Methods //
Parameter.ToString Method
Returns a string representation of the parameter. |
public override string ToString() { StringBuilder result = new StringBuilder(200); string kind = CSharpKind; if (kind != null) result.AppendFormat("{0} ", kind); result.Append(ParameterType.ToString()); result.Append(' '); result.Append(ParameterName); return result.ToString(); } ////////////////////////////////////////////////////////////////////////// // Internal Methods //
Parameter Constructor
Initializes an instance of this class. |
internal Parameter()
{
}
}
ParameterKind Enumeration
Which kind of parameter a Parameter is.
Members
|
public enum ParameterKind {
ParameterKind.Unknown Enumeration Value
The parameter kind is not yet known. |
Unknown = 0,
ParameterKind.Normal Enumeration Value
Parameter is input-only (i.e. passed by value). |
Normal,
ParameterKind.Out Enumeration Value
Parameter is output-only. |
Out,
ParameterKind.Ref Enumeration Value
Parameter is input/output (i.e. passed by reference). |
Ref,
ParameterKind.Params Enumeration Value
Parameter is a "params" parameter (i.e. variable-length argument list). |
Params, }
Accessor Class
A accessor within a method or indexer declaration. |
[DebuggerDisplay("{DebuggerDisplay}")] public class Accessor { ////////////////////////////////////////////////////////////////////////// // Private Fields //
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
AccessorKind m_accessorKind;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
TokenList m_accessorModifiers;
//////////////////////////////////////////////////////////////////////////
// Private Properties
//
#if DEBUG
/// <summary>
/// Gets a string displayed in the debugger.
/// </summary>
public string DebuggerDisplay
{
get
{
return ToString();
}
}
#endif
//////////////////////////////////////////////////////////////////////////
// Public Properties
//
Accessor.AccessorKind Property
Which kind of accessor this is. |
public AccessorKind AccessorKind { [DebuggerStepThrough] get { return m_accessorKind; } [DebuggerStepThrough] internal set { m_accessorKind = value; } }
Accessor.AccessorModifiers Property
The modifiers of this accessor (e.g. "internal"). |
public TokenList AccessorModifiers { [DebuggerStepThrough] get { return m_accessorModifiers; } [DebuggerStepThrough] internal set { m_accessorModifiers = value; } }
Accessor.HasModifier Method
Returns true if this accessor has one of a given set of modifiers (such as "public"), false if not.
Parameters
modifiers The modifiers to search for. Matching is performed in a case-sensitive manner. |
public bool HasModifier(params string[] modifiers) { if (m_accessorModifiers == null) return false; foreach (Token token in m_accessorModifiers) { foreach (string modifier in modifiers) { if (token.IsWordOrReservedWord(modifier)) return true; } } return false; }
Accessor.IsExternallyAccessible Property
Returns true if this accessor is accessible outside of this program or library -- assuming that the member associated with this accessor is similarly accessible. |
public bool IsExternallyAccessible { get { // if no modifiers are specified, default to public access if (AccessorModifiers == null) return true; // otherwise, the accessor is only externally accessible if its // modifiers include "protected" -- see section 25.1.1 of the C# // Language Specification 2.0 return HasModifier("protected"); } } ////////////////////////////////////////////////////////////////////////// // Public Methods //
Accessor.ToString Method
Returns a string representation of the accessor. |
public override string ToString() { StringBuilder result = new StringBuilder(200); if (AccessorModifiers != null) result.Append(AccessorModifiers.ToString()); if (result.Length != 0) result.Append(' '); if (AccessorKind == AccessorKind.Get) result.Append("get"); else if (AccessorKind == AccessorKind.Set) result.Append("set"); else Debug.Assert(false); return result.ToString(); } ////////////////////////////////////////////////////////////////////////// // Internal Methods //
Accessor Constructor
Initializes an instance of this class. |
internal Accessor()
{
}
}
AccessorKind Enumeration
Which kind of accessor a Accessor is.
Members
|
public enum AccessorKind {
AccessorKind.Unknown Enumeration Value
The accessor kind is not yet known. |
Unknown = 0,
AccessorKind.Get Enumeration Value
Accessor is a "get" accessor. |
Get,
AccessorKind.Set Enumeration Value
Accessor is a "set" accessor. |
Set, }
XmlCommentSection Class
Represents to a top-level section (for example, "<summary>" or "<param>") of an XML comment block. |
[DebuggerDisplay("XmlCommentSection: {SectionKind}")] public class XmlCommentSection { ////////////////////////////////////////////////////////////////////////// // Private Fields //
XmlCommentSection.s_sectionKindDictionary Field
Maps an XML comment section name (e.g. "summary") to a XmlCommentSectionKind enumeration value. |
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
static Dictionary<string, XmlCommentSectionKind> s_sectionKindDictionary =
InitializeSectionKindDictionary();
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
Topic m_topic;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
XmlCommentSectionKind m_sectionKind;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
string m_sectionName;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
string m_nameAttribute;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
string m_crefAttribute;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
string m_hrefAttribute;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
string m_html;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
bool m_enumerating;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
int m_lineNumber;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
Topic m_referencedTopic;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
XmlReader m_xmlReader;
//////////////////////////////////////////////////////////////////////////
// Public Properties
//
XmlCommentSection.Topic Property
Gets the Topic that contains the XML that contains this XmlCommentSection. |
public Topic Topic { [DebuggerStepThrough] get { return m_topic; } }
XmlCommentSection.SectionKind Property
Gets which kind of XML comment section this is. |
public XmlCommentSectionKind SectionKind { [DebuggerStepThrough] get { return m_sectionKind; } }
XmlCommentSection.SectionName Property
Gets the name of this section; for example, "summary". This name corresponds to SectionKind. |
public string SectionName { [DebuggerStepThrough] get { return m_sectionName; } }
XmlCommentSection.NameAttribute Property
Sets or gets the value of the "name" XML attribute of this section -- null if there is no "name" attribute. |
public string NameAttribute { [DebuggerStepThrough] get { return m_nameAttribute; } [DebuggerStepThrough] set { m_nameAttribute = value; } }
XmlCommentSection.CrefAttribute Property
Sets or gets the value of the "cref" XML attribute of this section -- null if there is no "cref" attribute. |
public string CrefAttribute { [DebuggerStepThrough] get { return m_crefAttribute; } [DebuggerStepThrough] set { m_crefAttribute = value; } }
XmlCommentSection.HrefAttribute Property
Sets or gets the value of the "href" XML attribute of this section -- null if there is no "href" attribute. |
public string HrefAttribute { [DebuggerStepThrough] get { return m_hrefAttribute; } [DebuggerStepThrough] set { m_hrefAttribute = value; } }
XmlCommentSection.Html Property
The HTML representation of this section. |
public string Html { [DebuggerStepThrough] get { return m_html; } [DebuggerStepThrough] internal set { m_html = value; } }
XmlCommentSection.Enumerating Property
true if this XmlCommentSection is participating in an enumeration through all top-level sections (e.g. "<summary>" or "<param>") of an XML comment block. |
public bool Enumerating { [DebuggerStepThrough] get { return m_enumerating; } [DebuggerStepThrough] internal set { m_enumerating = value; } }
XmlCommentSection.LineNumber Property
Sets or gets the line number of this XmlCommentSection within the source file that contains it. |
public int LineNumber { [DebuggerStepThrough] get { return m_lineNumber; } [DebuggerStepThrough] set { m_lineNumber = value; } }
XmlCommentSection.ReferencedTopic Property
Sets or gets the topic referenced by this XmlCommentSection (for example, via the "cref" attribute); null if none. |
public Topic ReferencedTopic { [DebuggerStepThrough] get { return m_referencedTopic; } [DebuggerStepThrough] set { m_referencedTopic = value; } } ////////////////////////////////////////////////////////////////////////// // Public Methods //
XmlCommentSection.GetXmlReader Method
Returns an XmlReader instance that can be used to read this XML comment section.
Return Value
A new XmlReader instance set to ReadState.Initial. A call to the Read method positions the new XmlReader on the opening element of this XML section node; for example, "<summary>" node. Read will return false on the first call after the call that reads the end element (e.g. "</summary>"). If the XML section is an empty element (e.g. "<summary/>" -- XmlReader.IsEmptyElement returns true), then the first call to Read will return the element and the next call will return false.
Exceptions
Remarks
Close must be called on the returned XmlReader before reading any further XmlCommentSection objects of this topic. If Enumerating is false, GetXmlReader cannot be called. |
public XmlReader GetXmlReader() { if (m_xmlReader == null) throw new InvalidOperationException(Resources.NotEnumerating); return m_xmlReader.ReadSubtree(); } #if false /// <summary> /// Disconnects this <r>XmlCommentSection</r> object from the object that /// created it, so that this <r>XmlCommentSection</r> object can safely /// be added to a list. /// </summary> /// /// <remarks> /// Once <r>Disconnect</r> is called, <r>GetXmlReader</r> can no longer be /// called. /// </remarks> /// public void Disconnect() { m_xmlReader = null; } #endif ////////////////////////////////////////////////////////////////////////// // Internal Methods //
XmlCommentSection Constructor
Initializes an instance of this class.
Parameters
topic The Topic containing the XML being parsed by this XmlCommentSection instance. xmlReader An XmlReader positioned on a top-level XML element within an XML comment block.
Exceptions
|
internal XmlCommentSection(Topic topic, XmlReader xmlReader) { // note: <topic> may not be fully initialized -- use with caution m_topic = topic; m_xmlReader = xmlReader; Debug.Assert(xmlReader.NodeType == XmlNodeType.Element); m_sectionName = xmlReader.Name; if (!s_sectionKindDictionary.TryGetValue(m_sectionName, out m_sectionKind)) { throw topic.NewParsingException(xmlReader, Resources.UnknownXmlCommentSection, m_sectionName); } }
XmlCommentSection.ReadToEnd Method
Advances XmlReader to the end element of this XML comment section (e.g. "</summary>"). |
internal void ReadToEnd() { while (true) { if (((m_xmlReader.NodeType == XmlNodeType.EndElement) || m_xmlReader.IsEmptyElement) && (m_xmlReader.Name == m_sectionName) && (m_xmlReader.Depth == 0)) break; if (!m_xmlReader.Read()) break; } } ////////////////////////////////////////////////////////////////////////// // Private Methods //
XmlCommentSection.InitializeSectionKindDictionary Method
Returns the initial value of s_sectionKindDictionary. |
static Dictionary<string, XmlCommentSectionKind> InitializeSectionKindDictionary() { // could have used Enum.Parse(), but that's a bit hacky and slow Dictionary<string, XmlCommentSectionKind> dictionary = new Dictionary<string, XmlCommentSectionKind>(); dictionary.Add("summary", XmlCommentSectionKind.Summary); dictionary.Add("param", XmlCommentSectionKind.Param); dictionary.Add("typeparam", XmlCommentSectionKind.TypeParam); dictionary.Add("returns", XmlCommentSectionKind.Returns); dictionary.Add("value", XmlCommentSectionKind.Value); dictionary.Add("remarks", XmlCommentSectionKind.Remarks); dictionary.Add("example", XmlCommentSectionKind.Example); dictionary.Add("exception", XmlCommentSectionKind.Exception); dictionary.Add("permission", XmlCommentSectionKind.Permission); dictionary.Add("seealso", XmlCommentSectionKind.SeeAlso); return dictionary; } }
MemberInfo Class
Information about a topic that is listed in the "Members" section of another topic. |
[DebuggerDisplay("MemberInfo: {Topic}")] public class MemberInfo : IComparable<MemberInfo> { ////////////////////////////////////////////////////////////////////////// // Private Fields //
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
Topic m_topic;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
Topic m_inheritedFromTopic;
//////////////////////////////////////////////////////////////////////////
// Public Properties
//
public Topic Topic { [DebuggerStepThrough] get { return m_topic; } }
MemberInfo.InheritedFromTopic Property
Gets the Topic of the class that this member is inherited from or null if this member wasn't inherited (i.e. it is a direct member of the topic being enumerated). |
public Topic InheritedFromTopic { [DebuggerStepThrough] get { return m_inheritedFromTopic; } } ////////////////////////////////////////////////////////////////////////// // Internal Methods //
MemberInfo Constructor
Initializes an instance of this class.
Parameters
topic The value to use for the Topic property. inheritedFromTopic The value to use for the InheritedFromTopic property. |
internal MemberInfo(Topic topic, Topic inheritedFromTopic) { m_topic = topic; m_inheritedFromTopic = inheritedFromTopic; } ////////////////////////////////////////////////////////////////////////// // IComparable<T> Implementation // int IComparable<MemberInfo>.CompareTo(MemberInfo other) { return String.Compare(Topic.VeryShortTitleNoKind, other.Topic.VeryShortTitleNoKind, true); } }
XmlCommentSectionKind Enumeration
Identifies a top-level section (for example, "<summary>" and "<param>") of an XML comment block.
Members
|
public enum XmlCommentSectionKind {
XmlCommentSectionKind.Summary Enumeration Value
A <summary> section in an XML comment block. |
Summary = 0,
XmlCommentSectionKind.Param Enumeration Value
A <param> section in an XML comment block. |
Param = 1,
XmlCommentSectionKind.TypeParam Enumeration Value
A <typeparam> section in an XML comment block. |
TypeParam = 2,
XmlCommentSectionKind.Returns Enumeration Value
A <returns> section in an XML comment block. |
Returns = 3,
XmlCommentSectionKind.Value Enumeration Value
A <value> section in an XML comment block. |
Value = 4,
XmlCommentSectionKind.Remarks Enumeration Value
A <remarks> section in an XML comment block. |
Remarks = 5,
XmlCommentSectionKind.Example Enumeration Value
An <example> section in an XML comment block. |
Example = 6,
XmlCommentSectionKind.Exception Enumeration Value
An <exception> section in an XML comment block. |
Exception = 7,
XmlCommentSectionKind.Permission Enumeration Value
A <permission> section in an XML comment block. |
Permission = 8,
XmlCommentSectionKind.SeeAlso Enumeration Value
A <permission> section in an XML comment block. |
SeeAlso = 9,
/* if you update this list, update InitializeSectionKindDictionary() */
XmlCommentSectionKind.Length Enumeration Value
Value equal to the number of enumeration members in XmlCommentSectionKind. |
Length = 10/*must be equal to highest-numbered value plus one*/,
}
HtmlTextWriterDelegate Delegate
A delegate which writes to a given HtmlTextWriter.
Parameters
writer The HtmlTextWriter to write to. |
public delegate void HtmlTextWriterDelegate(HtmlTextWriter writer); }