Implement global MSBuild defaults for [Projectable] options#191
Implement global MSBuild defaults for [Projectable] options#191
Conversation
…ce attribute handling
There was a problem hiding this comment.
Pull request overview
Adds support for project-wide defaults for [Projectable] options by flowing MSBuild global properties (CompilerVisibleProperty → build_property.*) into the generator and applying them as fallbacks when the attribute doesn’t specify an option.
Changes:
- Introduces
ProjectableGlobalOptionsand wires global analyzer config options into the incremental generator pipeline. - Updates attribute snapshotting to preserve “unset vs explicitly set” semantics (nullable option fields) so member-level settings can override global defaults.
- Adds generator tests that inject MSBuild global properties via
AnalyzerConfigOptionsProvider.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/EntityFrameworkCore.Projectables.Generator.Tests/ProjectionExpressionGeneratorTestsBase.cs | Adds a new RunGenerator overload and helper types to inject MSBuild global properties in generator tests. |
| tests/EntityFrameworkCore.Projectables.Generator.Tests/GlobalOptionsTests.cs | New tests validating global defaults and member-level overrides for key [Projectable] options. |
| src/EntityFrameworkCore.Projectables.Generator/ProjectionExpressionGenerator.cs | Plumbs global options into the generator pipeline and execution path. |
| src/EntityFrameworkCore.Projectables.Generator/Models/ProjectableGlobalOptions.cs | New model that snapshots build_property.Projectables_* values from global analyzer config options. |
| src/EntityFrameworkCore.Projectables.Generator/Models/ProjectableAttributeData.cs | Changes option fields to nullable so absence can fall back to global defaults. |
| src/EntityFrameworkCore.Projectables.Generator/Interpretation/ProjectableInterpreter.cs | Resolves effective option values with precedence: attribute → global MSBuild default → hard-coded fallback. |
| src/EntityFrameworkCore.Projectables.Generator/Comparers/MemberDeclarationSyntaxAndCompilationEqualityComparer.cs | Includes global options in incremental equality/hashing so changes invalidate cached results correctly. |
| src/EntityFrameworkCore.Projectables.Abstractions/build/EntityFrameworkCore.Projectables.Abstractions.props | Adds CompilerVisibleProperty declarations (and placeholder properties) to expose MSBuild values to the compiler/generator. |
| src/EntityFrameworkCore.Projectables.Abstractions/EntityFrameworkCore.Projectables.Abstractions.csproj | Packs the new .props file into the NuGet package. |
| { | ||
| if (globalOptions.TryGetValue("build_property.Projectables_NullConditionalRewriteSupport", out var nullConditionalStr) | ||
| && !string.IsNullOrEmpty(nullConditionalStr) | ||
| && Enum.TryParse<NullConditionalRewriteSupport>(nullConditionalStr, ignoreCase: true, out var nullConditional)) |
There was a problem hiding this comment.
Projectables_NullConditionalRewriteSupport is parsed with Enum.TryParse, which will also accept numeric values (and potentially undefined enum values) as valid. That means a malformed MSBuild value like 999 would silently become an effective option rather than being treated as "not set". Consider validating with Enum.IsDefined (or rejecting numeric-only inputs) so malformed values are ignored consistently with the bool options tests.
| && Enum.TryParse<NullConditionalRewriteSupport>(nullConditionalStr, ignoreCase: true, out var nullConditional)) | |
| && Enum.TryParse<NullConditionalRewriteSupport>(nullConditionalStr, ignoreCase: true, out var nullConditional) | |
| && Enum.IsDefined(typeof(NullConditionalRewriteSupport), nullConditional)) |
...FrameworkCore.Projectables.Abstractions/EntityFrameworkCore.Projectables.Abstractions.csproj
Outdated
Show resolved
Hide resolved
…orkCore.Projectables.Abstractions.csproj Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Introduce global MSBuild defaults for [Projectable] options, enhancing attribute handling and allowing for project-wide configuration. This change enables the use of global settings while maintaining the ability to override them at the member level.
closes #133