Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Docs: ApiDocsGenerator for API documentation from XML comments #5846

Merged
merged 87 commits into from
Dec 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
87 commits
Select commit Hold shift + click to select a range
efbb71b
ApiDocsGenerator
tesar-tech Nov 14, 2024
ed724e1
Adding simple logger that emits logs into cs file.
tesar-tech Nov 16, 2024
8e4a909
Handles default values.
tesar-tech Nov 16, 2024
4a0b5b1
adds README.md
tesar-tech Nov 16, 2024
25d21ac
Enum values are part of the comment.
tesar-tech Nov 16, 2024
d60850c
Handling multiple components in one docs page
tesar-tech Nov 16, 2024
4dda3d6
small edits
tesar-tech Nov 18, 2024
2bfb0cb
Parametrize the Name -> column in table for API
tesar-tech Nov 19, 2024
28b2466
Methods for APIdocs done!
tesar-tech Nov 19, 2024
0bc4e91
Styling adjustments
stsrki Nov 20, 2024
c4bcaa4
Fix docs api structure
stsrki Nov 20, 2024
4ae8b2f
Use shared generator settings
stsrki Nov 20, 2024
9f1e796
Move apidocs dtos to own project.
tesar-tech Nov 20, 2024
d8b0421
Merge remote-tracking branch 'origin/sup/rel-1.7/xml-comments-autogen…
tesar-tech Nov 20, 2024
9574588
Adds typeName for components (mainly bcs of generics).
tesar-tech Nov 20, 2024
58113e6
Generator also includes generic types (e.g. BaseTextInput<TValue>)
tesar-tech Nov 20, 2024
6892987
Properties and method from inheritance chain. Making it work with ext…
tesar-tech Nov 22, 2024
0b19fc6
inheritdocs, "should only be used internally"
tesar-tech Nov 24, 2024
09ec166
Merge branch 'rel-1.7' into sup/rel-1.7/xml-comments-autogen
stsrki Nov 25, 2024
b7d8d5d
Add ApiDocsDtos to solution
stsrki Nov 25, 2024
edfba60
Don't show empty parameters
stsrki Nov 25, 2024
842ba24
checked some of the docs pages
tesar-tech Nov 25, 2024
4f4fbef
prepare to be checked
tesar-tech Nov 25, 2024
792873a
xml comment improvements
tesar-tech Nov 25, 2024
61c5cf3
Update apidocsGenerator with Remarks and `<c>` support
tesar-tech Nov 25, 2024
5d7a49a
Formating
stsrki Nov 26, 2024
18561fb
Improve BaseComponent comments
stsrki Nov 26, 2024
85a51a9
markup string on remarks
tesar-tech Nov 26, 2024
4bd7901
Merge remote-tracking branch 'origin/sup/rel-1.7/xml-comments-autogen…
tesar-tech Nov 26, 2024
1f65bcf
Better Should only be used internally message
stsrki Nov 26, 2024
0edd84c
Merge branch 'sup/rel-1.7/xml-comments-autogen' of https://github.com…
stsrki Nov 26, 2024
6e053a1
Improve Field comments
stsrki Nov 26, 2024
287cbae
Adds Events to the apidocs.
tesar-tech Nov 26, 2024
e12d8f1
Replaces base component type name inside description or remarks with …
tesar-tech Nov 26, 2024
dc1fdb3
Rename "description" to "summary".
tesar-tech Nov 26, 2024
49d4325
removes dead code
tesar-tech Nov 26, 2024
4d7161e
typo fix
stsrki Nov 27, 2024
4d89dc2
support for <seealso (links in xml comments), fixes generic param in …
tesar-tech Nov 27, 2024
4db34fd
(D-V) new api docs on several components
tesar-tech Nov 27, 2024
775bf0b
BreadcrumbItem comment
stsrki Nov 28, 2024
0735478
format
stsrki Nov 28, 2024
2231d38
see instead of seealso
stsrki Nov 28, 2024
4b733ca
Render content of see tag.
stsrki Nov 28, 2024
4d1e4ad
cleanups
tesar-tech Nov 28, 2024
a5a402c
removes redundant type (on enums and enum like types)
tesar-tech Nov 28, 2024
4ea62c6
Blazorise constants with numeric values. Fix for enums from different…
tesar-tech Nov 28, 2024
316c6ee
Dont include DocsApiSourceGenerator to nuget
tesar-tech Nov 29, 2024
6f194c8
include fody. Blazorise dll cleanup works
tesar-tech Nov 29, 2024
489cbcb
ApiDocsGenerator and Dtos to existing Generators and Features projects;
tesar-tech Nov 30, 2024
17492fa
namespaces refactoring, small improvements
tesar-tech Nov 30, 2024
6383432
fixing for linux
tesar-tech Nov 30, 2024
16b65c0
Format csproj files
stsrki Dec 2, 2024
1216530
format md files
stsrki Dec 2, 2024
a074bce
Readme update
tesar-tech Dec 2, 2024
a561370
Merge remote-tracking branch 'origin/sup/rel-1.7/xml-comments-autogen…
tesar-tech Dec 2, 2024
16cc6b2
remove IsPack, includes EnableApiDocsGenerator.
tesar-tech Dec 2, 2024
ce2470f
Converts [Generator] into analyzer that generates source files; Remov…
tesar-tech Dec 5, 2024
9e68761
format csproj
stsrki Dec 6, 2024
0d18a53
clean, format, and reorganize
stsrki Dec 6, 2024
98fec92
Formating
stsrki Dec 6, 2024
117086c
load only current assembly
stsrki Dec 6, 2024
aba7201
Fix for generic in dictionary.
tesar-tech Dec 6, 2024
429afea
fix for component inheritance (up to IComponent)
tesar-tech Dec 6, 2024
d487c7a
fix from constant from complex type
tesar-tech Dec 6, 2024
0b7d735
Animate fix + docs
tesar-tech Dec 6, 2024
8338c55
removes Logger.cs
tesar-tech Dec 6, 2024
94eae34
Cleanups in ComponentApiDocs.razor. - review fixes.
tesar-tech Dec 6, 2024
ec007f6
Fix for retrieving xml comments from Microsoft.AspnetCore.Components …
tesar-tech Dec 7, 2024
48a65ac
fix for !: inside the cref type
tesar-tech Dec 7, 2024
2771f5f
System.Runtime attempt; Default value to remove global::
tesar-tech Dec 7, 2024
ca653bf
Extensions with new ApiDocs in place (also still with the old api for…
tesar-tech Dec 7, 2024
12ebf48
fixing local index
tesar-tech Dec 7, 2024
f80b548
Add missing comments
stsrki Dec 9, 2024
6d30ea1
change local var name
stsrki Dec 9, 2024
e2f0f37
More fixed comments
stsrki Dec 9, 2024
e474293
Skip internal components
stsrki Dec 9, 2024
564d56f
Don't show enum values of enum has more than 30 values
stsrki Dec 9, 2024
2e0fcfe
Remove DataGrid SG API for now
stsrki Dec 9, 2024
55a57d8
Remove old apis
stsrki Dec 9, 2024
ab87eb8
Remove old snackbar apis
stsrki Dec 9, 2024
39dffc2
Quick fix to not show Dispose method
stsrki Dec 9, 2024
7025b34
Fix comments
stsrki Dec 9, 2024
b58f17a
support for generic type "rename".
tesar-tech Dec 9, 2024
4a912e2
rm assembly name inside defualt value string (Vide.SettingsList)
tesar-tech Dec 9, 2024
5fc5725
Unified place for type qualified for apidocs; support for other types…
tesar-tech Dec 9, 2024
f859294
Format
stsrki Dec 10, 2024
718bc43
Cropper
stsrki Dec 10, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -273,3 +273,9 @@ Documentation/Blazorise.Docs.Server/wwwroot/img/blog/.DS_Store

# Source Generation directory
__SOURCEGENERATED__/

# Fody
/Source/Blazorise/FodyWeavers.xsd

# "source generator" for api docs
Documentation/Blazorise.Docs/ApiDocs
14 changes: 14 additions & 0 deletions Blazorise.sln
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Blazorise.Charts.Zoom", "So
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Blazorise.PdfViewer", "Source\Extensions\Blazorise.PdfViewer\Blazorise.PdfViewer.csproj", "{EAB7EC89-900A-4280-B24A-152B9DD2B503}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Blazorise.Weavers", "Source\SourceGenerators\Blazorise.Weavers\Blazorise.Weavers.csproj", "{BF5FFB8C-45AD-4875-BB01-2DA388890419}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Blazorise.Weavers.Fody", "Source\SourceGenerators\Blazorise.Weavers.Fody\Blazorise.Weavers.Fody.csproj", "{FFC4A285-1A16-4DD4-8B8C-141521E405B0}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -411,6 +415,14 @@ Global
{EAB7EC89-900A-4280-B24A-152B9DD2B503}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EAB7EC89-900A-4280-B24A-152B9DD2B503}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EAB7EC89-900A-4280-B24A-152B9DD2B503}.Release|Any CPU.Build.0 = Release|Any CPU
{BF5FFB8C-45AD-4875-BB01-2DA388890419}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BF5FFB8C-45AD-4875-BB01-2DA388890419}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BF5FFB8C-45AD-4875-BB01-2DA388890419}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BF5FFB8C-45AD-4875-BB01-2DA388890419}.Release|Any CPU.Build.0 = Release|Any CPU
{FFC4A285-1A16-4DD4-8B8C-141521E405B0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FFC4A285-1A16-4DD4-8B8C-141521E405B0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FFC4A285-1A16-4DD4-8B8C-141521E405B0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FFC4A285-1A16-4DD4-8B8C-141521E405B0}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -481,6 +493,8 @@ Global
{2B4FD79A-42E2-4B81-828B-0799E4744ADA} = {9731051E-0AA7-411E-A76A-987854F034DA}
{045536EC-BD97-409D-BDF7-C148B7C5AAFC} = {9731051E-0AA7-411E-A76A-987854F034DA}
{EAB7EC89-900A-4280-B24A-152B9DD2B503} = {9731051E-0AA7-411E-A76A-987854F034DA}
{BF5FFB8C-45AD-4875-BB01-2DA388890419} = {0538DB67-B4F3-4D00-B969-D3874A52E405}
{FFC4A285-1A16-4DD4-8B8C-141521E405B0} = {0538DB67-B4F3-4D00-B969-D3874A52E405}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {205B3EA4-470F-45DA-911E-346AF7D0A9A5}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,310 @@
#region Using directives
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.IO;
using System.Linq;
using System.Reflection;
using Blazorise.Docs.Compiler.ApiDocsGenerator.Dtos;
using Blazorise.Docs.Compiler.ApiDocsGenerator.Extensions;
using Blazorise.Docs.Compiler.ApiDocsGenerator.Helpers;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
#endregion

