public void TestTripleSlashParserForXamlSource() { string inputFolder = Path.GetRandomFileName(); Directory.CreateDirectory(inputFolder); var expectedExampleContent = @" <Grid> <TextBlock Text=""Hello World"" /> </Grid>"; File.WriteAllText(Path.Combine(inputFolder, "Example.xaml"), $@" <UserControl x:Class=""Examples"" xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"" xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml"" xmlns:mc=""http://schemas.openxmlformats.org/markup-compatibility/2006"" xmlns:d=""http://schemas.microsoft.com/expression/blend/2008"" mc: Ignorable = ""d"" d:DesignHeight=""300"" d:DesignWidth=""300"" > <UserControl.Resources> <!-- <Example> --> {expectedExampleContent} <!-- </Example> --> "); string input = @" <member name='T:TestClass1.Partial1'> <summary> </summary> <returns>Something</returns> <example> This is an example using source reference in a xaml file. <code source='Example.xaml' region='Example'/> </example> </member>"; var context = new TripleSlashCommentParserContext { AddReferenceDelegate = null, PreserveRawInlineComments = false, Source = new SourceDetail() { Path = Path.Combine(inputFolder, "Source.cs"), } }; var commentModel = TripleSlashCommentModel.CreateModel(input, SyntaxLanguage.CSharp, context); // using xml to get rid of escaped tags var example = commentModel.Examples.Single(); var doc = XDocument.Parse($"<root>{example}</root>"); var codeNode = doc.Descendants("code").Single(); var actual = NormalizeWhitespace(codeNode.Value); var expected = NormalizeWhitespace(expectedExampleContent.Replace("\r\n", "\n")); Assert.Equal(expected, actual); }
public void InheritDoc() { const string input = @" <member name=""M:ClassLibrary1.MyClass.DoThing""> <inheritdoc /> </member>"; var context = new TripleSlashCommentParserContext { AddReferenceDelegate = null, PreserveRawInlineComments = false, }; var commentModel = TripleSlashCommentModel.CreateModel(input, SyntaxLanguage.CSharp, context); Assert.True(commentModel.IsInheritDoc); }
public static void AddComments(this MetadataItem item, TripleSlashCommentParserContext context) { if (string.IsNullOrEmpty(item.RawComment)) { return; } var commentModel = TripleSlashCommentModel.CreateModel(item.RawComment, 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.IsInheritDoc = commentModel.IsInheritDoc; item.CommentModel = commentModel; }
public void TestTripleSlashParser() { string input = @" <member name='T:TestClass1.Partial1'> <summary> Parital classes <see cref='T:System.AccessViolationException'/><see cref='T:System.AccessViolationException'/>can not cross assemblies, ``` Classes in assemblies are by definition complete. ``` </summary> <remarks> <para>This is <paramref name='ref'/> <paramref />a sample of exception node</para> </remarks> <returns>Task<see cref='T:System.AccessViolationException'/> returns</returns> <param name='input'>This is <see cref='T:System.AccessViolationException'/>the input</param> <param name = 'output' > This is the output </param > <exception cref='T:System.Xml.XmlException'>This is a sample of exception node</exception> <exception cref='System.Xml.XmlException'>This is a sample of exception node with invalid cref</exception> <exception cref=''>This is a sample of invalid exception node</exception> <exception >This is a sample of another invalid exception node</exception> <example> This sample shows how to call the <see cref=""M: Microsoft.DocAsCode.EntityModel.TripleSlashCommentParser.GetExceptions(System.String, Microsoft.DocAsCode.EntityModel.ITripleSlashCommentParserContext)""/> method. <code> class TestClass { static int Main() { return GetExceptions(null, null).Count(); } } </code> </example> <example> This is another example </example> <see cref=""T:Microsoft.DocAsCode.EntityModel.SpecIdHelper""/> <see cref=""T:System.Diagnostics.SourceSwitch""/> <seealso cref=""T:System.IO.WaitForChangedResult""/> <seealso cref=""!:http://google.com"">ABCS</seealso> </member>"; var context = new TripleSlashCommentParserContext { AddReferenceDelegate = null, Normalize = true, PreserveRawInlineComments = false, }; var commentModel = TripleSlashCommentModel.CreateModel(input, context); var summary = commentModel.Summary; Assert.Equal(@" Parital classes <xref href=""System.AccessViolationException"" data-throw-if-not-resolved=""false""></xref><xref href=""System.AccessViolationException"" data-throw-if-not-resolved=""false""></xref>can not cross assemblies, ``` Classes in assemblies are by definition complete. ``` ", summary); var returns = commentModel.Returns; Assert.Equal("Task<xref href=\"System.AccessViolationException\" data-throw-if-not-resolved=\"false\"></xref> returns", returns); var paramInput = commentModel.Parameters["input"]; Assert.Equal("This is <xref href=\"System.AccessViolationException\" data-throw-if-not-resolved=\"false\"></xref>the input", paramInput); var remarks = commentModel.Remarks; Assert.Equal(@" <para>This is *ref* a sample of exception node</para> ", remarks); var exceptions = commentModel.Exceptions; Assert.Equal(1, exceptions.Count); Assert.Equal("System.Xml.XmlException", exceptions[0].Type); Assert.Equal("This is a sample of exception node", exceptions[0].Description); var example = commentModel.Examples; var expected = new List <string> { @" This sample shows how to call the <see cref=""M: Microsoft.DocAsCode.EntityModel.TripleSlashCommentParser.GetExceptions(System.String, Microsoft.DocAsCode.EntityModel.ITripleSlashCommentParserContext)"" /> method. <code> class TestClass { static int Main() { return GetExceptions(null, null).Count(); } } </code> ", @" This is another example " }; Assert.Equal(expected, example); context.PreserveRawInlineComments = true; commentModel = TripleSlashCommentModel.CreateModel(input, context); var sees = commentModel.Sees; Assert.Equal(2, sees.Count); Assert.Equal("Microsoft.DocAsCode.EntityModel.SpecIdHelper", sees[0].Type); Assert.Null(sees[0].Description); var seeAlsos = commentModel.SeeAlsos; Assert.Equal(1, seeAlsos.Count); Assert.Equal("System.IO.WaitForChangedResult", seeAlsos[0].Type); Assert.Null(seeAlsos[0].Description); }
public void TestTripleSlashParser() { string input = @" <member name='T:TestClass1.Partial1'> <summary> Parital classes <see cref='T:System.AccessViolationException'/><see cref='T:System.AccessViolationException'/>can not cross assemblies, Test <see langword='null'/> ``` Classes in assemblies are by definition complete. ``` </summary> <remarks> <see href=""https://example.org""/> <see href=""https://example.org"">example</see> <para>This is <paramref name='ref'/> <paramref />a sample of exception node</para> <list type='bullet'> <item> <description> <code language = 'c#'> public class XmlElement : XmlLinkedNode </code> <list type='number'> <item> <description> word inside list->listItem->list->listItem->para.> the second line. </description> </item> <item> <description>item2 in numbered list</description> </item> </list> </description> </item> <item> <description>item2 in bullet list</description> </item> </list> </remarks> <returns>Task<see cref='T:System.AccessViolationException'/> returns</returns> <param name='input'>This is <see cref='T:System.AccessViolationException'/>the input</param> <param name = 'output' > This is the output </param > <exception cref='T:System.Xml.XmlException'>This is a sample of exception node. Ref <see href=""http://exception.com"">Exception</see></exception> <exception cref='System.Xml.XmlException'>This is a sample of exception node with invalid cref</exception> <exception cref=''>This is a sample of invalid exception node</exception> <exception >This is a sample of another invalid exception node</exception> <example> This sample shows how to call the <see cref=""M: Microsoft.DocAsCode.EntityModel.TripleSlashCommentParser.GetExceptions(System.String, Microsoft.DocAsCode.EntityModel.ITripleSlashCommentParserContext)""/> method. <code> class TestClass { static int Main() { return GetExceptions(null, null).Count(); } } </code> </example> <example> This is another example </example> <example> Check empty code. <code></code> </example> <see cref=""T:Microsoft.DocAsCode.EntityModel.SpecIdHelper""/> <see cref=""T:System.Diagnostics.SourceSwitch""/> <see cref=""Overload:System.String.Compare""/> <see href=""http://exception.com"">Global See section</see> <see href=""http://exception.com""/> <seealso cref=""T:System.IO.WaitForChangedResult""/> <seealso cref=""!:http://google.com"">ABCS</seealso> <seealso href=""http://www.bing.com"">Hello Bing</seealso> <seealso href=""http://www.bing.com""/> </member>"; var context = new TripleSlashCommentParserContext { AddReferenceDelegate = null, PreserveRawInlineComments = false, }; var commentModel = TripleSlashCommentModel.CreateModel(input, SyntaxLanguage.CSharp, context); Assert.False(commentModel.IsInheritDoc, nameof(commentModel.IsInheritDoc)); var summary = commentModel.Summary; Assert.Equal(@" Parital classes <xref href=""System.AccessViolationException"" data-throw-if-not-resolved=""false""></xref><xref href=""System.AccessViolationException"" data-throw-if-not-resolved=""false""></xref>can not cross assemblies, Test <xref uid=""langword_csharp_null"" name=""null"" href=""""></xref> ``` Classes in assemblies are by definition complete. ``` ".Replace("\r\n", "\n"), summary); var returns = commentModel.Returns; Assert.Equal("Task<xref href=\"System.AccessViolationException\" data-throw-if-not-resolved=\"false\"></xref> returns", returns); var paramInput = commentModel.Parameters["input"]; Assert.Equal("This is <xref href=\"System.AccessViolationException\" data-throw-if-not-resolved=\"false\"></xref>the input", paramInput); var remarks = commentModel.Remarks; Assert.Equal(@" <a href=""https://example.org"">https://example.org</a> <a href=""https://example.org"">example</a> <p>This is <span class=""paramref"">ref</span> a sample of exception node</p> <ul><li> <pre><code class=""c#"">public class XmlElement : XmlLinkedNode</code></pre> <ol><li> word inside list->listItem->list->listItem->para.> the second line. </li><li>item2 in numbered list</li></ol> </li><li>item2 in bullet list</li></ul> ".Replace("\r\n", "\n"), remarks); var exceptions = commentModel.Exceptions; Assert.Equal(1, exceptions.Count); Assert.Equal("System.Xml.XmlException", exceptions[0].Type); Assert.Equal(@"This is a sample of exception node. Ref <a href=""http://exception.com"">Exception</a>", exceptions[0].Description); var example = commentModel.Examples; var expected = new List <string> { @" This sample shows how to call the <see cref=""M: Microsoft.DocAsCode.EntityModel.TripleSlashCommentParser.GetExceptions(System.String, Microsoft.DocAsCode.EntityModel.ITripleSlashCommentParserContext)""></see> method. <pre><code>class TestClass { static int Main() { return GetExceptions(null, null).Count(); } } </code></pre> ".Replace("\r\n", "\n"), @" This is another example ".Replace("\r\n", "\n"), @" Check empty code. <pre><code></code></pre> ".Replace("\r\n", "\n") }; Assert.Equal(expected, example); context.PreserveRawInlineComments = true; commentModel = TripleSlashCommentModel.CreateModel(input, SyntaxLanguage.CSharp, context); var sees = commentModel.Sees; Assert.Equal(5, sees.Count); Assert.Equal("Microsoft.DocAsCode.EntityModel.SpecIdHelper", sees[0].LinkId); Assert.Null(sees[0].AltText); Assert.Equal("System.String.Compare*", sees[2].LinkId); Assert.Null(sees[1].AltText); Assert.Equal("http://exception.com", sees[3].LinkId); Assert.Equal("Global See section", sees[3].AltText); Assert.Equal("http://exception.com", sees[4].AltText); Assert.Equal("http://exception.com", sees[4].LinkId); var seeAlsos = commentModel.SeeAlsos; Assert.Equal(3, seeAlsos.Count); Assert.Equal("System.IO.WaitForChangedResult", seeAlsos[0].LinkId); Assert.Null(seeAlsos[0].AltText); Assert.Equal("http://www.bing.com", seeAlsos[1].LinkId); Assert.Equal("Hello Bing", seeAlsos[1].AltText); Assert.Equal("http://www.bing.com", seeAlsos[2].AltText); Assert.Equal("http://www.bing.com", seeAlsos[2].LinkId); }
private void PatchViewModel(ItemViewModel item, string comment) { var commentModel = TripleSlashCommentModel.CreateModel(comment, TripleSlashCommentParserContext.Instance); var summary = commentModel.Summary; if (!string.IsNullOrEmpty(summary)) { item.Summary = summary; } var remarks = commentModel.Remarks; if (!string.IsNullOrEmpty(remarks)) { item.Remarks = remarks; } var exceptions = commentModel.Exceptions; if (exceptions != null && exceptions.Count > 0) { item.Exceptions = exceptions; } var sees = commentModel.Sees; if (sees != null && sees.Count > 0) { item.Sees = sees; } var seeAlsos = commentModel.SeeAlsos; if (seeAlsos != null && seeAlsos.Count > 0) { item.SeeAlsos = seeAlsos; } var examples = commentModel.Examples; if (examples != null && examples.Count > 0) { item.Examples = examples; } if (item.Syntax != null) { if (item.Syntax.Parameters != null) { foreach (var p in item.Syntax.Parameters) { var description = commentModel.GetParameter(p.Name); if (!string.IsNullOrEmpty(description)) { p.Description = description; } } } if (item.Syntax.TypeParameters != null) { foreach (var p in item.Syntax.TypeParameters) { var description = commentModel.GetTypeParameter(p.Name); if (!string.IsNullOrEmpty(description)) { p.Description = description; } } } if (item.Syntax.Return != null) { var returns = commentModel.Returns; if (!string.IsNullOrEmpty(returns)) { item.Syntax.Return.Description = returns; } } } // todo more. }