/// <summary> /// Empty constructor /// </summary> /// <param name="name">Documented element name</param> /// <param name="docResolver">Documentation resolver</param> /// <param name="typeResolver">Type resolver</param> internal DocElement(string name, DocResolver docResolver, IResolver typeResolver) { Name = name; Documentation = new DocumentationContent(new Dictionary <TagType, IReadOnlyCollection <ITag> >()); Members = new Lazy <IReadOnlyDictionary <string, IDocMember> >(() => RetrieveMembers(docResolver, typeResolver), LazyThreadSafetyMode.PublicationOnly); }
/// <summary> /// Default constructor /// </summary> /// <param name="name">Documented element name</param> /// <param name="source">Documentation source</param> /// <param name="docResolver">Documentation resolver</param> /// <param name="typeResolver">Type resolver</param> public DocElement(string name, XElement source, DocResolver docResolver, IResolver typeResolver) { if (source is null) { throw new ArgumentNullException(nameof(source)); } Name = name; Documentation = new DocumentationContent(source); Members = new Lazy <IReadOnlyDictionary <string, IDocMember> >(() => RetrieveMembers(docResolver, typeResolver), LazyThreadSafetyMode.PublicationOnly); }
// ReSharper disable once CognitiveComplexity private IReadOnlyDictionary <string, IDocMember> RetrieveMembers(DocResolver docResolver, IResolver typeResolver) { // If there is no documentation for this element.. if (!docResolver.TryFindMembers(Name, out var memberDocs) || memberDocs is null) { // return empty members return(new Dictionary <string, IDocMember>()); } // Prepare the main cache var result = new Dictionary <string, IReadOnlyDictionary <TagType, IReadOnlyCollection <ITag> > >(memberDocs.Count); // For every member grouped by whether it has an inheritdoc or not.. foreach (var items in memberDocs.GroupBy(x => x.Value.Documentation.HasInheritDoc)) { // if the items have inheritdoc and the type is known and the type is not an enum.. if (items.Key && typeResolver.TryFindType(Name, out var type) && type is IInterface interfaceDef) { // prepare a temporary cache for the inheritdoc items var temps = items.ToDictionary(pair => pair.Value.DisplayName, pair => (pair.Key, new Dictionary <TagType, LinkedList <ITag> >())); // resolve the items inheritdoc ProcessInheritDoc(temps, interfaceDef, temps.Select(pair => pair.Key).ToArray(), memberDocs, docResolver); // for every temporarily cached documentation.. foreach (var(_, (key, tags)) in temps) { // move it to the main cache result.Add(key, tags.ToDictionary(pair => pair.Key, pair => pair.Value.ToReadOnlyCollection())); } } // otherwise.. else { // for every item.. foreach (var(key, value) in items) { // cache the item result.Add(key, value.Documentation.Tags); } } } IEnumerable <IDocMember> ProcessCache(IReadOnlyDictionary <string, IReadOnlyDictionary <TagType, IReadOnlyCollection <ITag> > > cache) { // For every cached member.. foreach (var(key, value) in cache) { // select the member var member = memberDocs[key]; // return the prepared member yield return(new DocMember(member.RawName, member.DisplayName, member.Type, new DocumentationContent(value))); } } // Materialize the processed cache to a dictionary return(ProcessCache(result).ToDictionary(x => x.RawName)); }