Пример #1
0
        private void ResolveCodeSource(XDocument doc, ITripleSlashCommentParserContext context)
        {
            foreach (XElement node in doc.XPathSelectElements("//code"))
            {
                var source = node.Attribute("source");
                if (source == null || string.IsNullOrEmpty(source.Value))
                {
                    continue;
                }

                if (context.Source == null || string.IsNullOrEmpty(context.Source.Path))
                {
                    Logger.LogWarning($"Unable to get source file path for {node.ToString()}");
                    return;
                }

                var region = node.Attribute("region");

                var path = source.Value;
                if (!Path.IsPathRooted(path))
                {
                    var basePath = !string.IsNullOrEmpty(context.CodeSourceBasePath) ? context.CodeSourceBasePath : Path.GetDirectoryName(Path.Combine(EnvironmentContext.BaseDirectory, context.Source.Path));

                    path = Path.Combine(basePath, path);
                }

                ResolveCodeSource(node, path, region?.Value);
            }
        }
Пример #2
0
 public static TripleSlashCommentModel CreateModel(string xml, ITripleSlashCommentParserContext context)
 {
     if (context == null)
     {
         throw new ArgumentNullException(nameof(context));
     }
     if (string.IsNullOrEmpty(xml))
     {
         return(null);
     }
     // Quick turnaround for badly formed XML comment
     if (xml.StartsWith("<!-- Badly formed XML comment ignored for member "))
     {
         Logger.LogWarning($"Invalid triple slash comment is ignored: {xml}");
         return(null);
     }
     try
     {
         var model = new TripleSlashCommentModel(xml, context);
         return(model);
     }
     catch (XmlException)
     {
         return(null);
     }
 }
Пример #3
0
        private TripleSlashCommentModel(string xml, SyntaxLanguage language, ITripleSlashCommentParserContext context)
        {
            // Transform triple slash comment
            XDocument doc = TripleSlashCommentTransformer.Transform(xml, language);

            _context = context;
            if (!context.PreserveRawInlineComments)
            {
                ResolveSeeCref(doc, context.AddReferenceDelegate, context.ResolveCRef);
                ResolveSeeAlsoCref(doc, context.AddReferenceDelegate, context.ResolveCRef);
                ResolveExceptionCref(doc, context.AddReferenceDelegate, context.ResolveCRef);
            }
            ResolveCodeSource(doc, context);
            var nav = doc.CreateNavigator();

            Summary = GetSummary(nav, context);
            Remarks = GetRemarks(nav, context);
            Returns = GetReturns(nav, context);

            Exceptions     = GetExceptions(nav, context);
            Sees           = GetSees(nav, context);
            SeeAlsos       = GetSeeAlsos(nav, context);
            Examples       = GetExamples(nav, context);
            Parameters     = GetParameters(nav, context);
            TypeParameters = GetTypeParameters(nav, context);
            IsInheritDoc   = GetIsInheritDoc(nav, context);
        }
Пример #4
0
        private TripleSlashCommentModel(string xml, ITripleSlashCommentParserContext context)
        {
            // Normalize xml line ending before load into xml
            XDocument doc = XDocument.Parse(xml, LoadOptions.SetLineInfo | LoadOptions.PreserveWhitespace);

            if (!context.PreserveRawInlineComments)
            {
                ResolveSeeCref(doc, context.AddReferenceDelegate);
                ResolveSeeAlsoCref(doc, context.AddReferenceDelegate);
                ResolveParameterRef(doc);
            }
            var nav = doc.CreateNavigator();

            _lines  = doc.ToString().Split('\n');
            Summary = GetSummary(nav, context);
            Remarks = GetRemarks(nav, context);
            Returns = GetReturns(nav, context);

            Exceptions     = GetExceptions(nav, context);
            Sees           = GetSees(nav, context);
            SeeAlsos       = GetSeeAlsos(nav, context);
            Examples       = GetExamples(nav, context);
            Parameters     = GetParameters(nav, context);
            TypeParameters = GetTypeParameters(nav, context);
        }
