Пример #1
0
        public override void BuildDocs(string outputPath)
        {
            outputPath = DocUtilities.ChangeExtension(outputPath, "md");

            // Write markdown file
            using (var writer = new MarkdownWriter(outputPath))
            {
                foreach (var type in Library.ExportedTypes.Where(t => !t.Name.StartsWith("_")).OrderBy(t => t.Name))
                {
                    // Pull XML docs for type
                    var typeDocs = Docs[ID.GetIDString(type)];

                    // Header, e.g. "StringBuilder class (System)"
                    writer.WriteHeader(2, DocUtilities.GetTypeTitle(type, true), true);

                    // Summary and other info
                    PrintObsoleteWarning(type, writer);
                    writer.WriteParagraph($"**Namespace:** {type.Namespace}");
                    writer.WriteParagraph($"**Inheritance:** {DocUtilities.GetInheritanceString(type)}", true);
                    Summary(typeDocs, writer);

                    // Signature
                    writer.WriteCodeBlock(Lang, DocUtilities.GetClassSignature(type));

                    // Members
                    WriteConstructors(type, writer);
                    WriteProperties(type, writer);
                    WriteIndexers(type, writer);
                    WriteFields(type, writer);
                    WriteMethods(type, writer);
                }
            }
        }
Пример #2
0
        private void WriteMethods(Type type, MarkdownWriter writer)
        {
            var methods = type.GetMethods(MemberSearchFlags)
                          // Exclude compiler-generated and internal methods
                          .Where(m => !m.IsSpecialName && !m.IsAssembly)
                          // Exclude protected methods when class is sealed
                          .Where(m => type.IsSealed
                                        ? m.IsPublic
                                        : !m.IsPrivate)
                          // Sort alphabetically...
                          .OrderBy(m => m.Name)
                          // ... then by parameter count.
                          .ThenBy(m => m.GetParameters().Length)
                          .ToArray();

            if (methods.Length > 0)
            {
                writer.WriteHeader(3, "Methods");
                foreach (var method in methods)
                {
                    var methodDocs = Docs[ID.GetIDString(method)];

                    // Heading
                    writer.WriteHeader(4, DocUtilities.GetMethodSignature(method, false, false), true);
                    PrintObsoleteWarning(method, writer);
                    Summary(methodDocs, writer);
                    writer.WriteCodeBlock(Lang, DocUtilities.GetMethodSignature(method, true, true));

                    // Parameters
                    WriteParamList(4, method, writer, methodDocs);
                    Returns(4, methodDocs, writer);
                    Remarks(4, methodDocs, writer);
                }
            }
        }
Пример #3
0
        private void WriteFields(Type type, MarkdownWriter writer)
        {
            var fields = type.GetFields()
                         .Where(f => !f.IsSpecialName)
                         .OrderBy(f => f.Name)
                         .ToArray();

            if (fields.Length == 0)
            {
                return;
            }

            writer.WriteHeader(3, "Fields");

            for (int i = 0; i < fields.Length; i++)
            {
                var fieldDocs = Docs[ID.GetIDString(fields[i])];
                writer.WriteHeader(4, DocUtilities.GetFieldSignature(fields[i], false));
                PrintObsoleteWarning(fields[i], writer);
                Summary(fieldDocs, writer);

                writer.WriteCodeBlock(Lang, DocUtilities.GetFieldSignature(fields[i], true));

                Remarks(5, fieldDocs, writer);
            }
        }
Пример #4
0
        private void WriteConstructors(Type type, MarkdownWriter writer)
        {
            // Constructor list
            var ctors = type.GetConstructors();

            if (ctors.Length > 0)
            {
                writer.WriteHeader(3, "Constructors");

                for (int i = 0; i < ctors.Length; i++)
                {
                    // Heading for constructor section
                    var ctorDocs = Docs[ID.GetIDString(ctors[i])];
                    writer.WriteHeader(4, DocUtilities.GetMethodSignature(ctors[i], false, false));
                    PrintObsoleteWarning(ctors[i], writer);
                    Summary(ctorDocs, writer);

                    // Signature
                    writer.WriteCodeBlock(Lang, DocUtilities.GetMethodSignature(ctors[i], true, true));

                    // Get constructor's parameters and associated docs
                    WriteParamList(5, ctors[i], writer, ctorDocs);
                    Remarks(5, ctorDocs, writer);
                }
            }
        }