namespace Blazorise.Docs.Compiler.ApiDocsGenerator;

public class ComponentsApiDocsGenerator
{
#region Members

private Assembly aspNetCoreComponentsAssembly;

private CSharpCompilation blazoriseCompilation;

private XmlDocumentationProvider aspnetCoreDocumentationProvider;


private Assembly systemRuntimeAssembly;
private XmlDocumentationProvider systemRuntimeDocumentationProvider;


const string ShouldOnlyBeUsedInternally = "This method is intended for internal framework use only and should not be called directly by user code";

#endregion

#region Constructors

public ComponentsApiDocsGenerator()
{
var aspnetCoreAssemblyName = typeof( Microsoft.AspNetCore.Components.ParameterAttribute ).Assembly.GetName().Name;
aspNetCoreComponentsAssembly = AppDomain.CurrentDomain
.GetAssemblies()
.FirstOrDefault( a => a.GetName().Name == aspnetCoreAssemblyName );

systemRuntimeAssembly = AppDomain.CurrentDomain
.GetAssemblies()
.FirstOrDefault( a => a.GetName().Name == "System.Runtime" );

if ( systemRuntimeAssembly is not null )
{
systemRuntimeDocumentationProvider = XmlDocumentationProvider.CreateFromFile( $"{Path.GetFullPath( "." )}/System.Runtime.xml" );
}
if ( aspNetCoreComponentsAssembly != null )
{
// Replace the .dll extension with .xml to get the documentation file path
string xmlDocumentationPath = Path.ChangeExtension( aspNetCoreComponentsAssembly.Location, ".xml" );
aspnetCoreDocumentationProvider = XmlDocumentationProvider.CreateFromFile( xmlDocumentationPath );
}
//get the blazorise compilation, it's needed for every extension.
blazoriseCompilation = GetCompilation( Paths.BlazoriseLibRoot, "Blazorise", true );
}

#endregion

#region Methods

public bool Execute()
{
if ( aspNetCoreComponentsAssembly is null )
{
Console.WriteLine( $"Error generating ApiDocs. Cannot find ASP.NET Core assembly." );
return false;
}
if ( blazoriseCompilation is null )
{
Console.WriteLine( $"Error generating ApiDocs. Cannot find Blazorise assembly." );
return false;
}
if ( !Directory.Exists( Paths.BlazoriseExtensionsRoot ) )
{
Console.WriteLine( $"Directory for extensions does not exist: {Paths.BlazoriseExtensionsRoot}" );
return false;
}

//directories where to load the source code from one by one
string[] inputLocations = [Paths.BlazoriseLibRoot, .. Directory.GetDirectories( Paths.BlazoriseExtensionsRoot )];

foreach ( var inputLocation in inputLocations )
{
string assemblyName = Path.GetFileName( inputLocation ); // Use directory name as assembly name

CSharpCompilation compilation = inputLocation.EndsWith( "Blazorise" )
? blazoriseCompilation // the case for getting components from Blazorise
: GetCompilation( inputLocation, assemblyName );

INamespaceSymbol namespaceToSearch = FindNamespace( compilation, assemblyName ); // e.g. Blazorise.Animate

IEnumerable<ComponentInfo> componentInfo = GetComponentsInfo( compilation, namespaceToSearch );
string sourceText = GenerateComponentsApiSource( compilation, [.. componentInfo], assemblyName );

if ( !Directory.Exists( Paths.ApiDocsPath ) ) // BlazoriseDocs.ApiDocs
Directory.CreateDirectory( Paths.ApiDocsPath );

string outputPath = Path.Join( Paths.ApiDocsPath, $"{assemblyName}.ApiDocs.cs" );

File.WriteAllText( outputPath, sourceText );
Console.WriteLine( $"API Docs generated for {assemblyName} at {outputPath}. {sourceText.Length} characters." );
}

return true;
}

//namespace are divided in chunks (Blazorise.Animate is under Blazorise...)
INamespaceSymbol FindNamespace( Compilation compilation, string namespaceName, INamespaceSymbol? namespaceToSearch = null )

Check warning on line 114 in Documentation/Blazorise.Docs.Compiler/ApiDocsGenerator/ComponentsApiDocsGenerator.cs

View workflow job for this annotation

GitHub Actions / build

The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.

Check warning on line 114 in Documentation/Blazorise.Docs.Compiler/ApiDocsGenerator/ComponentsApiDocsGenerator.cs

View workflow job for this annotation

GitHub Actions / build

The annotation for nullable reference types should only be used in code within a '#nullable' annotations context.
{
namespaceToSearch ??= compilation.GlobalNamespace
.GetNamespaceMembers()
.FirstOrDefault( ns => ns.Name == "Blazorise" );

if ( namespaceToSearch is null )
throw new Exception( $"Unable to find namespace {namespaceName}." );

if ( namespaceToSearch.ToDisplayString() == namespaceName )
return namespaceToSearch;

foreach ( var childNamespace in namespaceToSearch.GetNamespaceMembers() )
{
var result = FindNamespace( compilation, namespaceName, childNamespace );
if ( result != null )
return result;
}

return null;
}
private CSharpCompilation GetCompilation( string inputLocation, string assemblyName, bool isBlazoriseAssembly = false )
{
var sourceFiles = Directory.GetFiles( inputLocation, "*.cs", SearchOption.AllDirectories );

List<MetadataReference> references =
[
MetadataReference.CreateFromFile( systemRuntimeAssembly.Location, documentation:systemRuntimeDocumentationProvider ), // Microsoft.AspNetCore.Components
MetadataReference.CreateFromFile( aspNetCoreComponentsAssembly.Location, documentation:aspnetCoreDocumentationProvider ), // Microsoft.AspNetCore.Components
];
if ( !isBlazoriseAssembly ) //get Blazorise assembly as reference (for extensions)
references.Add( blazoriseCompilation.ToMetadataReference() );

var syntaxTrees = sourceFiles.Select( file => CSharpSyntaxTree.ParseText( File.ReadAllText( file ) ) );

var compilation = CSharpCompilation.Create(
assemblyName,
syntaxTrees,
references.ToImmutableArray(),
new CSharpCompilationOptions( OutputKind.DynamicallyLinkedLibrary )
);
return compilation;
}

private IEnumerable<ComponentInfo> GetComponentsInfo( Compilation compilation, INamespaceSymbol namespaceToSearch )
{
var baseComponentSymbol = compilation.GetTypeByMetadataName( "Blazorise.BaseComponent" );

foreach ( var type in namespaceToSearch.GetTypeMembers().OfType<INamedTypeSymbol>() )
{
var (qualifiesForApiDocs, inheritsFromChain, skipParamCheck) = QualifiesForApiDocs( type, baseComponentSymbol );
if ( !qualifiesForApiDocs )
continue;

// Retrieve properties
var parameterProperties = type.GetMembers()
.OfType<IPropertySymbol>()
.Where( p =>
p.DeclaredAccessibility == Accessibility.Public &&
( skipParamCheck || p.GetAttributes().Any( attr =>
attr.AttributeClass?.ToDisplayString() == "Microsoft.AspNetCore.Components.ParameterAttribute" ) ) &&
p.OverriddenProperty == null );

// Retrieve methods
var publicMethods = type.GetMembers()
.OfType<IMethodSymbol>()
.Where( m => m.DeclaredAccessibility == Accessibility.Public &&
!m.IsImplicitlyDeclared &&
m.MethodKind == MethodKind.Ordinary &&
m.OverriddenMethod == null );

yield return new ComponentInfo
(
Type: type,
PublicMethods: publicMethods,
Properties: parameterProperties,
InheritsFromChain: inheritsFromChain
);
}
}

/// <summary>
/// get the chain of inheritance to the BaseComponent or ComponentBase
/// Only return true if implements IComponent (that is the case for all BaseComponent and ComponentBase)
/// </summary>
/// <param name="type"></param>
/// <param name="baseType"></param>
/// <returns></returns>
private (bool qualifiesForApiDocs, IEnumerable<INamedTypeSymbol>, bool skipParamCheck) QualifiesForApiDocs( INamedTypeSymbol type,
INamedTypeSymbol baseType )
{

(bool continueProcessing, bool skipParamAndComponentCheck) = type switch
{
_ when type.TypeKind != TypeKind.Class || type.DeclaredAccessibility != Accessibility.Public => (false, false),
_ when type.Name.StartsWith( '_' ) => (false, false),
_ when type.Name.EndsWith( "Options" ) => (true, true),
_ when type.Name.EndsWith( "RouterTabsPageAttribute" ) => (true, true),
_ when !type.AllInterfaces.Any( i => i.Name == "IComponent" ) => (false, false),
_ => (true, false)
};

if ( !continueProcessing )
return (false, [], false);

List<INamedTypeSymbol> inheritsFromChain = [];
while ( type != null )
{
type = type.BaseType;
if ( type?.Name.Split( "." ).Last() == "ComponentBase" //for this to work, the inheritance (:ComponentBase) must be specified in .cs file.
|| SymbolEqualityComparer.Default.Equals( type, baseType )
)
return (true, inheritsFromChain, skipParamAndComponentCheck);
inheritsFromChain.Add( type );
}
return (true, [], skipParamAndComponentCheck);
}

private static string GenerateComponentsApiSource( Compilation compilation, ImmutableArray<ComponentInfo> components, string assemblyName )
{
IEnumerable<ApiDocsForComponent> componentsData = components.Select( component =>
{
string componentType = component.Type.ToStringWithGenerics();
string componentTypeName = StringHelpers.GetSimplifiedTypeName( component.Type );

var propertiesData = component.Properties.Select( property =>
InfoExtractor.GetPropertyDetails( compilation, property ) )
.Where( x => !x.Summary.Contains( ShouldOnlyBeUsedInternally ) );

var methodsData = component.PublicMethods.Select( InfoExtractor.GetMethodDetails )
.Where( x => !x.Summary.Contains( ShouldOnlyBeUsedInternally ) );

ApiDocsForComponent comp = new( type: componentType, typeName: componentTypeName,
properties: propertiesData, methods: methodsData,
inheritsFromChain: component.InheritsFromChain.Select( type => type.ToStringWithGenerics() ) );

return comp;
} );

return
$$"""
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Windows.Input;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components.Forms;
using Blazorise.Docs.Models.ApiDocsDtos;
using Blazorise.Charts;

namespace Blazorise.Docs.ApiDocs;

public class ComponentApiSource_ForNamespace_{{assemblyName.Replace( ".", "_" )}}:IComponentsApiDocsSource
{
public Dictionary<Type, ApiDocsForComponent> Components { get; } =
new Dictionary<Type, ApiDocsForComponent>
{
{{componentsData.Where( comp => comp is not null ).Select( comp =>
{
return $$"""
{ typeof({{comp.Type}}),new ApiDocsForComponent(typeof({{comp.Type}}),
"{{comp.TypeName}}",
new List<ApiDocsForComponentProperty>{
{{comp.Properties.Select( prop =>
$"""

new ("{prop.Name}",typeof({prop.Type}), "{prop.TypeName}",{prop.DefaultValueString}, "{prop.Summary}","{prop.Remarks}", {( prop.IsBlazoriseEnum ? "true" : "false" )}),
""" ).StringJoin( " " )}}},
new List<ApiDocsForComponentMethod>{
{{comp.Methods.Select( method =>
$$"""

new ("{{method.Name}}","{{method.ReturnTypeName}}", "{{method.Summary}}" ,"{{method.Remarks}}",
new List<ApiDocsForComponentMethodParameter>{
{{method.Parameters.Select( param =>
$"""
new ("{param.Name}","{param.TypeName}" ),
"""
).StringJoin( " " )}} }),
""" ).StringJoin( " " )}}
},
new List<Type>{
{{comp.InheritsFromChain.Select( x => $"typeof({x})" ).StringJoin( "," )}}
}
)},

""";
}
).StringJoin( "\n" )}}
};
}
""";
}

#endregion
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#region Using directives
using System.Collections.Generic;
#endregion

namespace Blazorise.Docs.Compiler.ApiDocsGenerator.Dtos;

/// <summary>
/// Easier to gather necessary info.
/// Almost keeps parity with Blazorise/Models/ApiDocsDtos.cs, changes here should be reflected there
/// </summary>
public class ApiDocsForComponent
{
public ApiDocsForComponent( string type, string typeName,
IEnumerable<ApiDocsForComponentProperty> properties,
IEnumerable<ApiDocsForComponentMethod> methods,
IEnumerable<string> inheritsFromChain )
{
Type = type;
TypeName = typeName;
Properties = properties;
Methods = methods;
InheritsFromChain = inheritsFromChain;
}

public string Type { get; }

public string TypeName { get; }
public IEnumerable<ApiDocsForComponentProperty> Properties { get; }
public IEnumerable<ApiDocsForComponentMethod> Methods { get; }

public IEnumerable<string> InheritsFromChain { get; }
}
Loading
Loading