From 99a7550dbb858f6a52f74cbb51d6188ecd49d0d3 Mon Sep 17 00:00:00 2001 From: Josef Pihrt Date: Sat, 29 Oct 2022 17:53:18 +0200 Subject: [PATCH 1/4] Add option ignored-title-parts --- .../Commands/GenerateDocCommand.cs | 5 ++ src/CommandLine/OptionNames.cs | 1 + .../Options/GenerateDocCommandLineOptions.cs | 7 +- src/CommandLine/Program.cs | 30 ++++---- src/Documentation/DocumentationGenerator.cs | 4 +- src/Documentation/DocumentationOptions.cs | 5 ++ src/Documentation/DocumentationWriter.cs | 72 +++++++++++++++++-- src/Documentation/SymbolTitleParts.cs | 15 ++++ 8 files changed, 117 insertions(+), 22 deletions(-) create mode 100644 src/Documentation/SymbolTitleParts.cs diff --git a/src/CommandLine/Commands/GenerateDocCommand.cs b/src/CommandLine/Commands/GenerateDocCommand.cs index 327bf87f27..19878d43f2 100644 --- a/src/CommandLine/Commands/GenerateDocCommand.cs +++ b/src/CommandLine/Commands/GenerateDocCommand.cs @@ -29,6 +29,7 @@ public GenerateDocCommand( TypeDocumentationParts ignoredTypeParts, MemberDocumentationParts ignoredMemberParts, CommonDocumentationParts ignoredCommonParts, + SymbolTitleParts ignoredTitleParts, OmitMemberParts omitMemberParts, IncludeContainingNamespaceFilter includeContainingNamespaceFilter, Visibility visibility, @@ -46,6 +47,7 @@ public GenerateDocCommand( IgnoredMemberParts = ignoredMemberParts; IgnoredCommonParts = ignoredCommonParts; OmitMemberParts = omitMemberParts; + IgnoredTitleParts = ignoredTitleParts; IncludeContainingNamespaceFilter = includeContainingNamespaceFilter; Visibility = visibility; DocumentationHost = documentationHost; @@ -70,6 +72,8 @@ public GenerateDocCommand( public OmitMemberParts OmitMemberParts { get; } + public SymbolTitleParts IgnoredTitleParts { get; } + public IncludeContainingNamespaceFilter IncludeContainingNamespaceFilter { get; } public Visibility Visibility { get; } @@ -111,6 +115,7 @@ public override async Task ExecuteAsync(ProjectOrSolution project ignoredTypeParts: IgnoredTypeParts, ignoredMemberParts: IgnoredMemberParts, ignoredCommonParts: IgnoredCommonParts, + ignoredTitleParts: IgnoredTitleParts, includeContainingNamespaceFilter: IncludeContainingNamespaceFilter, filesLayout: FilesLayout, scrollToContent: (DocumentationHost == DocumentationHost.GitHub) && Options.ScrollToContent); diff --git a/src/CommandLine/OptionNames.cs b/src/CommandLine/OptionNames.cs index 51e381836f..7e6811952d 100644 --- a/src/CommandLine/OptionNames.cs +++ b/src/CommandLine/OptionNames.cs @@ -20,6 +20,7 @@ internal static class OptionNames public const string IgnoredProjects = "ignored-projects"; public const string IgnoredRootParts = "ignored-root-parts"; public const string IgnoredScope = "ignored-scope"; + public const string IgnoredTitleParts = "ignored-title-parts"; public const string IgnoredTypeParts = "ignored-type-parts"; public const string IncludeContainingNamespace = "include-containing-namespace"; public const string IncludeSystemNamespace = "include-system-namespace"; diff --git a/src/CommandLine/Options/GenerateDocCommandLineOptions.cs b/src/CommandLine/Options/GenerateDocCommandLineOptions.cs index 1510ec48b2..41d6fe348a 100644 --- a/src/CommandLine/Options/GenerateDocCommandLineOptions.cs +++ b/src/CommandLine/Options/GenerateDocCommandLineOptions.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using CommandLine; -using Roslynator.Documentation; using static Roslynator.Documentation.DocumentationOptions; namespace Roslynator.CommandLine @@ -45,6 +44,12 @@ public class GenerateDocCommandLineOptions : AbstractGenerateDocCommandLineOptio MetaValue = "")] public IEnumerable IgnoredRootParts { get; set; } + [Option( + longName: OptionNames.IgnoredTitleParts, + HelpText = "Defines title parts of a documentation that should be excluded. Allowed value is containing-type, parameters and explicit-implementation.", + MetaValue = "")] + public IEnumerable IgnoredTitleParts { get; set; } + [Option( longName: OptionNames.IgnoredTypeParts, HelpText = "Defines parts of a type documentation that should be excluded. Allowed values are content, containing-namespace, containing-assembly, obsolete-message, summary, declaration, type-parameters, parameters, return-value, inheritance, attributes, derived, implements, examples, remarks, constructors, fields, indexers, properties, methods, operators, events, explicit-interface-implementations, extension-methods, classes, structs, interfaces, enums, delegates and see-also.", diff --git a/src/CommandLine/Program.cs b/src/CommandLine/Program.cs index 9a652d4c56..ce990aa316 100644 --- a/src/CommandLine/Program.cs +++ b/src/CommandLine/Program.cs @@ -762,6 +762,9 @@ private static async Task GenerateDocAsync(GenerateDocCommandLineOptions op if (!TryParseOptionValueAsEnumFlags(options.IgnoredCommonParts, OptionNames.IgnoredCommonParts, out CommonDocumentationParts ignoredCommonParts, DocumentationOptions.DefaultValues.IgnoredCommonParts)) return ExitCodes.Error; + if (!TryParseOptionValueAsEnumFlags(options.IgnoredTitleParts, OptionNames.IgnoredTitleParts, out SymbolTitleParts ignoredTitleParts, DocumentationOptions.DefaultValues.IgnoredTitleParts)) + return ExitCodes.Error; + if (!TryParseOptionValueAsEnumFlags(options.IncludeContainingNamespace, OptionNames.IncludeContainingNamespace, out IncludeContainingNamespaceFilter includeContainingNamespaceFilter, DocumentationOptions.DefaultValues.IncludeContainingNamespaceFilter)) return ExitCodes.Error; @@ -784,21 +787,22 @@ private static async Task GenerateDocAsync(GenerateDocCommandLineOptions op return ExitCodes.Error; var command = new GenerateDocCommand( - options, - depth, - ignoredRootParts, - ignoredNamespaceParts, - ignoredTypeParts, - ignoredMemberParts, - ignoredCommonParts, - omitMemberParts, - includeContainingNamespaceFilter, - visibility, - documentationHost, - filesLayout, + options: options, + depth: depth, + ignoredRootParts: ignoredRootParts, + ignoredNamespaceParts: ignoredNamespaceParts, + ignoredTypeParts: ignoredTypeParts, + ignoredMemberParts: ignoredMemberParts, + ignoredCommonParts: ignoredCommonParts, + ignoredTitleParts: ignoredTitleParts, + omitMemberParts: omitMemberParts, + includeContainingNamespaceFilter: includeContainingNamespaceFilter, + visibility: visibility, + documentationHost: documentationHost, + filesLayout: filesLayout, groupByCommonNamespace: options.GroupByCommonNamespace, inheritanceStyle: inheritanceStyle, - projectFilter); + projectFilter: projectFilter); CommandStatus status = await command.ExecuteAsync(paths, options.MSBuildPath, options.Properties); diff --git a/src/Documentation/DocumentationGenerator.cs b/src/Documentation/DocumentationGenerator.cs index 6c7a22eea8..5e011712f4 100644 --- a/src/Documentation/DocumentationGenerator.cs +++ b/src/Documentation/DocumentationGenerator.cs @@ -591,7 +591,9 @@ private DocumentationGeneratorResult GenerateType(TypeDocumentationModel typeMod writer.WriteHeading( 1, typeSymbol, - TypeSymbolDisplayFormats.Name_ContainingTypes_TypeParameters, + ((Options.IgnoredTitleParts & SymbolTitleParts.ContainingType) != 0) + ? TypeSymbolDisplayFormats.Name_TypeParameters + : TypeSymbolDisplayFormats.Name_ContainingTypes_TypeParameters, SymbolDisplayAdditionalMemberOptions.UseItemPropertyName | SymbolDisplayAdditionalMemberOptions.UseOperatorName, addLink: false, linkDestination: (Options.ScrollToContent) ? WellKnownNames.TopFragmentName : null); diff --git a/src/Documentation/DocumentationOptions.cs b/src/Documentation/DocumentationOptions.cs index 35254acac0..c4c87950b9 100644 --- a/src/Documentation/DocumentationOptions.cs +++ b/src/Documentation/DocumentationOptions.cs @@ -39,6 +39,7 @@ public DocumentationOptions( TypeDocumentationParts ignoredTypeParts = TypeDocumentationParts.None, MemberDocumentationParts ignoredMemberParts = MemberDocumentationParts.None, CommonDocumentationParts ignoredCommonParts = CommonDocumentationParts.None, + SymbolTitleParts ignoredTitleParts = SymbolTitleParts.None, IncludeContainingNamespaceFilter includeContainingNamespaceFilter = IncludeContainingNamespaceFilter.None, FilesLayout filesLayout = FilesLayout.Hierarchical, bool scrollToContent = DefaultValues.ScrollToContent) @@ -74,6 +75,7 @@ public DocumentationOptions( IgnoredTypeParts = ignoredTypeParts; IgnoredMemberParts = ignoredMemberParts; IgnoredCommonParts = ignoredCommonParts; + IgnoredTitleParts = ignoredTitleParts; IncludeContainingNamespaceFilter = includeContainingNamespaceFilter; FilesLayout = filesLayout; ScrollToContent = scrollToContent; @@ -141,6 +143,8 @@ public DocumentationOptions( public CommonDocumentationParts IgnoredCommonParts { get; } + public SymbolTitleParts IgnoredTitleParts { get; } + public IncludeContainingNamespaceFilter IncludeContainingNamespaceFilter { get; } public FilesLayout FilesLayout { get; } @@ -202,6 +206,7 @@ internal static class DefaultValues public const TypeDocumentationParts IgnoredTypeParts = TypeDocumentationParts.None; public const MemberDocumentationParts IgnoredMemberParts = MemberDocumentationParts.None; public const CommonDocumentationParts IgnoredCommonParts = CommonDocumentationParts.None; + public const SymbolTitleParts IgnoredTitleParts = SymbolTitleParts.None; public const IncludeContainingNamespaceFilter IncludeContainingNamespaceFilter = Roslynator.Documentation.IncludeContainingNamespaceFilter.None; } } diff --git a/src/Documentation/DocumentationWriter.cs b/src/Documentation/DocumentationWriter.cs index 9bc99d9055..c7c9ed1e3e 100644 --- a/src/Documentation/DocumentationWriter.cs +++ b/src/Documentation/DocumentationWriter.cs @@ -18,6 +18,10 @@ public abstract class DocumentationWriter : IDisposable { private bool _disposed; + private SymbolDisplayFormat _nonOverloadedConstructorDisplayFormat; + private SymbolDisplayFormat _nonOverloadedMemberDisplayFormat; + private SymbolDisplayFormat _overloadedMemberDisplayFormat; + protected DocumentationWriter(DocumentationContext context) { Context = context ?? throw new ArgumentNullException(nameof(context)); @@ -350,27 +354,81 @@ internal void WriteMemberTitle(ISymbol symbol, bool isOverloaded) { WriteStartHeading(1); - if (symbol.Kind == SymbolKind.Method - && ((IMethodSymbol)symbol).MethodKind == MethodKind.Constructor) + if ((symbol as IMethodSymbol)?.MethodKind == MethodKind.Constructor) { if (isOverloaded) { - WriteString(symbol.ContainingType.ToDisplayString(TypeSymbolDisplayFormats.Name_ContainingTypes_TypeParameters)); + SymbolDisplayFormat format = ((Options.IgnoredTitleParts & SymbolTitleParts.ContainingType) != 0) + ? TypeSymbolDisplayFormats.Name_TypeParameters + : TypeSymbolDisplayFormats.Name_ContainingTypes_TypeParameters; + + WriteString(symbol.ContainingType.ToDisplayString(format)); WriteSpace(); WriteString(Resources.ConstructorsTitle); } else { - WriteString(symbol.ToDisplayString(DocumentationDisplayFormats.SimpleDeclaration)); + _nonOverloadedConstructorDisplayFormat ??= DocumentationDisplayFormats.Default.Update( + genericsOptions: SymbolDisplayGenericsOptions.IncludeTypeParameters, + memberOptions: ((Options.IgnoredTitleParts & SymbolTitleParts.Parameters) != 0) + ? SymbolDisplayMemberOptions.None + : SymbolDisplayMemberOptions.IncludeParameters, + parameterOptions: SymbolDisplayParameterOptions.IncludeType); + + if ((Options.IgnoredTitleParts & SymbolTitleParts.ContainingType) == 0) + { + INamedTypeSymbol containingType = symbol.ContainingType.ContainingType; + + if (containingType is not null) + { + WriteString(containingType.ToDisplayString(TypeSymbolDisplayFormats.Name_ContainingTypes_TypeParameters)); + WriteString("."); + } + } + + WriteString(symbol.ToDisplayString(_nonOverloadedConstructorDisplayFormat)); WriteSpace(); WriteString(Resources.ConstructorTitle); } } else { - SymbolDisplayFormat format = (isOverloaded) - ? DocumentationDisplayFormats.OverloadedMemberTitle - : DocumentationDisplayFormats.MemberTitle; + SymbolDisplayFormat format; + if (isOverloaded) + { + _overloadedMemberDisplayFormat ??= DocumentationDisplayFormats.Default.Update( + typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameAndContainingTypes, + genericsOptions: SymbolDisplayGenericsOptions.None, + memberOptions: (((Options.IgnoredTitleParts & SymbolTitleParts.ExplicitImplementation) == SymbolTitleParts.ExplicitImplementation) + ? SymbolDisplayMemberOptions.None + : SymbolDisplayMemberOptions.IncludeExplicitInterface) + | (((Options.IgnoredTitleParts & SymbolTitleParts.ContainingType) != 0) + ? SymbolDisplayMemberOptions.None + : SymbolDisplayMemberOptions.IncludeContainingType)); + + format = _overloadedMemberDisplayFormat; + } + else + { + _nonOverloadedMemberDisplayFormat ??= DocumentationDisplayFormats.Default.Update( + typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameAndContainingTypes, + genericsOptions: SymbolDisplayGenericsOptions.IncludeTypeParameters, + memberOptions: (((Options.IgnoredTitleParts & SymbolTitleParts.ExplicitImplementation) == SymbolTitleParts.ExplicitImplementation) + ? SymbolDisplayMemberOptions.None + : SymbolDisplayMemberOptions.IncludeExplicitInterface) + | (((Options.IgnoredTitleParts & SymbolTitleParts.Parameters) != 0) + ? SymbolDisplayMemberOptions.None + : SymbolDisplayMemberOptions.IncludeParameters) + | (((Options.IgnoredTitleParts & SymbolTitleParts.ContainingType) != 0) + ? SymbolDisplayMemberOptions.None + : SymbolDisplayMemberOptions.IncludeContainingType), + delegateStyle: ((Options.IgnoredTitleParts & SymbolTitleParts.Parameters) != 0) + ? SymbolDisplayDelegateStyle.NameOnly + : SymbolDisplayDelegateStyle.NameAndParameters, + parameterOptions: SymbolDisplayParameterOptions.IncludeType); + + format = _nonOverloadedMemberDisplayFormat; + } WriteString(symbol.ToDisplayString(format, SymbolDisplayAdditionalMemberOptions.UseItemPropertyName | SymbolDisplayAdditionalMemberOptions.UseOperatorName)); WriteSpace(); diff --git a/src/Documentation/SymbolTitleParts.cs b/src/Documentation/SymbolTitleParts.cs new file mode 100644 index 0000000000..a981382ded --- /dev/null +++ b/src/Documentation/SymbolTitleParts.cs @@ -0,0 +1,15 @@ +// Copyright (c) Josef Pihrt and Contributors. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System; + +namespace Roslynator.Documentation +{ + [Flags] + public enum SymbolTitleParts + { + None = 0, + ContainingType = 1, + Parameters = 1 << 1, + ExplicitImplementation = 1 << 2, + } +} From b07a8a65a7b924d6ffdb6c8fe728a71d57cec7ba Mon Sep 17 00:00:00 2001 From: Josef Pihrt Date: Sat, 29 Oct 2022 17:55:42 +0200 Subject: [PATCH 2/4] update changelog --- ChangeLog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog.md b/ChangeLog.md index 2e40e1e514..c7e4d3f48a 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [CLI] Generate reference documentation that can be published with Sphinx ([#961](https://github.com/josefpihrt/roslynator/pull/961)). - `roslynator generate-doc --host sphinx` - [CLI] Basic support for `` when generating documentation (`generate-doc` command) ([#972](https://github.com/josefpihrt/roslynator/pull/972)). +- [CLI] Add option `ignored-title-parts` (`generate-doc` command) ([#975](https://github.com/josefpihrt/roslynator/pull/975)). ### Changed From 272e1f483896bf1a634b11234b3dc4966ed0e8d7 Mon Sep 17 00:00:00 2001 From: Josef Pihrt Date: Sat, 29 Oct 2022 18:11:36 +0200 Subject: [PATCH 3/4] update --- src/Documentation/DocumentationWriter.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Documentation/DocumentationWriter.cs b/src/Documentation/DocumentationWriter.cs index c7c9ed1e3e..d37b58e5c4 100644 --- a/src/Documentation/DocumentationWriter.cs +++ b/src/Documentation/DocumentationWriter.cs @@ -399,7 +399,7 @@ internal void WriteMemberTitle(ISymbol symbol, bool isOverloaded) _overloadedMemberDisplayFormat ??= DocumentationDisplayFormats.Default.Update( typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameAndContainingTypes, genericsOptions: SymbolDisplayGenericsOptions.None, - memberOptions: (((Options.IgnoredTitleParts & SymbolTitleParts.ExplicitImplementation) == SymbolTitleParts.ExplicitImplementation) + memberOptions: (((Options.IgnoredTitleParts & SymbolTitleParts.ExplicitImplementation) != 0) ? SymbolDisplayMemberOptions.None : SymbolDisplayMemberOptions.IncludeExplicitInterface) | (((Options.IgnoredTitleParts & SymbolTitleParts.ContainingType) != 0) @@ -413,7 +413,7 @@ internal void WriteMemberTitle(ISymbol symbol, bool isOverloaded) _nonOverloadedMemberDisplayFormat ??= DocumentationDisplayFormats.Default.Update( typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameAndContainingTypes, genericsOptions: SymbolDisplayGenericsOptions.IncludeTypeParameters, - memberOptions: (((Options.IgnoredTitleParts & SymbolTitleParts.ExplicitImplementation) == SymbolTitleParts.ExplicitImplementation) + memberOptions: (((Options.IgnoredTitleParts & SymbolTitleParts.ExplicitImplementation) != 0) ? SymbolDisplayMemberOptions.None : SymbolDisplayMemberOptions.IncludeExplicitInterface) | (((Options.IgnoredTitleParts & SymbolTitleParts.Parameters) != 0) From fd1a92bac05ccc37b2e735b006c7d81a46bdc378 Mon Sep 17 00:00:00 2001 From: Josef Pihrt Date: Sat, 29 Oct 2022 21:10:44 +0200 Subject: [PATCH 4/4] update --- src/CommandLine/Options/GenerateDocCommandLineOptions.cs | 2 +- src/Documentation/DocumentationGenerator.cs | 9 ++++++++- src/Documentation/SymbolTitleParts.cs | 7 ++++--- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/CommandLine/Options/GenerateDocCommandLineOptions.cs b/src/CommandLine/Options/GenerateDocCommandLineOptions.cs index 41d6fe348a..035835d4a0 100644 --- a/src/CommandLine/Options/GenerateDocCommandLineOptions.cs +++ b/src/CommandLine/Options/GenerateDocCommandLineOptions.cs @@ -46,7 +46,7 @@ public class GenerateDocCommandLineOptions : AbstractGenerateDocCommandLineOptio [Option( longName: OptionNames.IgnoredTitleParts, - HelpText = "Defines title parts of a documentation that should be excluded. Allowed value is containing-type, parameters and explicit-implementation.", + HelpText = "Defines title parts of a documentation that should be excluded. Allowed value is containing-namespace, containing-type, parameters and explicit-implementation.", MetaValue = "")] public IEnumerable IgnoredTitleParts { get; set; } diff --git a/src/Documentation/DocumentationGenerator.cs b/src/Documentation/DocumentationGenerator.cs index 5e011712f4..b8f392f34d 100644 --- a/src/Documentation/DocumentationGenerator.cs +++ b/src/Documentation/DocumentationGenerator.cs @@ -332,7 +332,14 @@ private DocumentationGeneratorResult GenerateNamespace(INamespaceSymbol namespac SymbolXmlDocumentation xmlDocumentation = DocumentationModel.GetXmlDocumentation(namespaceSymbol, Options.PreferredCultureName); - writer.WriteHeading(1, namespaceSymbol, TypeSymbolDisplayFormats.Name_ContainingTypes_Namespaces, addLink: false, linkDestination: (Options.ScrollToContent) ? WellKnownNames.TopFragmentName : null); + writer.WriteHeading( + 1, + namespaceSymbol, + ((Options.IgnoredTitleParts & SymbolTitleParts.ContainingNamespace) != 0) + ? TypeSymbolDisplayFormats.Name + : TypeSymbolDisplayFormats.Name_ContainingTypes_Namespaces, + addLink: false, + linkDestination: (Options.ScrollToContent) ? WellKnownNames.TopFragmentName : null); foreach (NamespaceDocumentationParts part in EnabledAndSortedNamespaceParts) { diff --git a/src/Documentation/SymbolTitleParts.cs b/src/Documentation/SymbolTitleParts.cs index a981382ded..685fd98a02 100644 --- a/src/Documentation/SymbolTitleParts.cs +++ b/src/Documentation/SymbolTitleParts.cs @@ -8,8 +8,9 @@ namespace Roslynator.Documentation public enum SymbolTitleParts { None = 0, - ContainingType = 1, - Parameters = 1 << 1, - ExplicitImplementation = 1 << 2, + ContainingNamespace = 1, + ContainingType = 1 << 1, + Parameters = 1 << 2, + ExplicitImplementation = 1 << 3, } }