Пример #5
0
        /// <summary>
        /// Get summary node out from triple slash comments
        /// </summary>
        /// <param name="xml"></param>
        /// <param name="normalize"></param>
        /// <returns></returns>
        /// <example>
        /// <code> <see cref="Hello"/></code>
        /// </example>
        private static string GetSummary(XPathNavigator nav, ITripleSlashCommentParserContext context)
        {
            // Resolve <see cref> to @ syntax
            // Also support <seealso cref>
            string selector = "/member/summary";

            return(GetSingleNodeValue(nav, selector, context.Normalize));
        }
Пример #6
0
        private string GetReturns(XPathNavigator nav, ITripleSlashCommentParserContext context)
        {
            // Resolve <see cref> to @ syntax
            // Also support <seealso cref>
            string selector = "/member/returns";

            return(GetSingleNodeValue(nav, selector));
        }
Пример #7
0
        /// <summary>
        /// To get `seealso` tags out
        /// </summary>
        /// <param name="xml"></param>
        /// <param name="context"></param>
        /// <returns></returns>
        /// <seealso cref="WaitForChangedResult"/>
        /// <seealso cref="http://google.com">ABCS</seealso>
        private List <LinkInfo> GetSeeAlsos(XPathNavigator nav, ITripleSlashCommentParserContext context)
        {
            var result = GetMultipleLinkInfo(nav, "/member/seealso").ToList();

            if (result.Count == 0)
            {
                return(null);
            }
            return(result);
        }
Пример #8
0
        /// <summary>
        /// To get `seealso` tags out
        /// </summary>
        /// <param name="xml"></param>
        /// <param name="context"></param>
        /// <returns></returns>
        /// <seealso cref="WaitForChangedResult"/>
        /// <seealso cref="http://google.com">ABCS</seealso>
        private static List <CrefInfo> GetSeeAlsos(XPathNavigator nav, ITripleSlashCommentParserContext context)
        {
            var result = GetMulitpleCrefInfo(nav, "/member/seealso", context.Normalize).ToList();

            if (result.Count == 0)
            {
                return(null);
            }
            return(result);
        }
Пример #9
0
        /// <summary>
        /// Get exceptions nodes out from triple slash comments
        /// </summary>
        /// <param name="xml"></param>
        /// <param name="normalize"></param>
        /// <returns></returns>
        /// <exception cref="XmlException">This is a sample of exception node</exception>
        private List <ExceptionInfo> GetExceptions(XPathNavigator nav, ITripleSlashCommentParserContext context)
        {
            string selector = "/member/exception";
            var    result   = GetMulitpleCrefInfo(nav, selector).ToList();

            if (result.Count == 0)
            {
                return(null);
            }
            return(result);
        }
Пример #10
0
 public static void FeedComments(MetadataItem item, ITripleSlashCommentParserContext context)
 {
     if (!string.IsNullOrEmpty(item.RawComment))
     {
         var commentModel = TripleSlashCommentModel.CreateModel(item.RawComment, item.Language, context);
         if (commentModel == null) return;
         item.Summary = commentModel.Summary;
         item.Remarks = commentModel.Remarks;
         item.Exceptions = commentModel.Exceptions;
         item.Sees = commentModel.Sees;
         item.SeeAlsos = commentModel.SeeAlsos;
         item.Examples = commentModel.Examples;
         item.CommentModel = commentModel;
     }
 }
Пример #11
0
        public static TripleSlashCommentModel CreateModel(string xml, ITripleSlashCommentParserContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }
            if (string.IsNullOrEmpty(xml))
            {
                return(null);
            }
            // Quick turnaround for badly formed XML comment
            if (xml.StartsWith("<!-- Badly formed XML comment ignored for member "))
            {
                return(null);
            }
            try
            {
                XmlDocument doc = new XmlDocument();
                doc.LoadXml(xml);
                var nav = doc.CreateNavigator();
                if (!context.PreserveRawInlineComments)
                {
                    ResolveSeeCref(nav, string.Empty, context.AddReferenceDelegate);
                    ResolveSeeAlsoCref(nav, string.Empty, context.AddReferenceDelegate);
                    ResolveParameterRef(nav);
                }

                var model = new TripleSlashCommentModel();
                model.Summary = GetSummary(nav, context);
                model.Remarks = GetRemarks(nav, context);
                model.Returns = GetReturns(nav, context);

                model.Exceptions     = GetExceptions(nav, context);
                model.Sees           = GetSees(nav, context);
                model.SeeAlsos       = GetSeeAlsos(nav, context);
                model.Examples       = GetExamples(nav, context);
                model.Parameters     = GetParameters(nav, context);
                model.TypeParameters = GetTypeParameters(nav, context);
                return(model);
            }
            catch (XmlException)
            {
                return(null);
            }
        }
