/// <summary>
        /// Generates the document map based on the <see cref="CurrentFiles"/>.
        /// </summary>
        public virtual DocumentMap GenerateMap()
        {
            EntryCreator.Reset();
            DocumentMap map         = this.UseObservableCollection ? new ObservableDocumentMap() : new DocumentMap();
            int         fileCounter = 1;

            // For each of the documentedfiles generate the document map and add
            // it to the parent node of the document map
            for (int i = 0; i < this.CurrentFiles.Count; i++)
            {
                if (!this.CurrentFiles[i].IsCompiled)
                {
                    continue;
                }
                Entry assemblyEntry = this.GenerateDocumentForAssembly(map, this.CurrentFiles[i], ref fileCounter);
                if (assemblyEntry.Children.Count > 0)
                {
                    map.Add(assemblyEntry);
                }
            }

            map.Sort();
            map.NumberOfEntries = this.EntryCreator.Created;

            return(map);
        }
        private void BuildMethodEntries(string collectionName, List <MethodDef> entries, Entry typeEntry, ICommentSource commentsXml)
        {
            if (entries.Count == 0)
            {
                return;
            }

            ReflectedMember containingType = (ReflectedMember)typeEntry.Item;

            Entry eventsEntry = EntryCreator.Create(entries, collectionName, commentsXml, typeEntry);

            eventsEntry.IsSearchable = false;
            eventsEntry.Key          = containingType.GetGloballyUniqueId();
            eventsEntry.SubKey       = collectionName;

            foreach (MethodDef current in entries)
            {
                PreEntryAddedEventArgs e = new PreEntryAddedEventArgs(current);
                this.OnPreEntryAdded(e);
                if (!e.Filter)
                {
                    Entry propertyEntry = EntryCreator.Create(current, current.GetDisplayName(false, false), commentsXml, eventsEntry);
                    propertyEntry.IsSearchable = true;
                    propertyEntry.Key          = current.GetGloballyUniqueId();
                    eventsEntry.Children.Add(propertyEntry);
                }
            }

            if (eventsEntry.Children.Count > 0)
            {
                eventsEntry.Children.Sort();
                typeEntry.Children.Add(eventsEntry);
            }
        }
        /// <summary>
        /// Factory method for creating new DocumentMappers.
        /// </summary>
        /// <include file='code-documentation\members.xml' path='members/member[@name="DocumentMapper"]/entry[@name="Create"]'/>
        public static IDocumentMapper Create(List <DocumentedAssembly> assemblies,
                                             Mappers typeOfMapper,
                                             bool useObservableCollection,
                                             EntryCreator creator)
        {
            DocumentMapper mapper = null;

            switch (typeOfMapper)
            {
            case Mappers.AssemblyFirst:
                mapper = new AssemblyFirstDocumentMapper(assemblies, useObservableCollection, creator);
                break;

            case Mappers.NamespaceFirst:
                mapper = new NamespaceFirstDocumentMapper(assemblies, useObservableCollection, creator);
                break;

            case Mappers.GroupedNamespaceFirst:
            default:
                mapper = new GroupedNamespaceDocumentMapper(assemblies, useObservableCollection, creator);
                break;
            }

            if (mapper == null)
            {
                throw new InvalidOperationException($"There is no implementation of {typeOfMapper} document mapper. Document could not be mapped.");
            }

            return(mapper);
        }
 /// <summary>
 /// Initialises a new instance of the NamespaceFirstDocumentMapper.
 /// </summary>
 /// <param name="assemblies">The assemblies being documented.</param>
 /// <param name="useObservableCollection">Indicates if an observable collection should be used instead of a normal one.</param>
 /// <param name="creator">The factory class for creating new <see cref="Entry"/> instances.</param>
 public GroupedNamespaceDocumentMapper
 (
     List <DocumentedAssembly> assemblies,
     bool useObservableCollection,
     EntryCreator creator
 )
     : base(assemblies, useObservableCollection, creator)
 {
     _fileSystem = new FileSystem();
 }
        /// <summary>
        /// Generates a document map grouping related namespaces.
        /// </summary>
        public override DocumentMap GenerateMap()
        {
            EntryCreator.Reset();
            DocumentMap map         = UseObservableCollection ? new ObservableDocumentMap() : new DocumentMap();
            int         fileCounter = 1;

            // For each of the documentedfiles generate the document map and add
            // it to the parent node of the document map
            for (int i = 0; i < CurrentFiles.Count; i++)
            {
                if (!CurrentFiles[i].IsCompiled)
                {
                    continue;
                }

                GenerateDocumentForAssembly(map, CurrentFiles[i], ref fileCounter);
            }

            map.Sort();

            bool          dontGroupNamespaces = true;
            List <string> counter             = new List <string>();
            List <Entry>  namespaceContainers = new List <Entry>();

            if (map.Count > 10)
            {
                // calculate the best level to create groups from or if there is no best place
                dontGroupNamespaces = false;
                float parentPercentage = 0, currentPercentage = 0;
                int   currentLevel = 0;

                do
                {
                    counter.Clear();

                    for (int dmI = 0; dmI < map.Count; dmI++)
                    {
                        string[] parts            = map[dmI].Name.Split('.');
                        string   currentNamespace = parts.Length > currentLevel?string.Join(".", parts, 0, currentLevel + 1) : string.Join(".", parts);

                        if (!counter.Contains(currentNamespace))
                        {
                            counter.Add(currentNamespace);
                        }
                    }

                    currentPercentage = counter.Count / ((float)map.Count);
                    if (parentPercentage < 0.1 && currentPercentage > 0.65 && currentLevel > 0)
                    {
                        dontGroupNamespaces = true;
                        break;
                    }

                    currentLevel++;
                    parentPercentage = counter.Count / ((float)map.Count);
                }while (counter.Count / ((float)map.Count) < 0.1306);
            }

            if (!dontGroupNamespaces)
            {
                // create all the top level groupings
                int id = 0;
                for (int cI = 0; cI < counter.Count; cI++)
                {
                    Entry namespaceContainer = EntryCreator.Create(EntryTypes.NamespaceContainer, counter[cI], null);
                    namespaceContainer.Key = id++;
                    if (string.IsNullOrEmpty(counter[cI]))
                    {
                        // this is the no name namespace
                        namespaceContainer.SubKey = "No Namespace";
                    }
                    else
                    {
                        namespaceContainer.SubKey = counter[cI] + "Namespaces";
                    }
                    namespaceContainers.Add(namespaceContainer);
                }

                // add all the namespaces to the groupings
                for (int namespaceI = 0; namespaceI < map.Count; namespaceI++)
                {
                    for (int containersI = namespaceContainers.Count; containersI > 0; containersI--)
                    {
                        if (map[namespaceI].Name.Contains(namespaceContainers[containersI - 1].Name))
                        {
                            map[namespaceI].Parent = namespaceContainers[containersI - 1];
                            namespaceContainers[containersI - 1].Children.Add(map[namespaceI]);
                            break;
                        }
                    }
                }
            }

            if (namespaceContainers.Count > 1)
            {
                map.Clear();

                for (int i = 0; i < namespaceContainers.Count; i++)
                {
                    namespaceContainers[i].Name += " Namespaces";
                    map.Add(namespaceContainers[i]);
                }
            }

            map.NumberOfEntries = EntryCreator.Created;

            return(map);
        }
        protected override Entry GenerateDocumentForAssembly(DocumentMap map, DocumentedAssembly current, ref int fileCounter)
        {
            AssemblyDef    assembly    = GetAssemblyDef(current);
            ICommentSource xmlComments = GetXmlCommentFile(current);

            Entry assemblyEntry = EntryCreator.Create(assembly, System.IO.Path.GetFileName(current.FileName), xmlComments);

            current.UniqueId           = assembly.UniqueId = fileCounter++;
            assemblyEntry.Key          = assembly.GetGloballyUniqueId();
            assemblyEntry.IsSearchable = false;
            Entry namespaceEntry = null;

            // Add the namespaces to the document map
            Dictionary <string, List <TypeDef> > typesInNamespaces = assembly.GetTypesInNamespaces();

            foreach (KeyValuePair <string, List <TypeDef> > currentNamespace in typesInNamespaces)
            {
                if (currentNamespace.Value.Count == 0)
                {
                    continue;
                }
                string namespaceSubKey = BuildSubkey(currentNamespace);

                namespaceEntry = Find(map, namespaceSubKey);
                if (namespaceEntry == null)
                {
                    string displayName = currentNamespace.Key;

                    if (string.IsNullOrEmpty(currentNamespace.Key))
                    {
                        displayName = "None";
                    }

                    namespaceEntry              = EntryCreator.Create(currentNamespace, displayName, xmlComments);
                    namespaceEntry.Key          = assemblyEntry.Key;
                    namespaceEntry.SubKey       = namespaceSubKey;
                    namespaceEntry.IsSearchable = false;
                }

                // Add the types from that namespace to its map
                foreach (TypeDef currentType in currentNamespace.Value)
                {
                    if (currentType.IsCompilerGenerated || currentType.Name[0] == '<')
                    {
                        continue;
                    }

                    PreEntryAddedEventArgs e = new PreEntryAddedEventArgs(currentType);
                    this.OnPreEntryAdded(e);
                    if (!e.Filter)
                    {
                        Entry typeEntry = EntryCreator.Create(currentType, currentType.GetDisplayName(false), xmlComments, namespaceEntry);
                        typeEntry.Key          = currentType.GetGloballyUniqueId();
                        typeEntry.IsSearchable = true;

                        // For some elements we will not want to load the child objects
                        // this is currently for System.Enum derived values.
                        if
                        (
                            currentType.InheritsFrom != null && currentType.InheritsFrom.GetFullyQualifiedName() == "System.Enum" ||
                            currentType.IsDelegate)
                        {
                            // Ignore children
                        }
                        else
                        {
                            this.GenerateTypeMap(currentType, typeEntry, xmlComments);
                            typeEntry.Children.Sort();
                        }

                        namespaceEntry.Children.Add(typeEntry);
                    }
                }
                if (namespaceEntry.Children.Count > 0)
                {
                    namespaceEntry.Children.Sort();
                    // we still need to add here otherwise we get duplicate namespaces.
                    assemblyEntry.Children.Add(namespaceEntry);
                    if (!map.Contains(namespaceEntry))
                    {
                        map.Add(namespaceEntry);
                    }
                    else
                    {
                        // update the type list is the contianing namespace
                        KeyValuePair <string, List <TypeDef> > original = (KeyValuePair <string, List <TypeDef> >)namespaceEntry.Item;
                        original.Value.AddRange(currentNamespace.Value);
                    }
                }
            }

            // we are not interested in assemblies being used here so make them childless
            return(this.EntryCreator.Create(null, string.Empty, null));
        }
