From f13dfbba68c1c4faa7df882ac557d3ec286dd3b3 Mon Sep 17 00:00:00 2001 From: Kieron Lanning Date: Mon, 26 Oct 2026 22:08:36 +0000 Subject: [PATCH] fix: added cs1519 to the auto generater header in code writer --- docs/wiki/Code-Writer.md | 16 ++++ package.json | 2 +- .../SourceGeneratorFramework/Sdk/README.md | 2 +- src/src/SourceGeneratorShared/CodeWriter.cs | 38 +++++++++- .../GenerationSettings.cs | 7 ++ .../CodeWriterTests.cs | 74 +++++++++++++++++++ 6 files changed, 134 insertions(+), 5 deletions(-) diff --git a/docs/wiki/Code-Writer.md b/docs/wiki/Code-Writer.md index 64d222a..02b21d1 100644 --- a/docs/wiki/Code-Writer.md +++ b/docs/wiki/Code-Writer.md @@ -471,6 +471,8 @@ Emits: // This code was generated by ExampleGenerator (version 1.0.0). // Changes to this file will be lost when the source generator runs again. +#pragma warning disable CS1591 + #if !NET48_OR_GREATER && !PURVIEW_TELEMETRY_NON_NULLABLE #nullable enable #endif @@ -480,6 +482,20 @@ Emits: namespace Purview.Telemetry; ``` +`AutoGeneratedHeader` writes `#pragma warning disable CS1591` by default, so generated public members +do not require XML documentation comments in consuming projects that produce a documentation file. +Passing `CS1591` through the `pragmas` parameter is ignored rather than duplicated. Opt out per writer +or generator-wide: + +```csharp +writer.IncludeMissingXmlCommentPragma = false; + +var settings = GenerationSettings.Create() with +{ + IncludeMissingXmlCommentPragma = false, +}; +``` + The generator version in the header and the `GeneratedCode` attribute comes from the `GenerationSettings` used to create the writer. When settings are created via `GenerationSettings.Create()`, the full assembly informational version is used, so any diff --git a/package.json b/package.json index 296b9f4..7dcc6d3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sourcegenerator-framework", - "version": "1.2.0", + "version": "1.2.1", "license": "MIT", "author": { "name": "Kieron Lanning", diff --git a/src/src/SourceGeneratorFramework/Sdk/README.md b/src/src/SourceGeneratorFramework/Sdk/README.md index 65e33f4..97a3f57 100644 --- a/src/src/SourceGeneratorFramework/Sdk/README.md +++ b/src/src/SourceGeneratorFramework/Sdk/README.md @@ -191,7 +191,7 @@ See [`SourceGeneratorFramework.ExampleGenerator`](../SourceGeneratorFramework.Ex ## Generated attributes and determinism -`CodeWriter` automatically stamps generated declarations with `[GeneratedCode]`, `[CompilerGenerated]`, and `[ExcludeFromCodeCoverage]` (where applicable) using the generator identity supplied to its constructor. The header written by `AutoGeneratedHeader()` is deterministic and does not include a timestamp, so the same inputs always produce the same source. +`CodeWriter` automatically stamps generated declarations with `[GeneratedCode]`, `[CompilerGenerated]`, and `[ExcludeFromCodeCoverage]` (where applicable) using the generator identity supplied to its constructor. The header written by `AutoGeneratedHeader()` is deterministic and does not include a timestamp, so the same inputs always produce the same source. It also writes `#pragma warning disable CS1591` by default, so generated public members do not require XML documentation comments in consuming projects that produce a documentation file; set `CodeWriter.IncludeMissingXmlCommentPragma` or `GenerationSettings.IncludeMissingXmlCommentPragma` to `false` to omit it. ### The `#nullable enable` directive diff --git a/src/src/SourceGeneratorShared/CodeWriter.cs b/src/src/SourceGeneratorShared/CodeWriter.cs index 80d4948..0faa088 100644 --- a/src/src/SourceGeneratorShared/CodeWriter.cs +++ b/src/src/SourceGeneratorShared/CodeWriter.cs @@ -21,6 +21,7 @@ public sealed partial class CodeWriter const int DefaultExpressionCapacity = 128; const int DefaultIndentationSize = 4; const int DefaultMaximumLineLength = 100; + const string MissingXmlCommentWarning = "CS1591"; int _indentLevel; int _nextScopeId; @@ -82,6 +83,7 @@ public CodeWriter( GeneratorVersion = settings.GeneratorVersion; NullableDirectiveMode = settings.NullableDirectiveMode; IsNullableContextEnabled = settings.IsNullableContextEnabled; + IncludeMissingXmlCommentPragma = settings.IncludeMissingXmlCommentPragma; ThrowOnUnclosedScopes = throwOnUnclosedScopes; DefaultTypeAccessibility = settings.DefaultTypeAccessibility; @@ -115,6 +117,7 @@ public CodeWriter( GeneratorVersion = source.GeneratorVersion; NullableDirectiveMode = source.NullableDirectiveMode; IsNullableContextEnabled = source.IsNullableContextEnabled; + IncludeMissingXmlCommentPragma = source.IncludeMissingXmlCommentPragma; ThrowOnUnclosedScopes = source.ThrowOnUnclosedScopes; DefaultIncludeGeneratedAttributes = source.DefaultIncludeGeneratedAttributes; DefaultTypeAccessibility = source.DefaultTypeAccessibility; @@ -185,6 +188,14 @@ public CodeWriter( /// public bool? IsNullableContextEnabled { get; set; } + /// + /// Gets or sets whether disables CS1591, so that generated + /// public members do not require XML documentation comments. The value is seeded from + /// at construction and defaults to + /// . + /// + public bool IncludeMissingXmlCommentPragma { get; set; } = true; + /// /// Gets or sets whether generated attributes are emitted for declarations that do not /// explicitly override , @@ -2088,6 +2099,13 @@ public CodeWriter Constructor(ConstructorDeclarationOptions declaration, Action< /// /// Writes the standard header for an automatically generated source file. /// + /// + /// The header disables CS1591 so that generated public members do not require XML + /// documentation comments in consuming projects that produce a documentation file. Set + /// (or + /// ) to to + /// omit it. + /// /// The generator name; defaults to . /// The generator version; defaults to . /// @@ -2095,7 +2113,10 @@ public CodeWriter Constructor(ConstructorDeclarationOptions declaration, Action< /// reference annotations are rendered. When , /// is used, which defaults to . /// - /// The pragmas to include in the header. + /// + /// Additional pragmas to include in the header; CS1591 is ignored here when + /// already writes it. + /// /// The current writer. /// /// writer.AutoGeneratedHeader(pragmas: ["CS0618"]); @@ -2128,11 +2149,22 @@ params string[] pragmas if (ShouldWriteNullableDirective(mode, IsNullableContextEnabled)) NewLine().Line("#nullable enable"); - if (pragmas is not null && pragmas.Length > 0) + var additionalPragmas = pragmas ?? []; + if (IncludeMissingXmlCommentPragma || additionalPragmas.Length > 0) { NewLine(); - foreach (var pragma in pragmas) + + if (IncludeMissingXmlCommentPragma) + Write("#pragma warning disable ").Line(MissingXmlCommentWarning); + + foreach (var pragma in additionalPragmas) { + if ( + IncludeMissingXmlCommentPragma + && string.Equals(pragma, MissingXmlCommentWarning, StringComparison.Ordinal) + ) + continue; + Write("#pragma warning disable ").Line(pragma); } } diff --git a/src/src/SourceGeneratorShared/GenerationSettings.cs b/src/src/SourceGeneratorShared/GenerationSettings.cs index b431506..6692b70 100644 --- a/src/src/SourceGeneratorShared/GenerationSettings.cs +++ b/src/src/SourceGeneratorShared/GenerationSettings.cs @@ -58,6 +58,13 @@ public GenerationSettings( /// public bool? IsNullableContextEnabled { get; init; } + /// + /// Gets whether the header written by CodeWriter.AutoGeneratedHeader disables CS1591, + /// so that generated public members do not require XML documentation comments. The default is + /// . + /// + public bool IncludeMissingXmlCommentPragma { get; init; } = true; + /// /// Gets whether created code writers validate undisposed scopes. /// diff --git a/src/tests/SourceGeneratorShared.UnitTests/CodeWriterTests.cs b/src/tests/SourceGeneratorShared.UnitTests/CodeWriterTests.cs index c00a06c..266f7c5 100644 --- a/src/tests/SourceGeneratorShared.UnitTests/CodeWriterTests.cs +++ b/src/tests/SourceGeneratorShared.UnitTests/CodeWriterTests.cs @@ -2591,6 +2591,74 @@ public async Task AutoGeneratedHeader_WritesHeader() await Assert.That(result).DoesNotContain("// Generated at "); } + [Test] + public async Task AutoGeneratedHeader_GivenAdditionalPragmas_WritesMissingXmlCommentPragmaOnce() + { + var writer = CodeWriterFactory.ForTests(); + + writer.AutoGeneratedHeader("TestGenerator", "1.0", NullableDirectiveMode.Disable, "CS0618", "CS1591"); + + await Assert + .That(writer.ToString()) + .IsEqualTo( + "// \n" + + "// This code was generated by TestGenerator (version 1.0).\n" + + "// Changes to this file will be lost when the source generator runs again.\n" + + "\n" + + "#pragma warning disable CS1591\n" + + "#pragma warning disable CS0618\n" + + "\n" + ); + } + + [Test] + public async Task AutoGeneratedHeader_GivenMissingXmlCommentPragmaDisabled_OmitsPragma() + { + var writer = CodeWriterFactory.ForTests( + settings: new GenerationSettings("TestGenerator", "1.0.0") + { + NullableDirectiveMode = NullableDirectiveMode.Disable, + IncludeMissingXmlCommentPragma = false, + } + ); + + writer.AutoGeneratedHeader("TestGenerator", "1.0"); + + await Assert + .That(writer.ToString()) + .IsEqualTo( + "// \n" + + "// This code was generated by TestGenerator (version 1.0).\n" + + "// Changes to this file will be lost when the source generator runs again.\n" + + "\n" + ); + } + + [Test] + public async Task AutoGeneratedHeader_GivenMissingXmlCommentPragmaDisabledAndExplicitPragma_WritesPragma() + { + var writer = CodeWriterFactory.ForTests( + settings: new GenerationSettings("TestGenerator", "1.0.0") + { + NullableDirectiveMode = NullableDirectiveMode.Disable, + IncludeMissingXmlCommentPragma = false, + } + ); + + writer.AutoGeneratedHeader("TestGenerator", "1.0", pragmas: ["CS1591"]); + + await Assert + .That(writer.ToString()) + .IsEqualTo( + "// \n" + + "// This code was generated by TestGenerator (version 1.0).\n" + + "// Changes to this file will be lost when the source generator runs again.\n" + + "\n" + + "#pragma warning disable CS1591\n" + + "\n" + ); + } + [Test] public async Task AutoGeneratedHeader_GivenDefaultSettings_WritesNullableEnableDirective() { @@ -2689,6 +2757,8 @@ await Assert + "// This code was generated by TestGenerator (version 1.0).\n" + "// Changes to this file will be lost when the source generator runs again.\n" + "\n" + + "#pragma warning disable CS1591\n" + + "\n" ); } @@ -2713,6 +2783,8 @@ await Assert + "\n" + "#nullable enable\n" + "\n" + + "#pragma warning disable CS1591\n" + + "\n" ); } @@ -5688,6 +5760,8 @@ await Assert + "// This code was generated by TestGenerator (version 1.0.0).\n" + "// Changes to this file will be lost when the source generator runs again.\n" + "\n" + + "#pragma warning disable CS1591\n" + + "\n" + "#if !NET48_OR_GREATER && !PURVIEW_TELEMETRY_NON_NULLABLE\n" + "#nullable enable\n" + "#endif\n"