Пример #12
0
 public static void FeedComments(MetadataItem item, ITripleSlashCommentParserContext context)
 {
     if (!string.IsNullOrEmpty(item.RawComment))
     {
         var commentModel = TripleSlashCommentModel.CreateModel(item.RawComment, item.Language, context);
         if (commentModel == null)
         {
             return;
         }
         item.Summary      = commentModel.Summary;
         item.Remarks      = commentModel.Remarks;
         item.Exceptions   = commentModel.Exceptions;
         item.Sees         = commentModel.Sees;
         item.SeeAlsos     = commentModel.SeeAlsos;
         item.Examples     = commentModel.Examples;
         item.CommentModel = commentModel;
     }
 }
Пример #13
0
        private bool GetIsInheritDoc(XPathNavigator nav, ITripleSlashCommentParserContext context)
        {
            var node = nav.SelectSingleNode("/member/inheritdoc");

            if (node == null)
            {
                return(false);
            }
            if (node.HasAttributes)
            {
                //The Sandcastle implementation of <inheritdoc /> supports two attributes: 'cref' and 'select'.
                //These attributes allow changing the source of the inherited doc and controlling what is inherited.
                //Until these attributes are supported, ignoring inheritdoc elements with attributes, so as not to misinterpret them.
                Logger.LogWarning("Attributes on <inheritdoc /> elements are not supported; inheritdoc element will be ignored.");
                return(false);
            }
            return(true);
        }
Пример #14
0
        private string GetInheritDoc(XPathNavigator nav, ITripleSlashCommentParserContext context)
        {
            var node = nav.SelectSingleNode("/member/inheritdoc");

            if (node == null)
            {
                return(null);
            }

            if (node.HasAttributes)
            {
                // The Sandcastle implementation of <inheritdoc /> supports two attributes: 'cref' and 'select'.
                // These attributes allow changing the source of the inherited doc and controlling what is inherited.
                // Only cref is supported currently
                var cRef = node.GetAttribute("cref", node.NamespaceURI);
                if (!string.IsNullOrEmpty(cRef))
                {
                    // Strict check is needed as value could be an invalid href,
                    // e.g. !:Dictionary&lt;TKey, string&gt; when user manually changed the intellisensed generic type
                    var match = CommentIdRegex.Match(cRef);
                    if (match.Success)
                    {
                        var id   = match.Groups["id"].Value;
                        var type = match.Groups["type"].Value;

                        if (type == "Overload")
                        {
                            id += '*';
                        }

                        context.AddReferenceDelegate?.Invoke(id, cRef);
                        return(id);
                    }
                }
                else
                {
                    Logger.LogWarning("Unsupported attribute on <inheritdoc />; inheritdoc element will be ignored.");
                    return(null);
                }
            }

            // Default inheritdoc (no explicit reference)
            return(string.Empty);
        }
Пример #15
0
 public static TripleSlashCommentModel CreateModel(string xml, SyntaxLanguage language, ITripleSlashCommentParserContext context)
 {
     if (context == null) throw new ArgumentNullException(nameof(context));
     if (string.IsNullOrEmpty(xml)) return null;
     // Quick turnaround for badly formed XML comment
     if (xml.StartsWith("<!-- Badly formed XML comment ignored for member "))
     {
         Logger.LogWarning($"Invalid triple slash comment is ignored: {xml}");
         return null;
     }
     try
     {
         var model = new TripleSlashCommentModel(xml, language, context);
         return model;
     }
     catch (XmlException)
     {
         return null;
     }
 }