Beispiel #7
0
 /// <file name='code-documentation\entry.xml' path='docs/namespacefirstdocumentmapper/member[@name="ctor1"]/*' />
 public NamespaceFirstDocumentMapper(List <DocumentedAssembly> assemblies, bool useObservableCollection, EntryCreator creator)
     : base(assemblies, useObservableCollection, creator)
 {
 }
 /// <summary>
 /// Initialises a new instance of the DocumentMapper.
 /// </summary>
 /// <param name="assemblies">The assembles to document.</param>
 /// <param name="useObservableCollection">Whether or not utilise an observable collection for the DocumentMap.</param>
 /// <param name="creator">The EntryCreator to use.</param>
 protected DocumentMapper(List <DocumentedAssembly> assemblies, bool useObservableCollection, EntryCreator creator)
 {
     _currentFiles            = assemblies;
     _useObservableCollection = useObservableCollection;
     _entryCreator            = creator;
 }
        protected virtual Entry GenerateDocumentForAssembly(DocumentMap map, DocumentedAssembly current, ref int fileCounter)
        {
            AssemblyDef assembly = AssemblyDef.Create(current.FileName);

            current.LoadedAssembly = assembly;

            XmlCommentFile commentFile = new XmlCommentFile(current.XmlFileName, new FileSystem());

            commentFile.Load();
            ICommentSource xmlComments = commentFile;

            Entry assemblyEntry = this.EntryCreator.Create(assembly, System.IO.Path.GetFileName(current.FileName), xmlComments);

            current.UniqueId           = assembly.UniqueId = fileCounter++;
            assemblyEntry.Key          = assembly.GetGloballyUniqueId();
            assemblyEntry.IsSearchable = false;
            Entry namespaceEntry = null;

            // Add the namespaces to the document map
            Dictionary <string, List <TypeDef> > typesInNamespaces = assembly.GetTypesInNamespaces();

            foreach (KeyValuePair <string, List <TypeDef> > currentNamespace in typesInNamespaces)
            {
                if (string.IsNullOrEmpty(currentNamespace.Key) || currentNamespace.Value.Count == 0)
                {
                    continue;
                }
                string namespaceSubKey = BuildSubkey(currentNamespace);

                namespaceEntry = FindByKey(map, assemblyEntry.Key, namespaceSubKey, false);
                if (namespaceEntry == null)
                {
                    namespaceEntry              = EntryCreator.Create(currentNamespace, currentNamespace.Key, xmlComments);
                    namespaceEntry.Key          = assemblyEntry.Key;
                    namespaceEntry.SubKey       = namespaceSubKey;
                    namespaceEntry.IsSearchable = false;
                    map[0].Children.Add(namespaceEntry);
                }

                // Add the types from that namespace to its map
                foreach (TypeDef currentType in currentNamespace.Value)
                {
                    if (currentType.Name.StartsWith("<"))
                    {
                        continue;
                    }
                    PreEntryAddedEventArgs e = new PreEntryAddedEventArgs(currentType);
                    this.OnPreEntryAdded(e);

                    if (!e.Filter)
                    {
                        Entry typeEntry = EntryCreator.Create(currentType, currentType.GetDisplayName(false), xmlComments, namespaceEntry);
                        typeEntry.Key          = currentType.GetGloballyUniqueId();
                        typeEntry.IsSearchable = true;

                        // For some elements we will not want to load the child objects
                        // this is currently for System.Enum derived values.
                        if (
                            currentType.InheritsFrom != null && currentType.InheritsFrom.GetFullyQualifiedName() == "System.Enum" ||
                            currentType.IsDelegate)
                        {
                            // Ignore children
                        }
                        else
                        {
                            this.GenerateTypeMap(currentType, typeEntry, xmlComments);
                            typeEntry.Children.Sort();
                        }

                        namespaceEntry.Children.Add(typeEntry);
                    }
                }
                if (namespaceEntry.Children.Count > 0)
                {
                    namespaceEntry.Children.Sort();
                }
            }

            // Make sure we dont display any empty namespaces
            for (int i = map[0].Children.Count - 1; i >= 0; i--)
            {
                Entry entry = map[0].Children[i];
                if (namespaceEntry.Children.Count == 0)
                {
                    map[0].Children.RemoveAt(i);
                }
            }

            return(namespaceEntry);
        }
Beispiel #10
0
 /// <summary>
 /// Initialises a new instance of the Document class.
 /// </summary>
 /// <param name="assemblies">The assemblies being documented.</param>
 /// <param name="mapperType">The type of document mapper to use to create the document map</param>
 /// <param name="useObservableCollection">Should the document map use an observable collection.</param>
 /// <param name="creator">The EntryCreator to use to create new Entries in the Map</param>
 public Document(List <DocumentedAssembly> assemblies, Mappers mapperType, bool useObservableCollection, EntryCreator creator)
 {
     _mapper = DocumentMapper.Create(assemblies, mapperType, useObservableCollection, creator);
     _mapper.PreEntryAdded += new EventHandler <PreEntryAddedEventArgs>(PreEntryAdded);
     _assemblies            = assemblies;
 }