Exemple #1
0
        /// <summary>
        /// Parses a <see cref="DocAssembly"/> to return a <see cref="DocFile"/>.
        /// </summary>
        /// <param name="assembly">The <see cref="DocAssembly"/> to parse.</param>
        /// <returns>The transformed <see cref="DocFile"/>.</returns>
        public DocFile Parse(DocAssembly assembly)
        {
            var result = new DocFile(assembly.FileName);

            result.AddThenBlankLine(writer.WriteHeading1($"{assembly.Name} API Reference"));
            result.AddThenBlankLine(ParserUtils.ProcessBreadcrumb(this));

            var list = new MarkdownList();

            foreach (var customDoc in assembly.CustomDocs)
            {
                if (customDoc is DocSerialization ser)
                {
                    list.AddItem(writer.WriteLink($"{ser.Name.NameOnly()} Reference", ser.FileName));
                    result.Files.Add(ProcessSerialization(ser, assembly));
                }
            }

            foreach (var ns in assembly.Namespaces.OrderBy(ns => ns.Name))
            {
                list.AddItem(writer.WriteLink(ns.Name, ns.FileName));
                result.Files.Add(ProcessNamespace(ns));
            }

            writer.AddRange(result.Markdown, list.CloseList());
            return(result);
        }
Exemple #2
0
        private DocFile ProcessSerialization(DocSerialization ser, DocAssembly assembly)
        {
            var result = new DocFile(ser.FileName);

            result.AddThenBlankLine(writer.WriteHeading1($"{ser.Name} Reference"));
            result.AddThenBlankLine(ParserUtils.ProcessBreadcrumb(assembly));
            var table = new MarkdownTable("ExpressionType", "Serializer");

            foreach (ExpressionType expressionType in Enum.GetValues(typeof(ExpressionType)))
            {
                var name = expressionType.ToString();
                if (ser.Serializers.ContainsKey(expressionType))
                {
                    var entry = ser.Serializers[expressionType];
                    table.AddRow(name, writer.WriteLink(entry.Name.NameOnly(), entry.FileName));
                }
                else
                {
                    table.AddRow(name, "_Not Supported_");
                }
            }

            writer.AddRange(result.Markdown, table.CloseTable());
            return(result);
        }
        /// <summary>
        /// Builds the serializer cross-reference.
        /// </summary>
        /// <param name="doc">The <see cref="DocAssembly"/> for serializers.</param>
        private void IterateSerializers(DocAssembly doc)
        {
            if (doc.CustomDocs.OfType <DocSerialization>().Any())
            {
                return;
            }

            var serializerDoc = new DocSerialization
            {
                Name = typeof(ExpressionSerializerAttribute).Namespace,
            };

            var types = Assembly.GetTypes()
                        .Where(t => t.Namespace == typeof(BaseSerializer <,>).Namespace &&
                               t.GetCustomAttributes(false)
                               .Any(c => c is ExpressionSerializerAttribute))
                        .SelectMany(t => t.GetCustomAttributes(false).OfType <ExpressionSerializerAttribute>()
                                    .Select(c => new { serializer = t, type = c.Type }));

            foreach (var serializer in types)
            {
                var name    = serializer.serializer.FullName;
                var typeDoc = ParserUtils.GetTypeQuery(doc).Where(d => d.Name == name).Single();
                serializerDoc.Serializers.Add(serializer.type, typeDoc);
            }

            doc.CustomDocs.Add(serializerDoc);
        }
Exemple #4
0
        /// <summary>
        /// Parse the comments for an assembly.
        /// </summary>
        /// <param name="path">The path that contains the XML comments.</param>
        /// <param name="assembly">The <see cref="DocAssembly"/> to annotate.</param>
        public void ParseComments(string path, DocAssembly assembly)
        {
            var doc = fileHelper.LoadXmlDocs(path);

            if (doc != null)
            {
                ParseXml(doc, assembly);
            }
        }
        /// <summary>
        /// Iterate the namespaces of the assembly.
        /// </summary>
        /// <param name="doc">The <see cref="DocAssembly"/> to iterate.</param>
        private void IterateNamespaces(DocAssembly doc)
        {
            Types = Assembly.GetExportedTypes();
            var namespaces = Types.Select(t => t.Namespace).Distinct().OrderBy(n => n);

            foreach (var nsp in namespaces)
            {
                Console.WriteLine($"Parsing namespace \"{nsp}\"...");
                var docNamespace = new DocNamespace(nsp)
                {
                    Assembly = doc,
                };
                IterateTypes(docNamespace);
                doc.Namespaces.Add(docNamespace);
            }
        }
        /// <summary>
        /// Parses the assembly.
        /// </summary>
        /// <remarks>
        /// First pass creates the assembly and parses it. Second pass takes the
        /// assembly and processes for addition info that requires cross-referencing.
        /// </remarks>
        /// <param name="doc">The <see cref="DocAssembly"/> ref for pass 2.</param>
        /// <returns>The parsed <see cref="DocAssembly"/>.</returns>
        public DocAssembly Parse(DocAssembly doc = null)
        {
            if (doc == null)
            {
                doc = new DocAssembly(AssemblyName);
                IterateNamespaces(doc);
            }
            else
            {
                IterateNamespacesPass2(doc);
            }

            if (Assembly.GetTypes().Any(t => t == typeof(ExpressionSerializerAttribute)))
            {
                IterateSerializers(doc);
            }

            return(doc);
        }
        /// <summary>
        /// Second pass to handle relationships.
        /// </summary>
        /// <param name="doc">The <see cref="DocAssembly"/> to iterate.</param>
        private void IterateNamespacesPass2(DocAssembly doc)
        {
            // now go back and handle relationships
            foreach (var nsp in doc.Namespaces)
            {
                foreach (var type in nsp.Types)
                {
                    ProcessTypePass2(type);
                    if (!type.IsInterface)
                    {
                        type.Inheritance = ProcessInheritance(type.Type);
                    }

                    ProcessConstructors(type);
                    ProcessProperties(type);
                    ProcessMethods(type);
                }
            }
        }