Пример #5
0
        private void WriteIndexers(Type type, MarkdownWriter writer)
        {
            var indexers = type.GetProperties()
                           .Where(p => p.GetIndexParameters().Length > 0)
                           .OrderBy(p => p.GetIndexParameters().Length)
                           .ToArray();

            if (indexers.Length == 0)
            {
                return;
            }

            writer.WriteHeader(3, "Indexers");

            for (int i = 0; i < indexers.Length; i++)
            {
                var indexDocs = Docs[ID.GetIDString(indexers[i])];
                writer.WriteHeader(4, DocUtilities.GetPropertySignature(indexers[i], false, true, false));
                PrintObsoleteWarning(indexers[i], writer);
                Summary(indexDocs, writer);

                writer.WriteCodeBlock(Lang, DocUtilities.GetPropertySignature(indexers[i], true, true, true));

                Remarks(5, indexDocs, writer);
            }
        }
Пример #6
0
        private void WriteProperties(Type type, MarkdownWriter writer)
        {
            var props = type.GetProperties(MemberSearchFlags)
                        // Show protected members if class is not sealed
                        .Where(p => type.IsSealed
                                        ? (p.CanRead && p.GetMethod.IsPublic) || (p.CanWrite && p.SetMethod.IsPublic)
                                        : (p.CanRead && !p.GetMethod.IsPrivate) || (p.CanWrite && !p.SetMethod.IsPrivate))
                        // Indexers are technically properties, but we want to handle them separately
                        .Where(p => p.GetIndexParameters().Length == 0)
                        // Sort alphabetically
                        .OrderBy(p => p.Name)
                        .ToArray();

            if (props.Length == 0)
            {
                return;
            }

            writer.WriteHeader(3, "Properties");

            for (int i = 0; i < props.Length; i++)
            {
                var propDocs = Docs[ID.GetIDString(props[i])];
                writer.WriteHeader(4, DocUtilities.GetPropertySignature(props[i], false, false, false));
                PrintObsoleteWarning(props[i], writer);
                Summary(propDocs, writer);

                writer.WriteCodeBlock(Lang, DocUtilities.GetPropertySignature(props[i], true, true, true));

                Remarks(5, propDocs, writer);
            }
        }
Пример #7
0
        private void WriteParamList(int rank, MethodBase method, MarkdownWriter writer, MemberXmlDocs docs)
        {
            var plist = method.GetParameters();


            if (method.ContainsGenericParameters)
            {
                if (method.IsGenericMethod)
                {
                    var tplist = method.GetGenericArguments();
                    writer.WriteParagraph("**Type Parameters**");
                    for (int i = 0; i < tplist.Length; i++)
                    {
                        writer.WriteLine($"- `{tplist[i].Name}`: {TypeParam(docs, tplist[i].Name)}");
                    }
                }
            }

            if (plist.Length > 0)
            {
                writer.WriteParagraph("**Parameters**");
                for (int i = 0; i < plist.Length; i++)
                {
                    writer.WriteLine($"- `{plist[i].Name}`: {Param(docs, plist[i])}");
                }
            }
        }
Пример #8
0
        private static void Returns(int rank, MemberXmlDocs docs, MarkdownWriter writer)
        {
            var returns = docs?.Returns;

            if (!String.IsNullOrWhiteSpace(returns))
            {
                writer.WriteHeader(rank, "Returns");
                writer.WriteParagraph(returns);
            }
        }
Пример #9
0
        private void PrintObsoleteWarning(MemberInfo member, MarkdownWriter writer)
        {
            var obsAttr = member.GetCustomAttribute <ObsoleteAttribute>();

            if (obsAttr == null)
            {
                return;
            }
            writer.WriteInfoBox($"**This item is deprecated.**\n{obsAttr.Message}", "warning");
        }
