Add provider-emission config and replace reflection-based entry-assembly access#122
Conversation
…cess Implements the initial changes for two issues: #120 - Add configuration for which assemblies should emit the provider - New compiler-visible MSBuild property `IndagoEmitProvider` (default true) in build/Indago.props. - The generator now gates emission of the IndagoProvider implementation and its `[assembly: IndagoProviderAttribute]` on this property. Scan-metadata assembly attributes (used for cross-assembly cache reuse) are still emitted so library assemblies can opt out of emitting a provider while remaining scannable. #121 - Remove entry assembly / get-provider method; emit a generic provider - Removed the reflection-based access points: `IIndagoProvider.EntryAssembly`, `IndagoSupport.EntryAssembly`, and the `Assembly.GetIndagoProvider()` extension (IndagoProviderExtensions.cs deleted). - The generated provider is now an `internal sealed class` exposing a compile-time singleton `public static IIndagoProvider Instance`, so consumers reference `IndagoProvider.Instance` directly instead of resolving it through runtime reflection. - Migrated test input sources and updated the Readme accordingly. Generated-provider snapshots were updated with the corresponding mechanical transform; they should be reconciled with `dotnet verify accept` in a build environment, since the .NET SDK could not be installed here to regenerate them. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PBar5Fv87ybxm13xH1Zier
Not up to standards ⛔🔴 Issues
|
| Category | Results |
|---|---|
| Compatibility | 97 medium |
| CodeStyle | 3 minor |
🟢 Metrics 1717 complexity · 12915 duplication
Metric Results Complexity 1717 Duplication 12915
AI Reviewer: first review requested successfully. AI can make mistakes. Always validate suggestions.
TIP This summary will be updated as you push new changes.
There was a problem hiding this comment.
Pull Request Overview
While this PR successfully introduces a singleton pattern for better AOT compatibility and an MSBuild flag to control provider generation, it is currently not up to standards due to a high-severity compilation risk and verification gaps. Specifically, the use of modern APIs like MD5.HashData and ThrowIfNull inside a broad !NETSTANDARD2_0 block will cause build failures on .NET Core 3.1 and .NET Standard 2.1 targets.
A significant concern is that the author could not build or test the changes locally; consequently, 376 snapshots were updated mechanically without runtime verification. This is particularly problematic as there are no tests or snapshots confirming the behavior of the source generator when IndagoEmitProvider is set to false, which is a core feature of this PR. These gaps must be addressed before the PR is considered for merging.
About this PR
- The PR includes 376 snapshot updates that were performed mechanically without local build or test verification. Given the scope of changes to the source generator, these snapshots must be validated in a CI environment or a verified local environment to ensure no regressions in scanning logic or code structure.
1 comment outside of the diff
src/Indago/IndagoSupport.cs
line 21-34🔴 HIGH RISK
The usage of .HashData and ThrowIfNull inside the current #if !NETSTANDARD2_0 block will cause compilation errors on frameworks like netstandard2.1 or .NET Core 3.x where these APIs are unavailable. Refine the conditional logic to ensure these are only used on compatible platforms. Additionally, please restore the SuppressMessage attributes for CA5351 and CA1850 that were removed from the interface file, as MD5 usage still requires explicit suppression.
Test suggestions
- Generated provider is emitted with 'internal sealed' modifiers and an 'Instance' singleton member when IndagoEmitProvider is true (default).
- Consuming code can successfully resolve the scanner and execute scans using the static 'IndagoProvider.Instance' property.
- Source generator suppresses the emission of the provider class and its corresponding IndagoProviderAttribute when IndagoEmitProvider is set to false.
- Source generator still emits selector metadata attributes when IndagoEmitProvider is set to false, allowing downstream assemblies to consume its scan data.
Prompt proposal for missing tests
Consider implementing these tests if applicable:
1. Source generator suppresses the emission of the provider class and its corresponding IndagoProviderAttribute when IndagoEmitProvider is set to false.
2. Source generator still emits selector metadata attributes when IndagoEmitProvider is set to false, allowing downstream assemblies to consume its scan data.
Low confidence findings
- Changing the visibility of the generated IndagoProvider from 'file' to 'internal sealed' increases the risk of name collisions if consuming assemblies already define a type with that name. Ensure this is noted as a potential breaking change for consumers.
TIP Improve review quality by adding custom instructions
TIP How was this review? Give us feedback
| // public static IIndagoProvider Instance { get; } = new IndagoProvider(); | ||
| // Exposes the generated provider as a compile-time singleton so consumers can reference it | ||
| // directly (IndagoProvider.Instance) instead of resolving it through runtime reflection. |
There was a problem hiding this comment.
⚪ LOW RISK
Remove this commented-out code to avoid static analysis warnings. The descriptive documentation below it already explains the purpose and structure of the property.
| @@ -107,7 +107,7 @@ The scanner uses the compiler API to scan all assemblies and types of the given | |||
|
|
|||
| > I skipped something in the explination of the types earlier. Every method on the `IndagoProvider` takes in it's arguments but it also uses `CallerLineNumber`, `CallerFilePath` and `CallerArgumentExpression`. It then uses these values in a huge switch statement to determine which list of items to return. If the queries are all on different lines 1 jump, at most you'll have 2 jumps (unless you make some silly single long code!) | |||
There was a problem hiding this comment.
⚪ LOW RISK
Nitpick: Typo in 'explination' and incorrect use of 'it's' (it is) instead of 'its' (possessive).
…s-two-issues-owdvcn
Initial changes for #120 and #121.
#120 — Add configuration for which assemblies should emit the provider
IndagoEmitProvider(defaults totrue) insrc/Indago/build/Indago.props.IndagoProviderGeneratornow gates emission of theIndagoProviderimplementation and its[assembly: IndagoProviderAttribute]on this property.<IndagoEmitProvider>false</IndagoEmitProvider>to stay scannable while letting the consuming application be the one that emits the provider.#121 — Remove entry assembly / get-provider method; emit a generic provider where available
IIndagoProvider.EntryAssemblyIndagoSupport.EntryAssemblyAssembly.GetIndagoProvider()extension (IndagoProviderExtensions.csdeleted)internal sealed classthat exposes a compile-time singletonpublic static IIndagoProvider Instance, so consumers referenceIndagoProvider.Instancedirectly instead of resolving the provider throughAssembly.GetEntryAssembly()+ attribute reflection.typeof(X).Assembly.GetIndagoProvider()toIndagoProvider.Instance, and the Readme updated.The
IndagoProviderAttributeitself is retained (it still carries theGeneratedHashused for cross-assembly cache busting).The .NET SDK pinned in
global.json(10.0.301) could not be installed in this environment — the SDK download hosts (builds.dotnet.microsoft.com,ci.dot.net,dot.net) are blocked by the egress policy (HTTP 403). As a result I could not build, run the test suite, or regenerate snapshots here.*#IndagoProvider.g.verified.cs) were updated with the mechanical transform the regenerated generator should produce (file class→internal sealed class+ the newInstancemember). The data-model snapshots (*.verified.txt) are unchanged because behavior is unchanged.dotnet verify accept(or./build.sh Test) locally / in CI to confirm the generated output is byte-for-byte correct and reconcile any whitespace differences.Open design notes for review
internal(notfile) so the in-assemblyInstancesingleton is referenceable; this changes name visibility within the compilation. Confirm this is the intended "generic provider where it's available" shape (a public, cross-assembly-referenceable type would riskIndagoProvidername collisions between referenced assemblies, which Add configuration for which assemblies should emit the provider #120's opt-out is designed to avoid).🤖 Generated with Claude Code
Generated by Claude Code