diff --git a/.agents/prompts/refactor-source-generator-to-codewriter.prompt.md b/.agents/prompts/refactor-source-generator-to-codewriter.prompt.md index d1bbb1f..e230d22 100644 --- a/.agents/prompts/refactor-source-generator-to-codewriter.prompt.md +++ b/.agents/prompts/refactor-source-generator-to-codewriter.prompt.md @@ -19,11 +19,11 @@ Refactor the selected legacy emitter implementation from manual `string` / `Stri ### Requirements 1. Use structured declaration APIs where applicable: - - `WriteClass/WriteStruct/WriteRecordClass/WriteInterface/WriteEnum` - - `WriteMethod`, `WriteProperty`, `WriteField`, `WriteConstructor` + - `Class/Struct/RecordClass/Interface/Enum` + - `Method`, `Property`, `Field`, `Constructor` 2. Use XML helper extensions instead of raw `///` composition: - `XmlSummary`, `XmlParam`, `XmlReturn`, `XmlRemarks`, `XmlCode` or `XmlCodeBlock` -3. Use `TypeReferenceOptions` when type text becomes complex (nullability, generics, arrays). +3. Use `TypeReference` when type text becomes complex (nullability, generics, arrays). 4. Ensure writer lifetime is output-scoped (`generationContext.CreateCodeWriter()` inside callback). 5. Preserve behavior, diagnostics, and generated names. 6. Keep changes minimal and focused; do not reformat unrelated logic. diff --git a/.agents/skills/project-placement-defaults/SKILL.md b/.agents/skills/project-placement-defaults/SKILL.md deleted file mode 100644 index 1a2d3e5..0000000 --- a/.agents/skills/project-placement-defaults/SKILL.md +++ /dev/null @@ -1,114 +0,0 @@ ---- -name: project-placement-defaults -description: "Use when creating, moving, or splitting projects in a repository that uses Purview.DotNetProjectSdk, especially for src/tests placement, test suffix naming, namespace alignment, and automatic project-reference behavior." ---- - -# Project placement defaults for Purview.DotNetProjectSdk - -Use this skill whenever a task asks to add, move, split, or create a project in a repository that uses `Purview.DotNetProjectSdk` and you need placement, naming, and reference decisions to remain consistent with the SDK's automatic conventions. - -## Core principle - -Preserve the host repository's existing layout first; only introduce new structure when no established pattern exists. In Purview-based repos, prefer layouts that let the SDK's naming and auto-reference rules work without extra overrides. - -## Placement heuristics - -Use the repository's current structure as the source of truth, with these Purview-friendly defaults: - -1. Prefer source projects under `src/`. -2. Prefer test projects under `tests/`. -3. Place new projects beside similar projects (same language, layer, and test type). -4. Keep one test type per project by default. -5. Keep shared helper projects in explicit shared/shared-testing locations when those concepts exist. - -When a repo has no clear structure, use these conservative defaults because they align well with the SDK's automatic project-reference search paths: - -- Source/library projects under `src/` -- Test projects under `tests/` -- Integration/end-to-end tests in explicit sibling projects/folders such as `tests/Api.IntegrationTests/` or `tests/Api.E2ETests/` - -## Purview-specific naming rules - -The SDK relies heavily on project names. - -- Keep the `.csproj` filename equal to its containing directory name unless `DisableProjectFileNamingConventionCheck=true` is explicitly used. -- Use conventional test suffixes such as `.UnitTests`, `.IntegrationTests`, `.E2ETests`, `.FunctionalTests`, `.ContractTests`, and other supported `*Tests` suffixes. -- Keep shared helper projects on the SDK's exact recognized names when you want shared behavior: - - Shared projects: `Shared`, `SharedFramework`, `SharedInfrastructure`, `SharedInfra`, `SharedUtilities`, `SharedUtils`, `SharedLibrary`, `SharedLib`, `SharedHelpers` - - Shared testing projects: `SharedTestingFramework`, `SharedTestingInfrastructure`, `SharedTestingInfra`, `SharedTestingUtilities`, `SharedTestingUtils`, `SharedTestingLibrary`, `SharedTestingLib`, `SharedTestingHelpers` -- Do not invent near-miss names if you expect the SDK to classify the project automatically. - -## Test-type boundaries - -Separate tests by behavior and dependency scope: - -- **Unit tests**: isolate logic with minimal external dependencies. -- **Integration tests**: verify behavior across component boundaries (I/O, framework integration, build/evaluation behavior). -- **End-to-end/system tests**: verify full workflow behavior across the assembled system. - -If specialized test categories exist (for example, analyzer diagnostics vs code-fix integration), keep category-specific tests in distinct projects/folders. - -The SDK recognizes many test suffixes, including `Unit`, `Integration`, `E2E`, `EndToEnd`, `Acceptance`, `Functional`, `Performance`, `Load`, `Smoke`, `Stress`, `Regression`, `Security`, `Chaos`, `Scenario`, `System`, `Threat`, `BlackBox`, `WhiteBox`, `Accessibility`, `Interactive`, `Environment`, `Architecture`, and `Contract`. - -## Naming and namespace defaults - -Align identities with existing repository conventions: - -- Project names should follow prevailing patterns in sibling projects. -- Test project names should clearly indicate scope/type with recognized test suffixes. -- `NamespacePrefix` should remain the root identity source for the repo. -- `RootNamespace` usually flows from the logical project identity generated by the SDK; avoid custom namespace overrides unless required. -- `AssemblyName` and `PackageId` default to the fully evaluated `RootNamespace`, so a project's package/assembly identity follows its namespace unless the repo explicitly overrides `AssemblyName`/`PackageId` or opts out via `EnableAssemblyNameGeneration=false`. -- When moving files between projects, update namespaces so they match the destination project's conventions. - -Do not invent a new naming scheme when an existing one is already in use. - -## Project defaults - -When creating a new project: - -1. Match the SDK/project style used by sibling projects. -2. Reuse central dependency/version management if present. -3. Add only dependencies required for the project's scope. -4. Add the project to the repository solution/workspace entry point. -5. Keep configuration consistent with neighboring projects (target frameworks, nullable, analyzers, warnings). - -When working in a Purview-based repo, also assume: - -- `TargetFramework` defaults to `net10.0` if not otherwise set, or `netstandard2.0` when the project explicitly declares `IsRoslynComponent=true`. -- Test projects receive framework packages and coverage defaults from the SDK. -- Non-test projects receive SourceLink and telemetry defaults unless explicitly opted out. - -## Move/split workflow checklist - -When splitting or relocating tests/projects: - -1. Create destination project/folder using established layout patterns. -2. Move files physically. -3. Update namespaces/imports/references for the destination. -4. Verify the destination project name still produces the intended `TestingType`, `TargetProjectName`, and `RootNamespace`. -5. Remove stale dependencies from the source project. -6. Update solution/workspace membership and project references. -6. Run build and relevant tests. - -## Automatic project-reference behavior to preserve - -The SDK automatically searches for project references based on naming and placement. - -- Test projects probe for their target project in these relative locations: - - `../$(TargetProjectName)/$(TargetProjectName).csproj` - - `../../$(TargetProjectName)/$(TargetProjectName).csproj` - - `../src/$(TargetProjectName)/$(TargetProjectName).csproj` - - `../../src/$(TargetProjectName)/$(TargetProjectName).csproj` -- Non-test projects automatically look for sibling shared projects via `../Shared*/Shared*.csproj`. -- Test projects automatically look for sibling shared-testing projects via `../SharedTesting*/SharedTesting*.csproj`. - -If you move projects away from these conventions, be prepared to add explicit project references. - -## Guardrails - -- Prefer minimal, targeted diffs. -- Avoid cross-cutting renames unrelated to the move/split intent. -- Keep test intent unchanged while relocating. -- If structure is ambiguous, infer from nearest sibling projects and document the assumption in the change summary. -- When in doubt, preserve compatibility with the SDK's automatic naming, namespace, and project-reference behavior. diff --git a/Directory.Packages.props b/Directory.Packages.props index 04b379d..df31a38 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -2,7 +2,7 @@ true 1.65.63 - 1.0.0-prerelease.31 + 1.0.0-prerelease.35 diff --git a/src/src/SourceGeneration/Helpers/CodeGenEmiiter.ExtensionMethod.cs b/src/src/SourceGeneration/Helpers/CodeGenEmiiter.ExtensionMethod.cs index 6083b05..fd75fb2 100644 --- a/src/src/SourceGeneration/Helpers/CodeGenEmiiter.ExtensionMethod.cs +++ b/src/src/SourceGeneration/Helpers/CodeGenEmiiter.ExtensionMethod.cs @@ -10,7 +10,7 @@ static void EmitExtensionClass(OutputContext context, CancellationToken cancella context.Debug($"Generating extension class for host kit: {context.HostKit.HostKitType.Name}"); - using (context.Writer.WriteBlockNamespaceScope(TypeLibrary.IDistributedApplicationBuilder)) + using (context.Writer.BlockNamespaceScope(TypeLibrary.IDistributedApplicationBuilder)) { AttributeDeclarationOptions editorBrowsable = new(TypeLibrary.EditorBrowsableAttribute) { @@ -19,7 +19,7 @@ static void EmitExtensionClass(OutputContext context, CancellationToken cancella context .Writer.XmlSummary($"Extension methods for {CodeWriter.XmlSee(context.HostKit.HostKitType)}.") - .WriteClass( + .Class( new($"{context.HostKit.HostKitType.Name}BuilderExtensions", context.HostKit.Accessibility) { IsStatic = true, @@ -96,7 +96,7 @@ static void BuildExtensionMethod(CodeWriter writer, OutputContext context) } using ( - writer.WriteMethodScope( + writer.MethodScope( new( context.HostKit.ExtensionMethodName, TypeLibrary.IDistributedApplicationBuilder, @@ -134,11 +134,9 @@ static void BuildExtensionMethod(CodeWriter writer, OutputContext context) terminate: false ) .NewLine() - .Indented(w => - w.WriteInvocation($".Get<{context.HostKit.OptionsType}>", [], terminate: false) + .WriteInvocation($".Get<{context.HostKit.OptionsType}>", [], terminate: false) .Write(" ?? new();") - .NewLine() - ); + .NewLine(); } writer.Comment("Create an instance of the generated host kit and configure it."); @@ -150,17 +148,15 @@ static void BuildExtensionMethod(CodeWriter writer, OutputContext context) : ["onBuilt", "onConfigured"], terminate: false ); - writer.WriteLine(";"); + writer.Line(";"); writer .NewLine() - .WriteInvocationLine("hostKit.Build", ["builder"]) - .WriteInvocationLine("hostKit.Configure", []) - .NewLine() - .WriteInvocationLine("builder.Services.AddSingleton", ["hostKit"]) - .NewLine(); + .MethodCallOn("hostKit", "Build", ["builder"]) + .MethodCallOn("hostKit", "Configure") + .MethodCallOn("builder.Services", "AddSingleton", ["hostKit"]); - writer.WriteLine("return builder;"); + writer.Return("builder"); } } } diff --git a/src/src/SourceGeneration/Helpers/CodeGenEmiiter.HostKit.cs b/src/src/SourceGeneration/Helpers/CodeGenEmiiter.HostKit.cs index d90d677..10fdb0d 100644 --- a/src/src/SourceGeneration/Helpers/CodeGenEmiiter.HostKit.cs +++ b/src/src/SourceGeneration/Helpers/CodeGenEmiiter.HostKit.cs @@ -1,5 +1,5 @@ -using System.Collections.Immutable; using Purview.Aspire.ResourceKit.SourceGeneration.Models; +using System.Collections.Immutable; namespace Purview.Aspire.ResourceKit.SourceGeneration.Helpers; @@ -11,7 +11,7 @@ static void EmitHostKit(OutputContext context, CancellationToken cancellationTok context.Info($"Generating {context.HostKit.HostKitType.MetadataFullName}..."); - using var nsScope = context.Writer.WriteBlockNamespaceScope(context.HostKit.HostKitType.Namespace); + using var nsScope = context.Writer.BlockNamespaceScope(context.HostKit.HostKitType.Namespace); var primaryConstructorParameters = ImmutableArray.CreateBuilder(); primaryConstructorParameters.Add( @@ -35,7 +35,7 @@ static void EmitHostKit(OutputContext context, CancellationToken cancellationTok using ( context .Writer.XmlSummary("Represents the generated Host Kit and composes all discovered Resources Kits") - .WriteClassScope( + .ClassScope( new(context.HostKit.HostKitType) { IsPartial = true, @@ -51,7 +51,7 @@ static void EmitHostKit(OutputContext context, CancellationToken cancellationTok { context .Writer.XmlSummary($"Gets the Host Kit options .") - .WriteProperty( + .Property( new("Options", context.HostKit.OptionsType, TypeDeclarationAccessibility.Public) { HasGetter = true, @@ -95,12 +95,12 @@ static void EmitResourceKitBase(OutputContext context, CancellationToken cancell $"Generating Resource Kit base class for host kit: {context.Model.HostKit.Value.HostKitType.Name}" ); - using (context.Writer.WriteBlockNamespaceScope(context.Model.HostKit.Value.ResourceKitBaseType.Namespace)) + using (context.Writer.BlockNamespaceScope(context.Model.HostKit.Value.ResourceKitBaseType.Namespace)) { context .Writer.XmlSummary("Represents a typed base class for all generated Resource Kits for the Host Kit.") - .WriteClass( - new(context.Model.HostKit.Value.ResourceKitBaseType.Name, context.Model.HostKit.Value.Accessibility) + .Class( + new(context.Model.HostKit.Value.ResourceKitBaseType, context.Model.HostKit.Value.Accessibility) { IsPartial = true, IsAbstract = true, @@ -115,7 +115,7 @@ static void EmitResourceKitBase(OutputContext context, CancellationToken cancell }, body => body.XmlSummary("Initializes a new instance of the Host Kit Resource Kit base class.") - .WriteConstructor( + .Constructor( new( context.Model.HostKit.Value.ResourceKitBaseType, TypeDeclarationAccessibility.Protected @@ -161,7 +161,7 @@ var resourceKit in context ) .XmlException(TypeLibrary.ArgumentNullException, "Thrown if the resource is set to null."); - context.Writer.WriteProperty( + context.Writer.Property( new(resourceKit.PropertyName, resourceKit.ResourceKitType, TypeDeclarationAccessibility.Public) { HasGetter = true, @@ -169,22 +169,19 @@ var resourceKit in context SetterAccessibility = TypeDeclarationAccessibility.Private, }, writeGetterBody => - writeGetterBody.WriteLine( + writeGetterBody.Line( $"return field ?? throw new {TypeLibrary.InvalidOperationException}(\"The '{resourceKit.PropertyName}' resource has not been initialized. Call Build first.\");" ), writeSetterBody => { - writeSetterBody - .WriteLine(TypeLibrary.ArgumentNullException.StaticMember("ThrowIfNull(value);")) - .NewLine(); - - using (writeSetterBody.OpenBlockScope("if (field is not null)")) - writeSetterBody.WriteThrow( + writeSetterBody.MethodCallOn(TypeLibrary.ArgumentNullException, "ThrowIfNull(value)"); + using (writeSetterBody.IfBlockScope("if (field is not null)")) + writeSetterBody.Throw( TypeLibrary.InvalidOperationException, $"The '{resourceKit.PropertyName}' resource has already been initialized." ); - writeSetterBody.NewLine().WriteAssignment("field", "value"); + writeSetterBody.Assignment("field", "value"); } ); } @@ -198,7 +195,7 @@ static void GenerateBuildMethod(OutputContext context, CancellationToken cancell context.Writer.XmlInheritDoc(); using ( - context.Writer.WriteMethodScope( + context.Writer.MethodScope( new("Build", TypeDeclarationAccessibility.Public) { IsOverride = true, @@ -207,7 +204,7 @@ static void GenerateBuildMethod(OutputContext context, CancellationToken cancell ) ) { - context.Writer.WriteLine(TypeLibrary.ArgumentNullException.StaticMember("ThrowIfNull(builder);")).NewLine(); + context.Writer.MethodCallOn(TypeLibrary.ArgumentNullException, "ThrowIfNull(builder);"); foreach ( var resourceKit in context.ResourceKits.AsImmutableArray().SelectMany(r => r.Items.AsImmutableArray()) @@ -246,14 +243,14 @@ var resourceKit in context ) { cancellationToken.ThrowIfCancellationRequested(); - context.Writer.WriteInvocationLine("AddResource", [$"{resourceKit.PropertyName}"]); + context.Writer.MethodCall("AddResource", [resourceKit.PropertyName]); } } context .Writer.NewLine() .Comment("Now the additional post-build func builder") - .WriteInvocationLine("onBuilt?.Invoke", ["this", "builder"]); + .MethodCallOn("onBuilt?", "Invoke", ["this", "builder"]); context .Writer.NewLine() @@ -261,7 +258,7 @@ var resourceKit in context "Now that we've populated all of the resources, call the base classes", "Build method to register the app resources with the builder." ) - .WriteInvocationLine("base.Build", ["builder"]); + .MethodCallOn("base", "Build", ["builder"]); } } @@ -273,7 +270,7 @@ static void GenerateConfigureMethod(OutputContext context, CancellationToken can context.Writer.XmlInheritDoc(); using ( - context.Writer.WriteMethodScope(new("Configure", TypeDeclarationAccessibility.Public) { IsOverride = true }) + context.Writer.MethodScope(new("Configure", TypeDeclarationAccessibility.Public) { IsOverride = true }) ) { context @@ -297,7 +294,7 @@ static void GenerateHostKitOptionsClass(OutputContext context, CancellationToken context.Writer.NewLine().XmlSummary($"Typed settings for ${CodeWriter.XmlSee(context.HostKit.OptionsType)}."); using ( - context.Writer.WriteClassScope( + context.Writer.ClassScope( new(context.HostKit.OptionsType.Name, TypeDeclarationAccessibility.Public) { IsSealed = true, @@ -308,7 +305,7 @@ static void GenerateHostKitOptionsClass(OutputContext context, CancellationToken { context .Writer.XmlSummary("Configuration section name for host kit options.") - .WriteField( + .Field( new("SectionName", PurviewTypeLibrary.System.String, TypeDeclarationAccessibility.Public) { IsConst = true, @@ -332,7 +329,7 @@ var resourceKit in context $"Gets or sets options for {CodeWriter.XmlSee(resourceKit.ResourceKitType)}.", $"{CodeWriter.XmlSee(resourceKit.OptionsType)} for specific configuration options." ) - .WriteProperty( + .Property( new(resourceKit.PropertyName, resourceKit.OptionsType, TypeDeclarationAccessibility.Public) { HasGetter = true, diff --git a/src/src/SourceGeneration/Helpers/CodeGenEmiiter.ResourceKit.cs b/src/src/SourceGeneration/Helpers/CodeGenEmiiter.ResourceKit.cs index cdc8e1f..afb2b63 100644 --- a/src/src/SourceGeneration/Helpers/CodeGenEmiiter.ResourceKit.cs +++ b/src/src/SourceGeneration/Helpers/CodeGenEmiiter.ResourceKit.cs @@ -25,7 +25,7 @@ static void EmitResourceKits(OutputContext context, CancellationToken cancellati var resourceKitForNS = resourceKitGroup.Items.AsImmutableArray().FirstOrDefault(); - using var resourceNs = context.Writer.WriteBlockNamespaceScope(resourceKitForNS.ResourceKitType); + using var resourceNs = context.Writer.BlockNamespaceScope(resourceKitForNS.ResourceKitType); context.Debug( $"Processing resource kit group: {resourceKitForNS.ResourceKitType.Namespace ?? ""}", 1 @@ -43,7 +43,7 @@ static void EmitResourceKits(OutputContext context, CancellationToken cancellati // Generate the resource kit class using ( - context.Writer.WriteClassScope( + context.Writer.ClassScope( new(resourceKit.ResourceKitType) { IsPartial = true, BaseType = baseClass } ) ) @@ -51,7 +51,7 @@ static void EmitResourceKits(OutputContext context, CancellationToken cancellati // Write the constructor context .Writer.XmlSummary("Initializes a new instance of the Host Kit Resource Kit base class.") - .WriteConstructor( + .Constructor( new(resourceKit.ResourceKitType, TypeDeclarationAccessibility.Public) { Parameters = @@ -68,7 +68,10 @@ static void EmitResourceKits(OutputContext context, CancellationToken cancellati body => { if (context.HostKit.ShouldGenerateOptions) - body.WriteLine("Options = options;").WriteLine("IsEnabled = options.IsEnabled;"); + { + body.Assignment("Options", "options") + .Assignment("IsEnabled", "options.IsEnabled"); + } } ); @@ -77,9 +80,9 @@ static void EmitResourceKits(OutputContext context, CancellationToken cancellati { context .Writer.XmlSummary("Gets the Resource Kit options.") - .WriteProperty( - new("Options", resourceKit.OptionsType, TypeDeclarationAccessibility.Public) - ); + .Property( + "Options", resourceKit.OptionsType, TypeDeclarationAccessibility.Public) + ; } if (context.HostKit.ShouldGenerateOptions) @@ -109,14 +112,14 @@ CancellationToken cancellationToken ); using ( - context.Writer.WriteClassScope( + context.Writer.ClassScope( new(resourceKit.OptionsType, TypeDeclarationAccessibility.Public) { IsSealed = true, IsPartial = true } ) ) { context .Writer.XmlSummary("Gets or sets the logical name used to register the resource.") - .WriteProperty( + .Property( new("Name", PurviewTypeLibrary.System.String, TypeDeclarationAccessibility.Public) { IsInitOnly = true, @@ -133,7 +136,7 @@ CancellationToken cancellationToken context .Writer.XmlSummary("Gets or sets whether the resource is enabled.") - .WriteProperty( + .Property( new("IsEnabled", PurviewTypeLibrary.System.Boolean, TypeDeclarationAccessibility.Public) { IsInitOnly = true, diff --git a/src/src/SourceGeneration/Helpers/CodeGenEmiiter.cs b/src/src/SourceGeneration/Helpers/CodeGenEmiiter.cs index 062c95a..40ffba7 100644 --- a/src/src/SourceGeneration/Helpers/CodeGenEmiiter.cs +++ b/src/src/SourceGeneration/Helpers/CodeGenEmiiter.cs @@ -8,11 +8,11 @@ public static CodeWriter Emit(OutputContext outputContext, CancellationToken can { var writer = outputContext.Writer; writer - .WriteAutoGeneratedHeader(pragmas: ["CS8601", "CS8618"]) - .WriteUsing(TypeLibrary.ConfigurationBinder.Namespace!) - .WriteUsing(TypeLibrary.IServiceCollection.Namespace!) - .WriteUsing(TypeLibrary.OptionsBuilder.Namespace!) - .WriteUsing(TypeLibrary.Action.Namespace!); + .AutoGeneratedHeader(pragmas: ["CS8601", "CS8618"]) + .Using(TypeLibrary.ConfigurationBinder.Namespace!) + .Using(TypeLibrary.IServiceCollection.Namespace!) + .Using(TypeLibrary.OptionsBuilder.Namespace!) + .Using(TypeLibrary.Action.Namespace!); cancellationToken.ThrowIfCancellationRequested(); diff --git a/src/src/SourceGeneration/Helpers/InvocationWriter.cs b/src/src/SourceGeneration/Helpers/InvocationWriter.cs index bd53780..efb85fd 100644 --- a/src/src/SourceGeneration/Helpers/InvocationWriter.cs +++ b/src/src/SourceGeneration/Helpers/InvocationWriter.cs @@ -29,7 +29,7 @@ public static CodeWriter WriteArgumentList( } else { - writer.WriteLine("("); + writer.Line("("); writer.Indented(indented => { for (var index = 0; index < arguments.Count; index++) diff --git a/src/src/SourceGeneration/Helpers/SourceGenLibrary.cs b/src/src/SourceGeneration/Helpers/SourceGenLibrary.cs index 8fc76b5..17ab5fb 100644 --- a/src/src/SourceGeneration/Helpers/SourceGenLibrary.cs +++ b/src/src/SourceGeneration/Helpers/SourceGenLibrary.cs @@ -1,9 +1,9 @@ -using System.Collections.Concurrent; -using System.Collections.Immutable; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; using Purview.Aspire.ResourceKit.SourceGeneration.Models; +using System.Collections.Concurrent; +using System.Collections.Immutable; namespace Purview.Aspire.ResourceKit.SourceGeneration.Helpers; diff --git a/src/src/SourceGeneration/HostKitGenerator.cs b/src/src/SourceGeneration/HostKitGenerator.cs index ea11250..3afec17 100644 --- a/src/src/SourceGeneration/HostKitGenerator.cs +++ b/src/src/SourceGeneration/HostKitGenerator.cs @@ -1,7 +1,7 @@ -using System.Collections.Immutable; using Microsoft.CodeAnalysis; using Purview.Aspire.ResourceKit.SourceGeneration.Helpers; using Purview.Aspire.ResourceKit.SourceGeneration.Models; +using System.Collections.Immutable; namespace Purview.Aspire.ResourceKit.SourceGeneration; @@ -44,7 +44,7 @@ public void Initialize(IncrementalGeneratorInitializationContext context) return; var validResourceKits = generationModel - .ResourceKits.AsImmutableArray() + .ResourceKits .Select(m => new ResourceKitModelGroup( m.Namespace, EquatableArray.Create([ diff --git a/src/src/SourceGeneration/SourceGeneration.csproj b/src/src/SourceGeneration/SourceGeneration.csproj index 5fe1036..16f437e 100644 --- a/src/src/SourceGeneration/SourceGeneration.csproj +++ b/src/src/SourceGeneration/SourceGeneration.csproj @@ -2,6 +2,7 @@ true + $(NoWarn);PSGFR19; diff --git a/src/tests/SourceGeneration.IntegrationTests/Infrastructure/TestHelper.cs b/src/tests/SourceGeneration.IntegrationTests/Infrastructure/TestHelper.cs index fb10af7..71fcd23 100644 --- a/src/tests/SourceGeneration.IntegrationTests/Infrastructure/TestHelper.cs +++ b/src/tests/SourceGeneration.IntegrationTests/Infrastructure/TestHelper.cs @@ -21,19 +21,19 @@ public static string GenerateAspireResource(TypeIdentity? typeIdentity = null) var writer = CodeWriter.CreateTestWriter(); - using (writer.WriteBlockNamespaceScope(typeIdentity)) + using (writer.BlockNamespaceScope(typeIdentity)) { - writer.WriteClass( + writer.Class( new(resourceIdentity, TypeDeclarationAccessibility.Public) { Interfaces = [TypeLibrary.IResource] }, bodyWriter => bodyWriter - .WriteProperty( + .Property( new("Name", PurviewTypeLibrary.System.String, TypeDeclarationAccessibility.Public) { ExpressionBody = $"\"{resourceIdentity.Name}\"", } ) - .WriteProperty( + .Property( new("Annotations", TypeLibrary.ResourceAnnotations, TypeDeclarationAccessibility.Public) { ExpressionBody = "[]", @@ -93,8 +93,8 @@ public static string GenerateHostKit( #pragma warning restore CA1308 // Normalize strings to uppercase writer - .WriteFileScopedNamespace(namespaceName) - .WriteClass( + .FileScopedNamespace(namespaceName) + .Class( new(hostKitName, TypeDeclarationAccessibility.Public) { BaseType = baseClass is null ? null : new TypeIdentity(baseClass, null).AsTypeReference(), @@ -128,15 +128,15 @@ baseClass is null ); writer - .WriteFileScopedNamespace(namespaceName) - .WriteClass( + .FileScopedNamespace(namespaceName) + .Class( new(resourceKitName, TypeDeclarationAccessibility.Public) { BaseType = baseType, IsPartial = true, Attributes = [resourceDefinitionAttribute], }, - bodyWriter => bodyWriter.WriteLine(GenerateBuildResourceMethod(aspireResource)) + bodyWriter => bodyWriter.Line(GenerateBuildResourceMethod(aspireResource)) ); return writer.ToString();