Пример #16
0
        private TripleSlashCommentModel(string xml, SyntaxLanguage language, ITripleSlashCommentParserContext context)
        {
            // Transform triple slash comment
            XDocument doc = _transformer.Transform(xml, language);

            _context = context;
            if (!context.PreserveRawInlineComments)
            {
                ResolveSeeCref(doc, context.AddReferenceDelegate);
                ResolveSeeAlsoCref(doc, context.AddReferenceDelegate);
            }
            var nav = doc.CreateNavigator();
            Summary = GetSummary(nav, context);
            Remarks = GetRemarks(nav, context);
            Returns = GetReturns(nav, context);

            Exceptions = GetExceptions(nav, context);
            Sees = GetSees(nav, context);
            SeeAlsos = GetSeeAlsos(nav, context);
            Examples = GetExamples(nav, context);
            Parameters = GetParameters(nav, context);
            TypeParameters = GetTypeParameters(nav, context);
        }
Пример #17
0
        public static TripleSlashCommentModel CreateModel(string xml, ITripleSlashCommentParserContext context)
        {
            if (context == null) throw new ArgumentNullException(nameof(context));
            if (string.IsNullOrEmpty(xml)) return null;
            // Quick turnaround for badly formed XML comment
            if (xml.StartsWith("<!-- Badly formed XML comment ignored for member ")) return null;
            try
            {
                XmlDocument doc = new XmlDocument();
                doc.LoadXml(xml);
                var nav = doc.CreateNavigator();
                if (!context.PreserveRawInlineComments)
                {
                    ResolveSeeCref(nav, string.Empty, context.AddReferenceDelegate);
                    ResolveSeeAlsoCref(nav, string.Empty, context.AddReferenceDelegate);
                    ResolveParameterRef(nav);
                }

                var model = new TripleSlashCommentModel();
                model.Summary = GetSummary(nav, context);
                model.Remarks = GetRemarks(nav, context);
                model.Returns = GetReturns(nav, context);

                model.Exceptions = GetExceptions(nav, context);
                model.Sees = GetSees(nav, context);
                model.SeeAlsos = GetSeeAlsos(nav, context);
                model.Examples = GetExamples(nav, context);
                model.Parameters = GetParameters(nav, context);
                model.TypeParameters = GetTypeParameters(nav, context);
                return model;
            }
            catch (XmlException)
            {
                return null;
            }
        }
Пример #18
0
 private static Dictionary<string, string> GetTypeParameters(XPathNavigator navigator, ITripleSlashCommentParserContext context)
 {
     return GetListContent(navigator, "/member/typeparam", "type parameter", context);
 }
Пример #19
0
        private static Dictionary<string, string> GetListContent(XPathNavigator navigator, string xpath, string contentType, ITripleSlashCommentParserContext context)
        {
            var iterator = navigator.Select(xpath);
            var result = new Dictionary<string, string>();
            if (iterator == null) return result;
            foreach (XPathNavigator nav in iterator)
            {
                string name = nav.GetAttribute("name", string.Empty);
                string description = nav.InnerXml;
                if (context.Normalize) description = NormalizeContentFromTripleSlashComment(description);
                if (!string.IsNullOrEmpty(name))
                {
                    if (result.ContainsKey(name))
                    {
                        string path = context.Source.Remote != null ? Path.Combine(context.Source.Remote.LocalWorkingDirectory, context.Source.Remote.RelativePath) : context.Source.Path;
                        Logger.LogWarning($"Duplicate {contentType} '{name}' found in comments, the latter one is ignored.", null, path.ToDisplayPath(), context.Source.StartLine.ToString());
                    }
                    else
                    {
                        result.Add(name, description);
                    }
                }
            }

            return result;
        }
Пример #20
0
 /// <summary>
 /// To get `example` tags out
 /// </summary>
 /// <param name="xml"></param>
 /// <param name="context"></param>
 /// <returns></returns>
 /// <example> 
 /// This sample shows how to call the <see cref="GetExceptions(string, ITripleSlashCommentParserContext)"/> method.
 /// <code>
 /// class TestClass  
 /// { 
 ///     static int Main()  
 ///     { 
 ///         return GetExceptions(null, null).Count(); 
 ///     } 
 /// } 
 /// </code> 
 /// </example>
 private static List<string> GetExamples(XPathNavigator nav, ITripleSlashCommentParserContext context)
 {
     // Resolve <see cref> to @ syntax
     // Also support <seealso cref>
     return GetMultipleExampleNodes(nav, "/member/example", context.Normalize).ToList();
 }
