Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Changed

- **DP086 assemble-contract copy**: message/description now name sync product `T` and async `Task<T>` / `ValueTask<T>` as valid `[BuilderAssemble]` returns, and call out void, bare `Task`/`ValueTask`, duplicate assemble, and multiple `CancellationToken` as illegal ([#325](https://github.com/Skymly/DesignPatterns/issues/325); Relates to [#324](https://github.com/Skymly/DesignPatterns/issues/324)).
- **F3 Work Graph MVP complete**: ROADMAP Top-3 marked `[x]` after Samples [DesignPatterns.Samples#25](https://github.com/Skymly/DesignPatterns.Samples/issues/25) / [PR#28](https://github.com/Skymly/DesignPatterns.Samples/pull/28); Design Doc references the request-prep sample; Spec [#308](https://github.com/Skymly/DesignPatterns/issues/308) closed (Phase 2+ Dop/trace/DI/unregistered Analyzer deferred).
- **Peer-presence Unregistered\* base**: extract `UnregisteredPayloadPeerAnalyzerBase` for DP024 / DP044 / DP072; `UnregisteredHandlerAnalyzer`, `UnregisteredEventHandlerAnalyzer`, and `UnregisteredCommandHandlerAnalyzer` become thin adapters supplying attribute-peer and declared-peer extraction. Strategy/Factory contract-peer base unchanged. Diagnostic behaviour frozen (including no `IStreamCommandHandler` peer-presence).
- **DI registration map consumer seam**: `CaptiveDependencyAnalyzer` and `SingletonLifecycleAnalyzer` obtain the map only via `DiRegistrationMap.Build(Compilation)` at compilation analysis time; incremental `DiRegistrationMapBuilder` wiring is a private implementation detail of `Build`. Diagnostic behaviour for DP062/066/068–071 is unchanged. `Build` skips generated syntax trees (`.g.cs` / auto-generated headers) so visibility matches the prior `RegisterSyntaxNodeAction` + `GeneratedCodeAnalysisFlags.None` path.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -736,8 +736,8 @@ public static class DesignPatternsDiagnosticDescriptors
public static DiagnosticDescriptor GenerateBuilderAssembleContractMismatch { get; } = Create(
DiagnosticIds.GenerateBuilderAssembleContractMismatch,
"GenerateBuilder assemble method contract is invalid",
"Method '{0}' on holder '{1}' is marked [BuilderAssemble] but does not satisfy the assemble contract (exactly one assemble method returning a non-void product type). Fix the signature or remove duplicate [BuilderAssemble] attributes.",
"The assemble method is the sole product factory for the generated builder and must return the product type.",
"Method '{0}' on holder '{1}' is marked [BuilderAssemble] but does not satisfy the assemble contract (exactly one assemble method returning sync product T, or async Task<T> / ValueTask<T>; not void, bare Task/ValueTask, or multiple CancellationToken parameters). Fix the signature or remove duplicate [BuilderAssemble] attributes.",
"The assemble method is the sole product factory for the generated builder. Return sync product type T, or async Task<T>/ValueTask<T>. Reject void, bare Task/ValueTask, duplicate [BuilderAssemble], and more than one CancellationToken.",
DiagnosticSeverity.Error,
GeneratorCategory);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[
{
Id: DP086,
Message: Method 'Assemble' on holder 'VoidAssembleSchema' is marked [BuilderAssemble] but does not satisfy the assemble contract (exactly one assemble method returning a non-void product type). Fix the signature or remove duplicate [BuilderAssemble] attributes.
Message: Method 'Assemble' on holder 'VoidAssembleSchema' is marked [BuilderAssemble] but does not satisfy the assemble contract (exactly one assemble method returning sync product T, or async Task<T> / ValueTask<T>; not void, bare Task/ValueTask, or multiple CancellationToken parameters). Fix the signature or remove duplicate [BuilderAssemble] attributes.
}
]
Original file line number Diff line number Diff line change
Expand Up @@ -145,13 +145,20 @@ public void Invalid_holder_descriptor_is_generator_error_with_actionable_message
public void Assemble_contract_mismatch_descriptor_is_generator_error_with_actionable_message()
{
var descriptor = DesignPatternsDiagnosticDescriptors.GenerateBuilderAssembleContractMismatch;
var message = descriptor.MessageFormat.ToString();
var description = descriptor.Description.ToString();

Assert.Equal(DiagnosticIds.GenerateBuilderAssembleContractMismatch, descriptor.Id);
Assert.Equal(DiagnosticSeverity.Error, descriptor.DefaultSeverity);
Assert.Equal("DesignPatterns.Generators", descriptor.Category);
Assert.Equal(DiagnosticHelpLinks.For(descriptor.Id), descriptor.HelpLinkUri);
Assert.False(string.IsNullOrWhiteSpace(descriptor.Description.ToString()));
Assert.Contains("[BuilderAssemble]", descriptor.MessageFormat.ToString(), StringComparison.Ordinal);
Assert.Contains("{0}", descriptor.MessageFormat.ToString(), StringComparison.Ordinal);
Assert.False(string.IsNullOrWhiteSpace(description));
Assert.Contains("[BuilderAssemble]", message, StringComparison.Ordinal);
Assert.Contains("{0}", message, StringComparison.Ordinal);
Assert.Contains("{1}", message, StringComparison.Ordinal);
Assert.Contains("Task<T>", message, StringComparison.Ordinal);
Assert.Contains("ValueTask<T>", message, StringComparison.Ordinal);
Assert.Contains("Task<T>", description, StringComparison.Ordinal);
Assert.Contains("ValueTask<T>", description, StringComparison.Ordinal);
}
}
Loading