diff --git a/docs/wiki/Code-Writer.md b/docs/wiki/Code-Writer.md index fbcecf4..055751e 100644 --- a/docs/wiki/Code-Writer.md +++ b/docs/wiki/Code-Writer.md @@ -518,6 +518,10 @@ one. Set the defaults on `GenerationSettings` (to apply across a generation) or (to override per writer). Each value is `null`-able, so setting a kind back to `null` omits the modifier entirely. +Partial methods are the one exception to method defaulting: `PartialMethod(...)` and any method +declaration with `IsPartial = true` omit the accessibility modifier when none is provided, even if +`DefaultMethodAccessibility` is still `Public`. + | Setting | Default | |---|---| | `DefaultTypeAccessibility` | `Public` | diff --git a/package.json b/package.json index 27915af..25c5ca0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "purview-sourcegenerator-framework", - "version": "1.0.0-prerelease.44", + "version": "1.0.0-prerelease.45", "license": "MIT", "author": { "name": "Kieron Lanning", diff --git a/src/src/SourceGeneratorShared/CodeWriter.DeclarationOverloads.cs b/src/src/SourceGeneratorShared/CodeWriter.DeclarationOverloads.cs index 603c18d..68440e2 100644 --- a/src/src/SourceGeneratorShared/CodeWriter.DeclarationOverloads.cs +++ b/src/src/SourceGeneratorShared/CodeWriter.DeclarationOverloads.cs @@ -64,7 +64,10 @@ Action writeBody /// /// The method name. /// The return type, or for void. - /// The optional accessibility. + /// + /// The optional accessibility. When omitted, the partial method is emitted without an accessibility + /// modifier. + /// /// An optional callback that configures the declaration. /// The current writer. /// writer.PartialMethod("OnChanged"); diff --git a/src/src/SourceGeneratorShared/CodeWriter.cs b/src/src/SourceGeneratorShared/CodeWriter.cs index 6e76c3e..80d4948 100644 --- a/src/src/SourceGeneratorShared/CodeWriter.cs +++ b/src/src/SourceGeneratorShared/CodeWriter.cs @@ -236,8 +236,10 @@ public CodeWriter( /// /// Gets or sets the default accessibility emitted for method declarations when a declaration does not - /// specify one. The default is . Set to - /// to omit the modifier. + /// specify one. The default is . Partial methods are + /// the exception: when their declaration does not specify an accessibility, the modifier is omitted + /// instead of using this default. Set to to omit the modifier for other method + /// declarations. /// public TypeDeclarationAccessibility? DefaultMethodAccessibility { get; set; } = TypeDeclarationAccessibility.Public; @@ -727,6 +729,11 @@ BlockScope MethodScope(MethodDeclarationOptions declaration, Action? void MethodHeader(MethodDeclarationOptions declaration) { + var accessibility = + declaration.IsPartial && declaration.Accessibility is null + ? null + : ResolveAccessibility(declaration.Accessibility, DefaultMethodAccessibility); + ValidateMethodDeclaration(declaration); BeginWrittenItem(WrittenItemKind.Method); @@ -737,7 +744,7 @@ void MethodHeader(MethodDeclarationOptions declaration) Attributes(declaration.ReturnAttributes, defaultTarget: "return"); MemberModifiers( - ResolveAccessibility(declaration.Accessibility, DefaultMethodAccessibility), + accessibility, declaration.IsStatic, declaration.IsAbstract, declaration.IsVirtual, @@ -759,6 +766,9 @@ void MethodHeader(MethodDeclarationOptions declaration) /// /// Writes a structured partial method declaration. + /// When is , the + /// declaration omits any accessibility modifier instead of using + /// . /// /// writer.PartialMethod(new MethodDeclarationOptions("OnChanged")); public CodeWriter PartialMethod(MethodDeclarationOptions declaration) diff --git a/src/src/SourceGeneratorShared/GenerationSettings.cs b/src/src/SourceGeneratorShared/GenerationSettings.cs index 929b881..f49429b 100644 --- a/src/src/SourceGeneratorShared/GenerationSettings.cs +++ b/src/src/SourceGeneratorShared/GenerationSettings.cs @@ -141,8 +141,10 @@ public GenerationSettings( /// /// Gets the default accessibility emitted for method declarations when a declaration does not specify - /// one. The default is . Set to - /// to omit the modifier, matching the previous behaviour. + /// one. The default is . Partial methods are the + /// exception: when their declaration does not specify an accessibility, the modifier is omitted + /// instead of using this default. Set to to omit the modifier for other + /// method declarations, matching the previous behaviour. /// public TypeDeclarationAccessibility? DefaultMethodAccessibility { get; init; } = TypeDeclarationAccessibility.Public; diff --git a/src/tests/SourceGeneratorShared.UnitTests/CodeWriterTests.cs b/src/tests/SourceGeneratorShared.UnitTests/CodeWriterTests.cs index 4616fb3..c00a06c 100644 --- a/src/tests/SourceGeneratorShared.UnitTests/CodeWriterTests.cs +++ b/src/tests/SourceGeneratorShared.UnitTests/CodeWriterTests.cs @@ -3535,7 +3535,7 @@ await Assert .That(writer.ToString()) .IsEqualTo( GeneratedAttributes() - + "public readonly partial void OnValidate(global::System.Guid id, string? displayName, bool isActive);\n" + + "readonly partial void OnValidate(global::System.Guid id, string? displayName, bool isActive);\n" ); } @@ -3550,7 +3550,7 @@ public async Task PartialMethod_GivenIsReadOnlyFalse_OmitsReadonlyModifier() writer.PartialMethod(declaration); // Assert - await Assert.That(writer.ToString()).IsEqualTo(GeneratedAttributes() + "public partial void Apply();\n"); + await Assert.That(writer.ToString()).IsEqualTo(GeneratedAttributes() + "partial void Apply();\n"); } [Test] @@ -4654,7 +4654,33 @@ public async Task PartialMethodOverload_GivenMinimalProperties_WritesPartialMeth writer.PartialMethod("OnChanged", Type("void")); // Assert - await Assert.That(writer.ToString()).IsEqualTo(GeneratedAttributes() + "public partial void OnChanged();\n"); + await Assert.That(writer.ToString()).IsEqualTo(GeneratedAttributes() + "partial void OnChanged();\n"); + } + + [Test] + public async Task PartialMethod_WithoutAccessibility_OmitsDefaultMethodAccessibility() + { + // Arrange + var writer = CodeWriterFactory.ForTests(); + + // Act + writer.PartialMethod(new("OnChanged")); + + // Assert + await Assert.That(writer.ToString()).IsEqualTo(GeneratedAttributes() + "partial void OnChanged();\n"); + } + + [Test] + public async Task PartialMethod_ExplicitAccessibility_OverridesOmittedDefault() + { + // Arrange + var writer = CodeWriterFactory.ForTests(); + + // Act + writer.PartialMethod(new("OnChanged", TypeDeclarationAccessibility.Internal)); + + // Assert + await Assert.That(writer.ToString()).IsEqualTo(GeneratedAttributes() + "internal partial void OnChanged();\n"); } [Test]