Пример #21
0
 /// <summary>
 /// To get `seealso` tags out
 /// </summary>
 /// <param name="xml"></param>
 /// <param name="context"></param>
 /// <returns></returns>
 /// <seealso cref="WaitForChangedResult"/>
 /// <seealso cref="http://google.com">ABCS</seealso>
 private static List<CrefInfo> GetSeeAlsos(XPathNavigator nav, ITripleSlashCommentParserContext context)
 {
     var result = GetMulitpleCrefInfo(nav, "/member/seealso", context.Normalize).ToList();
     if (result.Count == 0) return null;
     return result;
 }
Пример #22
0
 /// <summary>
 /// Get exceptions nodes out from triple slash comments
 /// </summary>
 /// <param name="xml"></param>
 /// <param name="normalize"></param>
 /// <returns></returns>
 /// <exception cref="XmlException">This is a sample of exception node</exception>
 private static List<CrefInfo> GetExceptions(XPathNavigator nav, ITripleSlashCommentParserContext context)
 {
     string selector = "/member/exception";
     var result = GetMulitpleCrefInfo(nav, selector, context.Normalize).ToList();
     if (result.Count == 0) return null;
     return result;
 }
Пример #23
0
 public static ApiParameter GetParameterDescription(ISymbol symbol, MetadataItem item, string id, bool isReturn, ITripleSlashCommentParserContext context)
 {
     string comment = isReturn ? item.CommentModel?.Returns : item.CommentModel?.GetParameter(symbol.Name);
     return new ApiParameter
     {
         Name = isReturn ? null : symbol.Name,
         Type = id,
         Description = comment,
     };
 }
Пример #24
0
 /// <summary>
 /// To get `seealso` tags out
 /// </summary>
 /// <param name="xml"></param>
 /// <param name="context"></param>
 /// <returns></returns>
 /// <seealso cref="WaitForChangedResult"/>
 /// <seealso cref="http://google.com">ABCS</seealso>
 private List<LinkInfo> GetSeeAlsos(XPathNavigator nav, ITripleSlashCommentParserContext context)
 {
     var result = GetMultipleLinkInfo(nav, "/member/seealso").ToList();
     if (result.Count == 0) return null;
     return result;
 }
Пример #25
0
 /// <summary>
 /// Get summary node out from triple slash comments
 /// </summary>
 /// <param name="xml"></param>
 /// <param name="normalize"></param>
 /// <returns></returns>
 /// <example>
 /// <code> <see cref="Hello"/></code>
 /// </example>
 private string GetSummary(XPathNavigator nav, ITripleSlashCommentParserContext context)
 {
     // Resolve <see cref> to @ syntax
     // Also support <seealso cref>
     string selector = "/member/summary";
     return GetSingleNodeValue(nav, selector);
 }
Пример #26
0
        private Dictionary <string, string> GetListContent(XPathNavigator navigator, string xpath, string contentType, ITripleSlashCommentParserContext context)
        {
            var iterator = navigator.Select(xpath);
            var result   = new Dictionary <string, string>();

            if (iterator == null)
            {
                return(result);
            }
            foreach (XPathNavigator nav in iterator)
            {
                string name        = nav.GetAttribute("name", string.Empty);
                string description = GetXmlValue(nav);
                if (!string.IsNullOrEmpty(name))
                {
                    if (result.ContainsKey(name))
                    {
                        string path = context.Source.Remote != null?Path.Combine(EnvironmentContext.BaseDirectory, context.Source.Remote.RelativePath) : context.Source.Path;

                        Logger.LogWarning($"Duplicate {contentType} '{name}' found in comments, the latter one is ignored.", null, StringExtension.ToDisplayPath(path), context.Source.StartLine.ToString());
                    }
                    else
                    {
                        result.Add(name, description);
                    }
                }
            }

            return(result);
        }
Пример #27
0
 public static ApiParameter GetTypeParameterDescription(ITypeParameterSymbol symbol, MetadataItem item, ITripleSlashCommentParserContext context)
 {
     string comment = item.CommentModel?.GetTypeParameter(symbol.Name);
     return new ApiParameter
     {
         Name = symbol.Name,
         Description = comment,
     };
 }
