private static void Diff(string caption, SlashdocDictionary left, SlashdocDictionary right) { foreach (var key in left.Keys) { if (!right.ContainsKey(key)) { Console.WriteLine(string.Format("{0}: {1}", caption, key)); } } }
private void Run() { try { if (OutputPath != null) { if (!Directory.Exists(OutputPath)) { Directory.CreateDirectory(OutputPath); } } using (var assembly = new AssemblyReflector(AssemblyFileName, _logger)) { var publicApiReferenceFileName = Path.GetFileNameWithoutExtension(AssemblyFileName) + ".html"; var publicApiSlashdocFileName = Path.GetFileNameWithoutExtension(AssemblyFileName) + ".xml"; if (OutputPath != null) { publicApiReferenceFileName = Path.Combine(OutputPath, publicApiReferenceFileName); publicApiSlashdocFileName = Path.Combine(OutputPath, publicApiSlashdocFileName); } var slashdocFileName = Path.ChangeExtension(AssemblyFileName, ".xml"); var slashdoc = new SlashdocDictionary(); if (File.Exists(slashdocFileName)) { using (var slashdocStream = new FileStream(slashdocFileName, FileMode.Open, FileAccess.Read)) { SlashdocProcessor.WritePublicApiSlashdoc(assembly, slashdocStream, publicApiSlashdocFileName); } using (var slashdocStream = new FileStream(slashdocFileName, FileMode.Open, FileAccess.Read)) { slashdoc = SlashdocReader.Parse(slashdocStream); } } else { _logger.LogWarning(string.Format(CultureInfo.InvariantCulture, "Could not open slashdoc file '{0}'.", slashdocFileName)); } var language = new CSharpSignatureProvider(); var title = string.Format(CultureInfo.InvariantCulture, "{0} public API reference", assembly.SimpleName); using (var apiReferenceWriter = new ApiReferenceHtmlWriter(publicApiReferenceFileName, title, slashdoc, language, _logger)) { apiReferenceWriter.EnableMissingSummaryWarnings = EnableMissingSummaryWarnings; apiReferenceWriter.DescribeAssembly(assembly); } } } catch (Exception ex) { _logger.LogError(ex.Message); } }
public static SlashdocDictionary Parse(Stream stream) { var slashdoc = new SlashdocDictionary(); var instance = new SlashdocReader(stream); instance.FoundAssemblyName += (x) => slashdoc.AssemblyName = x; instance.FoundMember += (x) => slashdoc.SetXmlDescription(x.Key, x.Value); instance.Parse(); return slashdoc; }
public static SlashdocDictionary Parse(Stream stream) { var slashdoc = new SlashdocDictionary(); var instance = new SlashdocReader(stream); instance.FoundAssemblyName += (x) => slashdoc.AssemblyName = x; instance.FoundMember += (x) => slashdoc.SetXmlDescription(x.Key, x.Value); instance.Parse(); return(slashdoc); }
public ApiReferenceHtmlWriter(Stream stream, bool closeStream, string title, SlashdocDictionary slashdoc, ILanguageSignatureProvider language, ILog logger) { if (slashdoc == null) { throw new ArgumentNullException("slashdoc"); } if (language == null) { throw new ArgumentNullException("language"); } if (logger == null) { throw new ArgumentNullException("logger"); } _slashdoc = slashdoc; _language = language; _logger = logger; var writerSettings = new XmlWriterSettings { CloseOutput = closeStream }; _writer = XmlWriter.Create(new StreamWriter(stream, new UTF8Encoding(false)), writerSettings); _writer.WriteStartDocument(); _writer.WriteDocType("html", "-//W3C//DTD XHTML 1.0 Strict//EN", "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd", null); _writer.WriteStartElement("html", "http://www.w3.org/1999/xhtml"); _writer.WriteStartElement("head"); WriteTextElement("title", title); _writer.WriteStartElement("style"); _writer.WriteAttributeString("type", "text/css"); WriteEmbeddedStyleSheet(); _writer.WriteEndElement(); // style _writer.WriteEndElement(); // head _writer.WriteStartElement("body"); }
public ApiReferenceHtmlWriter(string fileName, string title, SlashdocDictionary slashdoc, ILanguageSignatureProvider language, ILog logger) : this(new FileStream(fileName, FileMode.Create, FileAccess.Write), true, title, slashdoc, language, logger) { }
public void ShouldDescribeAGenericClass_CSharp() { var slashdoc = new SlashdocDictionary(); var stream = DescribeType(typeof(TestData.Xyz.Foo.TestGeneric<,>), slashdoc); var xmlReader = XmlReader.Create(stream, new XmlReaderSettings { DtdProcessing = DtdProcessing.Ignore }); var resolver = CreateHtmlNamespaceResolver(xmlReader); var navigator = CreateXPathNavigator(xmlReader); var node = navigator.SelectSingleNode("//html:div[@id='TestData.Xyz.Foo.TestGeneric<T, G>']", resolver); var content = GetNodeContent(node); Assert.That(content.Contains("<h2>TestGeneric<T, G> class</h2>"), "header"); }
private static Stream DescribeType(Type type, SlashdocDictionary slashdoc) { var stream = new MemoryStream(); var language = new CSharpSignatureProvider(); using (var writer = new ApiReferenceHtmlWriter(stream, false, "Xyz", slashdoc, language, new Mock<ILog>().Object)) { writer.DescribeType(type, new SlashdocSummaryHtmlFormatter(DummyAssembly, language)); } stream.Seek(0, SeekOrigin.Begin); return stream; }
public void ShouldDescribeAClassAndItsMembers_CSharp() { var slashdoc = new SlashdocDictionary(); slashdoc.SetXmlDescription("T:TestData.Xyz.Foo.TestClass", "<summary>Slashdoc summary for the TestClass class.</summary>"); slashdoc.SetXmlDescription("M:TestData.Xyz.Foo.TestClass.#ctor(System.String)", "<summary>[string ctor]</summary>"); slashdoc.SetXmlDescription("M:TestData.Xyz.Foo.TestClass.MethodReturningVoid", "<summary>[void method]</summary>"); slashdoc.SetXmlDescription("F:TestData.Xyz.Foo.TestClass.x", "<summary>[field]</summary>"); slashdoc.SetXmlDescription("E:TestData.Xyz.Foo.TestClass.AnEvent", "<summary>[event]</summary>"); var stream = DescribeType(typeof(TestData.Xyz.Foo.TestClass), slashdoc); //var reader = new StreamReader(stream); //Console.WriteLine(reader.ReadToEnd()); //stream.Seek(0, SeekOrigin.Begin); var xmlReader = XmlReader.Create(stream, new XmlReaderSettings { DtdProcessing = DtdProcessing.Ignore }); var resolver = CreateHtmlNamespaceResolver(xmlReader); var navigator = CreateXPathNavigator(xmlReader); // check type info var node = navigator.SelectSingleNode("//html:div[@id='TestData.Xyz.Foo.TestClass']", resolver); var content = GetNodeContent(node); Assert.That(content.Contains("<h2>TestClass class</h2>"), "header"); Assert.That(content.Contains("Slashdoc summary for the TestClass class."), "slashdoc summary"); Assert.That(content.Contains("TestData.Xyz.Foo"), "namespace"); Assert.That(content.Contains("class TestClass : System.ICloneable")); // constructors content = GetSingleNodeContent(".//html:table[.//html:th/text()='Constructors']", node, resolver); Assert.That(content.Contains("<td>TestClass(string xyz)</td>"), "constructor signature"); Assert.That(content.Contains("[string ctor]"), "constructor slashdoc"); Assert.That(!content.Contains("public"), "The public access modifier is assumed and therefore not included"); // properties content = GetSingleNodeContent(".//html:table[.//html:th/text()='Properties']", node, resolver); Assert.That(content.Contains("<td>int ReadOnlyProperty { get; }</td>"), "read-only property"); Assert.That(content.Contains("<td>int ReadWriteProperty { get; set; }</td>"), "read/write property"); Assert.That(!content.Contains("InternalProperty"), "Non-public property isn't included."); // methods content = GetSingleNodeContent(".//html:table[.//html:th/text()='Methods']", node, resolver); Assert.That(content.Contains("<td>object Clone()</td>"), "method signature"); Assert.That(content.Contains("<td>void MethodReturningVoid()</td>"), "MethodReturningVoid"); Assert.That(content.Contains("[void method]"), "method slashdoc"); Assert.That(!content.Contains("~TestClass") && !content.Contains("Finalize()"), "The finalizer shall not appear as a method."); Assert.That(!content.Contains("GetType()"), "Trivial methods shall be removed."); // operators content = GetSingleNodeContent(".//html:table[.//html:th/text()='Operators']", node, resolver); Assert.That(content.Contains("<td>static TestClass operator !(TestClass t)</td>"), "method signature"); // fields (including constants) content = GetSingleNodeContent(".//html:table[.//html:th/text()='Fields']", node, resolver); Assert.That(content.Contains("<td>int x</td>"), "field signature, x"); Assert.That(content.Contains("<td>const bool y</td>"), "field signature, y"); Assert.That(content.Contains("[field]"), "field slashdoc"); // events content = GetSingleNodeContent(".//html:table[.//html:th/text()='Events']", node, resolver); Assert.That(content.Contains("<td>static event System.EventHandler AnEvent</td>"), "event signature"); Assert.That(content.Contains("[event]"), "event slashdoc"); }
public void ShouldXmlEscapeSlashdocSummaries() { var slashdoc = new SlashdocDictionary(); slashdoc.SetXmlDescription("T:TestData.Xyz.Foo.ITest", "<summary><<Hello>></summary>"); var stream = DescribeType(typeof(TestData.Xyz.Foo.ITest), slashdoc); var xmlReader = XmlReader.Create(stream, new XmlReaderSettings { DtdProcessing = DtdProcessing.Ignore }); var resolver = CreateHtmlNamespaceResolver(xmlReader); var navigator = CreateXPathNavigator(xmlReader); var content = GetSingleNodeContent("//html:div[@id='TestData.Xyz.Foo.ITest']", navigator, resolver); Assert.That(content.Contains("<<Hello>>"), "slashdoc summary"); }
public void ShouldNotIncludeTrivialMethods() { var slashdoc = new SlashdocDictionary(); var stream = DescribeType(typeof(TestData.Xyz.Foo.PublicTestClass), slashdoc); var xmlReader = XmlReader.Create(stream, new XmlReaderSettings { DtdProcessing = DtdProcessing.Ignore }); var resolver = CreateHtmlNamespaceResolver(xmlReader); var navigator = CreateXPathNavigator(xmlReader); var node = navigator.SelectSingleNode("//html:div[@id='TestData.Xyz.Foo.PublicTestClass']", resolver); var content = GetNodeContent(node); Assert.That(!content.Contains("ToString()"), "the 'trivial' ToString method shouldn't be listed in the API reference."); Assert.That(!content.Contains("Equals(object"), "the 'trivial' ToString method shouldn't be listed in the API reference."); Assert.That(!content.Contains("GetHashCode()"), "the 'trivial' ToString method shouldn't be listed in the API reference."); Assert.That(content.Contains("ToString(int x)"), "the non-trivial ToString(int) method should be listed in the API reference."); Assert.That(content.Contains("Equals(PublicTestClass"), "the non-trivial Equals(PublicTestClass) method should be listed in the API reference."); }
public void ShouldDescribeAStruct_CSharp() { var slashdoc = new SlashdocDictionary(); var stream = DescribeType(typeof(TestData.Xyz.Foo.TestStruct), slashdoc); var xmlReader = XmlReader.Create(stream, new XmlReaderSettings { DtdProcessing = DtdProcessing.Ignore }); var resolver = CreateHtmlNamespaceResolver(xmlReader); var navigator = CreateXPathNavigator(xmlReader); var node = navigator.SelectSingleNode("//html:div[@id='TestData.Xyz.Foo.TestStruct']", resolver); var content = GetNodeContent(node); Assert.That(content.Contains("<h2>TestStruct struct</h2>"), "header"); content = GetSingleNodeContent(".//html:table[.//html:th/text()='Events']", node, resolver); Assert.That(content.Contains("<td>event System.EventHandler PublicEvent</td>"), "event signature"); }
public void ShouldDescribeAnInterface_CSharp() { var slashdoc = new SlashdocDictionary(); slashdoc.SetXmlDescription("T:TestData.Xyz.Foo.ITest", "<summary>Slashdoc summary for the ITest interface.</summary>"); var stream = DescribeType(typeof(TestData.Xyz.Foo.ITest), slashdoc); var xmlReader = XmlReader.Create(stream, new XmlReaderSettings { DtdProcessing = DtdProcessing.Ignore }); var resolver = CreateHtmlNamespaceResolver(xmlReader); var navigator = CreateXPathNavigator(xmlReader); var content = GetSingleNodeContent("//html:div[@id='TestData.Xyz.Foo.ITest']", navigator, resolver); Assert.That(content.Contains("<h2>ITest interface</h2>"), "header"); Assert.That(content.Contains("Slashdoc summary for the ITest interface."), "slashdoc summary"); }
public void ShouldDescribeANestedClass_CSharp() { var slashdoc = new SlashdocDictionary(); var stream = DescribeType(typeof(TestData.Xyz.Foo.TestClass.NestedClass), slashdoc); var xmlReader = XmlReader.Create(stream, new XmlReaderSettings { DtdProcessing = DtdProcessing.Ignore }); var resolver = CreateHtmlNamespaceResolver(xmlReader); var navigator = CreateXPathNavigator(xmlReader); var content = GetSingleNodeContent("//html:div[@id='TestData.Xyz.Foo.TestClass.NestedClass']", navigator, resolver); Assert.That(content.Contains("<h2>TestClass.NestedClass class</h2>"), "header"); Assert.That(content.Contains("TestData.Xyz.Foo"), "namespace"); Assert.That(content.Contains("class TestClass.NestedClass"), "NestedClass signature"); }
public void ShouldDescribeAnEnum_CSharp() { var slashdoc = new SlashdocDictionary(); slashdoc.SetXmlDescription("F:TestData.Xyz.Foo.TestEnum.One", "<summary>[enum One]</summary>"); var stream = DescribeType(typeof(TestData.Xyz.Foo.TestEnum), slashdoc); var xmlReader = XmlReader.Create(stream, new XmlReaderSettings { DtdProcessing = DtdProcessing.Ignore }); var resolver = CreateHtmlNamespaceResolver(xmlReader); var navigator = CreateXPathNavigator(xmlReader); var node = navigator.SelectSingleNode("//html:div[@id='TestData.Xyz.Foo.TestEnum']", resolver); var content = GetNodeContent(node); Assert.That(content.Contains("<h2>TestEnum enum</h2>"), "header"); content = GetSingleNodeContent(".//html:table[.//html:th/text()='Members']", node, resolver); Assert.That(content.Contains("<td>One</td>"), "member signature"); Assert.That(content.Contains("<td>[enum One]</td>"), "member slashdoc"); }