Пример #10
0
 private static void Summary(MemberXmlDocs docs, MarkdownWriter writer) => writer.WriteParagraph(docs?.Summary ?? "_No Summary_");
Пример #11
0
        public override void BuildDocs(string outputPath)
        {
            var pages     = new PageTree("docs");
            var PageTrees = new List <PageTree>();

            foreach (var type in Library.GetExportedTypes())
            {
                var typePath = $"{type.Namespace.Replace('.', '/')}/{DocUtilities.GetURLTitle(type)}";
                var typeData = Docs[ID.GetIDString(type)];

                pages[typePath] = new TypePage(type, typeData, Docs);
                PageTrees.Add(pages.GetNode(typePath));

                // Constructors
                var ctors = type.GetConstructors();
                if (ctors.Length > 0)
                {
                    // Path to ctors group
                    var ctorsGroupPath = $"{typePath}/ctors";

                    var ctorsData = new Dictionary <ConstructorInfo, MemberXmlDocs>();
                    foreach (var ctor in ctors)
                    {
                        var ctorData = Docs[ID.GetIDString(ctor)];
                        ctorsData.Add(ctor, ctorData);
                    }

                    pages[ctorsGroupPath] = new ConstructorsPage(type, ctors, ctorsData);
                    PageTrees.Add(pages.GetNode(ctorsGroupPath));
                }

                // Method groups
                foreach (var methodGroup in type.GetMethods()
                         .Where(m => !m.Name.StartsWith("get_") && !m.Name.StartsWith("set_"))
                         .GroupBy(m => m.Name))
                {
                    // Path to method group
                    var methodGroupPath = $"{typePath}/{methodGroup.Key}";

                    // Map of reflected methods and documentation
                    var methods = new Dictionary <MethodInfo, MemberXmlDocs>();

                    foreach (var method in methodGroup)
                    {
                        var methodData = Docs[ID.GetIDString(method)];
                        methods[method] = methodData;
                    }

                    pages[methodGroupPath] = new MethodGroupPage(type, methodGroup.Key, methods);
                    PageTrees.Add(pages.GetNode(methodGroupPath));
                }

                // Fields
                foreach (var field in type.GetFields().Where(f => (f.IsPublic || !f.IsPrivate) && (!f.DeclaringType.IsEnum || !f.IsSpecialName)))
                {
                    var fieldPath = Path.Combine(typePath, field.Name).Replace('\\', '/');
                    var fieldData = Docs[ID.GetIDString(field)];
                    pages[fieldPath] = new FieldPage(field, fieldData);
                    PageTrees.Add(pages.GetNode(fieldPath));
                }

                // Properties and Indexers
                int numIndexers = 0;
                foreach (var property in type.GetProperties())
                {
                    var propData = Docs[ID.GetIDString(property)];

                    string propPath;
                    if (property.GetIndexParameters().Length > 0)
                    {
                        propPath = $"{typePath}/this/{++numIndexers}";
                    }
                    else
                    {
                        propPath = $"{typePath}/{property.Name}";
                    }

                    pages[propPath] = new PropertyPage(property, propData);
                    PageTrees.Add(pages.GetNode(propPath));
                }
            }

            // Create a task for each document that needs to be exported, run them all at once
            var exportTasks = new Task[PageTrees.Count];

            for (int i = 0; i < PageTrees.Count; i++)
            {
                var node = PageTrees[i];
                exportTasks[i] = Task.Run(() =>
                {
                    var documentDir  = Directory.GetParent($"{outputPath}/{node.Path}").FullName;
                    var documentPath = $"{outputPath}/{node.Path}.md";
                    Directory.CreateDirectory(documentDir);
                    using (var writer = new MarkdownWriter(documentPath))
                    {
                        node.Page.Render(node, writer);
                    }
                });
            }

            // Wait for all export tasks to finish
            Task.WaitAll(exportTasks);
        }