Пример #28
0
 /// <summary>
 /// Get remarks node out from triple slash comments
 /// </summary>
 /// <remarks>
 /// <para>This is a sample of exception node</para>
 /// </remarks>
 /// <param name="xml"></param>
 /// <param name="normalize"></param>
 /// <returns></returns>
 private static string GetRemarks(XPathNavigator nav, ITripleSlashCommentParserContext context)
 {
     string selector = "/member/remarks";
     return GetSingleNodeValue(nav, selector, context.Normalize);
 }
Пример #29
0
        /// <summary>
        /// Get remarks node out from triple slash comments
        /// </summary>
        /// <remarks>
        /// <para>This is a sample of exception node</para>
        /// </remarks>
        /// <param name="xml"></param>
        /// <param name="normalize"></param>
        /// <returns></returns>
        private string GetRemarks(XPathNavigator nav, ITripleSlashCommentParserContext context)
        {
            string selector = "/member/remarks";

            return(GetSingleNodeValue(nav, selector));
        }
Пример #30
0
 private static string GetReturns(XPathNavigator nav, ITripleSlashCommentParserContext context)
 {
     // Resolve <see cref> to @ syntax
     // Also support <seealso cref>
     string selector = "/member/returns";
     return GetSingleNodeValue(nav, selector, context.Normalize);
 }
Пример #31
0
        public static ApiParameter GetParameterDescription(ISymbol symbol, MetadataItem item, string id, bool isReturn, ITripleSlashCommentParserContext context)
        {
            string comment = isReturn ? item.CommentModel?.Returns : item.CommentModel?.GetParameter(symbol.Name);

            return(new ApiParameter
            {
                Name = isReturn ? null : symbol.Name,
                Type = id,
                Description = comment,
            });
        }
Пример #32
0
        public static Dictionary<string, string> GetTypeParameters(XPathNavigator navigator, ITripleSlashCommentParserContext context)
        {
            var iterator = navigator.Select("/member/typeparam");
            var result = new Dictionary<string, string>();
            if (iterator == null) return result;
            foreach (XPathNavigator nav in iterator)
            {
                string name = nav.GetAttribute("name", string.Empty);
                string description = nav.Value;
                if (context.Normalize) description = NormalizeContentFromTripleSlashComment(description);
                if (!string.IsNullOrEmpty(name)) result.Add(name, description);
            }

            return result;
        }
Пример #33
0
 /// <summary>
 /// To get `example` tags out
 /// </summary>
 /// <param name="xml"></param>
 /// <param name="context"></param>
 /// <returns></returns>
 /// <example>
 /// This sample shows how to call the <see cref="GetExceptions(string, ITripleSlashCommentParserContext)"/> method.
 /// <code>
 /// class TestClass
 /// {
 ///     static int Main()
 ///     {
 ///         return GetExceptions(null, null).Count();
 ///     }
 /// }
 /// </code>
 /// </example>
 private List <string> GetExamples(XPathNavigator nav, ITripleSlashCommentParserContext context)
 {
     // Resolve <see cref> to @ syntax
     // Also support <seealso cref>
     return(GetMultipleExampleNodes(nav, "/member/example").ToList());
 }
Пример #34
0
        public static ApiParameter GetTypeParameterDescription(ITypeParameterSymbol symbol, MetadataItem item, ITripleSlashCommentParserContext context)
        {
            string comment = item.CommentModel?.GetTypeParameter(symbol.Name);

            return(new ApiParameter
            {
                Name = symbol.Name,
                Description = comment,
            });
        }
Пример #35
0
 private Dictionary <string, string> GetTypeParameters(XPathNavigator navigator, ITripleSlashCommentParserContext context)
 {
     return(GetListContent(navigator, "/member/typeparam", "type parameter", context));
 }
        public static Dictionary <string, string> GetTypeParameters(XPathNavigator navigator, ITripleSlashCommentParserContext context)
        {
            var iterator = navigator.Select("/member/typeparam");
            var result   = new Dictionary <string, string>();

            if (iterator == null)
            {
                return(result);
            }
            foreach (XPathNavigator nav in iterator)
            {
                string name        = nav.GetAttribute("name", string.Empty);
                string description = nav.Value;
                if (context.Normalize)
                {
                    description = NormalizeContentFromTripleSlashComment(description);
                }
                if (!string.IsNullOrEmpty(name))
                {
                    result.Add(name, description);
                }
            }

            return(result);
        }