Exemple #8
0
 /// <summary>
 /// Gets a queryable to examine types.
 /// </summary>
 /// <param name="assembly">The host <see cref="DocAssembly"/>.</param>
 /// <returns>The <see cref="IQueryable"/>.</returns>
 public static IQueryable <DocExportedType> GetTypeQuery(this DocAssembly assembly) =>
 assembly.Namespaces.SelectMany(ns => ns.Types).AsQueryable();
Exemple #9
0
        /// <summary>
        /// Parses the XML comments.
        /// </summary>
        /// <param name="doc">The <see cref="XmlDocument"/> for XML comments.</param>
        /// <param name="assembly">The <see cref="DocAssembly"/> to annotate.</param>
        private void ParseXml(XmlDocument doc, DocAssembly assembly)
        {
            var typeList = assembly.Namespaces.SelectMany(ns => ns.Types);

            foreach (var type in typeList)
            {
                var typeNode = doc.SelectSingleNode(type.XPath);
                if (typeNode == null)
                {
                    NotFound(type.XPath);
                }

                if (typeNode is XmlElement node)
                {
                    type.Description = GetTextBlock(node, ParserUtils.Summary);
                    type.Remarks     = GetTextBlock(node, ParserUtils.Remarks);
                    type.Example     = GetTextBlock(node, ParserUtils.Example);
                    ProcessTypeParamDescriptions(node, type.TypeParameters);
                }

                if (type.Constructor != null && type.Constructor.Overloads.Any())
                {
                    foreach (var overload in type.Constructor.Overloads)
                    {
                        var docNode = doc.SelectSingleNode(overload.XPath);

                        if (docNode == null)
                        {
                            NotFound(overload.XPath);
                        }

                        if (docNode is XmlElement ctorNode)
                        {
                            overload.Description = GetTextBlock(ctorNode, ParserUtils.Summary);
                            overload.Remarks     = GetTextBlock(ctorNode, ParserUtils.Remarks);
                            overload.Example     = GetTextBlock(ctorNode, ParserUtils.Example);
                            overload.Exceptions  = GetExceptions(ctorNode);
                            ProcessParameters(overload.Parameters, ctorNode);
                            ProcessTypeParamDescriptions(ctorNode, overload.TypeParameters);
                        }

                        if (string.IsNullOrWhiteSpace(overload.Description))
                        {
                            var ctorType = overload.Constructor.ConstructorType.Type;
                            overload.Description =
                                $"Initializes a new instance of the [{MarkdownWriter.Normalize(TypeCache.Cache[ctorType].FriendlyName)}]({TypeCache.Cache[ctorType].Link}) class.";
                        }
                    }
                }

                if (type.Methods.Any())
                {
                    foreach (var method in type.Methods)
                    {
                        foreach (var overload in method.MethodOverloads)
                        {
                            var oNode = doc.SelectSingleNode(overload.XPath);

                            if (oNode == null)
                            {
                                NotFound(overload.XPath);
                            }

                            if (oNode is XmlElement methodNode)
                            {
                                overload.Description = GetTextBlock(methodNode, ParserUtils.Summary);
                                overload.Remarks     = GetTextBlock(methodNode, ParserUtils.Remarks);
                                overload.Example     = GetTextBlock(methodNode, ParserUtils.Example);
                                overload.Exceptions  = GetExceptions(methodNode);
                                overload.Returns     = GetTextBlock(methodNode, ParserUtils.Returns);
                                ProcessParameters(overload.Parameters, methodNode);
                                ProcessTypeParamDescriptions(methodNode, overload.Method.MethodType.TypeParameters);
                            }
                        }
                    }
                }

                if (type.Properties.Any())
                {
                    ProcessProperties(doc, type.Properties, type.TypeParameters);
                }
            }
        }