diff --git a/src/Doki.Abstractions/CodeBlock.cs b/src/Doki.Abstractions/CodeBlock.cs index 14628d7..50ebdab 100644 --- a/src/Doki.Abstractions/CodeBlock.cs +++ b/src/Doki.Abstractions/CodeBlock.cs @@ -8,12 +8,12 @@ public sealed record CodeBlock : DocumentationObject /// /// Gets the language of the code block. /// - public string? Language { get; internal init; } + public string? Language { get; init; } /// /// Gets the code of the block. /// - public string Code { get; internal init; } = null!; + public string Code { get; init; } = null!; public CodeBlock() { diff --git a/src/Doki.Abstractions/DocumentationObject.cs b/src/Doki.Abstractions/DocumentationObject.cs index 7f7ebea..c0a4490 100644 --- a/src/Doki.Abstractions/DocumentationObject.cs +++ b/src/Doki.Abstractions/DocumentationObject.cs @@ -15,7 +15,7 @@ public abstract record DocumentationObject /// /// Gets the ID of the documentation object. /// - public string Id { get; internal init; } = null!; + public string Id { get; init; } = null!; /// /// Gets the parent of the documentation object. diff --git a/src/Doki.Abstractions/TextContent.cs b/src/Doki.Abstractions/TextContent.cs index 1eec99a..9508cad 100644 --- a/src/Doki.Abstractions/TextContent.cs +++ b/src/Doki.Abstractions/TextContent.cs @@ -8,7 +8,7 @@ public sealed record TextContent : DocumentationObject /// /// Gets the text content. /// - public string Text { get; internal init; } = null!; + public string Text { get; init; } = null!; public TextContent() { diff --git a/src/Doki.Output.Json/JsonOutput.cs b/src/Doki.Output.Json/JsonOutput.cs index 1be73d9..1c1170a 100644 --- a/src/Doki.Output.Json/JsonOutput.cs +++ b/src/Doki.Output.Json/JsonOutput.cs @@ -4,11 +4,7 @@ namespace Doki.Output.Json; public sealed class JsonOutput(OutputOptions options) : IOutput { - private static readonly JsonSerializerOptions JsonSerializerOptions = new() - { - WriteIndented = true, - PropertyNamingPolicy = JsonNamingPolicy.CamelCase - }; + private static readonly JsonSerializerOptions JsonSerializerOptions = new(); public Task BeginAsync(CancellationToken cancellationToken = default) { diff --git a/src/Doki/DocumentationGenerator.Content.cs b/src/Doki/DocumentationGenerator.Content.cs index 2d21702..eb4074c 100644 --- a/src/Doki/DocumentationGenerator.Content.cs +++ b/src/Doki/DocumentationGenerator.Content.cs @@ -60,6 +60,10 @@ private IEnumerable BuildGenericTypeArgumentDo Parent = parent, }; + if (genericArgument.BaseType != null) + genericArgumentDocumentation.InternalBaseType = + BuildTypeDocumentationReference(genericArgument.BaseType, genericArgumentDocumentation); + if (description != null) genericArgumentDocumentation.Description = BuildXmlDocumentation(description, genericArgumentDocumentation); @@ -360,7 +364,7 @@ private TypeDocumentationReference BuildTypeDocumentationReference(Type type, Do var assembly = type.Assembly.GetName(); - return new TypeDocumentationReference + var typeDocumentationReference = new TypeDocumentationReference { Id = typeId, Name = type.GetSanitizedName(), @@ -373,5 +377,11 @@ private TypeDocumentationReference BuildTypeDocumentationReference(Type type, Do IsMicrosoft = IsAssemblyFromMicrosoft(assembly), Parent = parent }; + + if (type.BaseType != null) + typeDocumentationReference.InternalBaseType = + BuildTypeDocumentationReference(type.BaseType, typeDocumentationReference); + + return typeDocumentationReference; } } \ No newline at end of file diff --git a/src/Doki/DocumentationGenerator.cs b/src/Doki/DocumentationGenerator.cs index 93a4e07..665f84b 100644 --- a/src/Doki/DocumentationGenerator.cs +++ b/src/Doki/DocumentationGenerator.cs @@ -376,33 +376,9 @@ private async Task GenerateTypeDocumentationAsync(GeneratorCo typeDocumentation.InternalMethods = BuildMethodDocumentation(context.Current, typeDocumentation, assemblyXml, context.Logger).ToArray(); - var baseType = context.Current.BaseType; - TypeDocumentationReference baseParent = typeDocumentation; - while (baseType != null) - { - var baseTypeAssembly = baseType.Assembly.GetName(); - - var typeReference = new TypeDocumentationReference - { - Id = baseType.GetXmlDocumentationId(), - Parent = baseParent, - Name = baseType.GetSanitizedName(), - FullName = baseType.GetSanitizedName(true), - Namespace = baseType.Namespace, - Assembly = baseTypeAssembly.Name, - IsDocumented = IsTypeDocumented(baseType), - IsMicrosoft = IsAssemblyFromMicrosoft(baseTypeAssembly), - IsGeneric = baseType.IsGenericType - }; - - typeReference.InternalGenericArguments = - BuildGenericTypeArgumentDocumentation(baseType, typeReference, null, context.Logger).ToArray(); - - baseParent.InternalBaseType = typeReference; - - baseType = baseType.BaseType; - baseParent = typeReference; - } + if (context.Current.BaseType != null) + typeDocumentation.InternalBaseType = + BuildTypeDocumentationReference(context.Current.BaseType, typeDocumentation); foreach (var output in context.Outputs) { diff --git a/tests/Doki.Output.Json.Tests/JsonOutputTests.cs b/tests/Doki.Output.Json.Tests/JsonOutputTests.cs index 05f42a1..dfdcc80 100644 --- a/tests/Doki.Output.Json.Tests/JsonOutputTests.cs +++ b/tests/Doki.Output.Json.Tests/JsonOutputTests.cs @@ -51,7 +51,109 @@ public class ExampleClass : AbstractClass {} var documentation = JsonSerializer.Deserialize(json); Assert.NotNull(documentation); - - + Assert.Equal("Doki.TestAssembly.InheritanceChain.Abstractions.dll", documentation.FileName); + Assert.Equal("1.0.0.0", documentation.Version); + Assert.Null(documentation.PackageId); + Assert.Equal("Doki.TestAssembly.InheritanceChain.Abstractions", documentation.Name); + Assert.Null(documentation.Description); + Assert.Equal("Doki.TestAssembly.InheritanceChain.Abstractions", documentation.Id); + Assert.Equal(DocumentationContentType.Assembly, documentation.ContentType); + Assert.Collection(documentation.Namespaces, + namespaceDocumentation => + { + Assert.NotNull(namespaceDocumentation); + Assert.Equal("Doki.TestAssembly.InheritanceChain.Abstractions", namespaceDocumentation.Name); + Assert.Null(namespaceDocumentation.Description); + Assert.Equal("Doki.TestAssembly.InheritanceChain.Abstractions", namespaceDocumentation.Id); + Assert.Equal(DocumentationContentType.Namespace, namespaceDocumentation.ContentType); + Assert.Collection(namespaceDocumentation.Types, + typeDocumentation => + { + Assert.NotNull(typeDocumentation); + Assert.Equal("public abstract class AbstractClass", typeDocumentation.Definition); + Assert.Equal(DocumentationContentType.Class, typeDocumentation.ContentType); + Assert.False(typeDocumentation.IsGeneric); + Assert.Equal("Doki.TestAssembly.InheritanceChain.Abstractions.AbstractClass", + typeDocumentation.FullName); + Assert.True(typeDocumentation.IsDocumented); + Assert.False(typeDocumentation.IsMicrosoft); + Assert.Equal("AbstractClass", typeDocumentation.Name); + Assert.Equal("Doki.TestAssembly.InheritanceChain.Abstractions", typeDocumentation.Namespace); + Assert.Equal("Doki.TestAssembly.InheritanceChain.Abstractions", typeDocumentation.Assembly); + Assert.Equal("Doki.TestAssembly.InheritanceChain.Abstractions.AbstractClass", + typeDocumentation.Id); + Assert.Empty(typeDocumentation.Remarks); + Assert.Empty(typeDocumentation.Interfaces); + Assert.Empty(typeDocumentation.DerivedTypes); + Assert.Empty(typeDocumentation.Fields); + Assert.Empty(typeDocumentation.Properties); + Assert.Empty(typeDocumentation.Methods); + Assert.Empty(typeDocumentation.GenericArguments); + + Assert.NotNull(typeDocumentation.BaseType); + Assert.False(typeDocumentation.BaseType.IsGeneric); + Assert.Equal("System.Object", typeDocumentation.BaseType.FullName); + Assert.False(typeDocumentation.BaseType.IsDocumented); + Assert.True(typeDocumentation.BaseType.IsMicrosoft); + Assert.Null(typeDocumentation.BaseType.BaseType); + Assert.Empty(typeDocumentation.BaseType.GenericArguments); + Assert.Equal("Object", typeDocumentation.BaseType.Name); + Assert.Equal("System", typeDocumentation.BaseType.Namespace); + Assert.Equal("System.Private.CoreLib", typeDocumentation.BaseType.Assembly); + Assert.Null(typeDocumentation.BaseType.Summary); + Assert.Equal(DocumentationContentType.TypeReference, typeDocumentation.BaseType.ContentType); + Assert.Equal("System.Object", typeDocumentation.BaseType.Id); + + Assert.Collection(typeDocumentation.Constructors, + memberDocumentation => + { + Assert.NotNull(memberDocumentation); + Assert.Equal("AbstractClass()", memberDocumentation.Name); + Assert.Equal("Doki.TestAssembly.InheritanceChain.Abstractions", + memberDocumentation.Namespace); + Assert.Equal("Doki.TestAssembly.InheritanceChain.Abstractions", + memberDocumentation.Assembly); + Assert.Null(memberDocumentation.Summary); + Assert.Equal(DocumentationContentType.Constructor, memberDocumentation.ContentType); + Assert.Equal("Doki.TestAssembly.InheritanceChain.Abstractions.AbstractClass.#ctor", + memberDocumentation.Id); + }); + + Assert.NotNull(typeDocumentation.Summary); + Assert.Equal("summary", typeDocumentation.Summary.Name); + Assert.Equal("summary", typeDocumentation.Summary.Id); + Assert.Equal(DocumentationContentType.Xml, typeDocumentation.Summary.ContentType); + Assert.Collection(typeDocumentation.Summary.Contents, + documentationObject => + { + Assert.NotNull(documentationObject); + Assert.IsType(documentationObject); + var textContent = (TextContent)documentationObject; + Assert.Equal("This is an abstract class. See ", textContent.Text); + Assert.Equal(DocumentationContentType.Text, documentationObject.ContentType); + Assert.Equal("text", documentationObject.Id); + }, + documentationObject => + { + Assert.NotNull(documentationObject); + Assert.IsType(documentationObject); + var typeDocumentationReference = (TypeDocumentationReference)documentationObject; + Assert.False(typeDocumentationReference.IsGeneric); + Assert.Equal("Doki.TestAssembly.InheritanceChain.Abstractions.AbstractClass", + typeDocumentationReference.FullName); + Assert.True(typeDocumentationReference.IsDocumented); + Assert.False(typeDocumentationReference.IsMicrosoft); + }, + documentationObject => + { + Assert.NotNull(documentationObject); + Assert.IsType(documentationObject); + var textContent = (TextContent)documentationObject; + Assert.Equal("for more information.", textContent.Text); + Assert.Equal(DocumentationContentType.Text, documentationObject.ContentType); + Assert.Equal("text", documentationObject.Id); + }); + }); + }); } } \ No newline at end of file