[WIP] Add support for EFP0013 diagnostic for unsupported expressions in projectable members#192
[WIP] Add support for EFP0013 diagnostic for unsupported expressions in projectable members#192
Conversation
…jectable members - Introduced new diagnostic descriptor for unsupported expressions. - Updated DeclarationSyntaxRewriter and ExpressionSyntaxRewriter to report diagnostics for unsupported syntax nodes. - Added tests to ensure correct diagnostics are emitted for various unsupported expressions.
There was a problem hiding this comment.
Pull request overview
Adds a new generator diagnostic (EFP0013) to explicitly flag C# syntax/features that can’t be represented in expression trees, so projectable members fail with a clear error instead of producing unusable output.
Changes:
- Introduces
Diagnostics.UnsupportedExpressionInProjectable(EFP0013) and documents it inAnalyzerReleases.Unshipped.md. - Updates
ExpressionSyntaxRewriterto detect/report EFP0013 for collection expressions, index-from-end (^), range (..), primary-constructor parameter references, and the C# 14fieldkeyword. - Updates
DeclarationSyntaxRewriterto detect/report EFP0013 for ref-like parameter types, and adds unit tests covering these scenarios.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| tests/EntityFrameworkCore.Projectables.Generator.Tests/UnsupportedExpressionTests.cs | Adds unit tests asserting EFP0013 is produced for several unsupported constructs. |
| src/EntityFrameworkCore.Projectables.Generator/SyntaxRewriters/ExpressionSyntaxRewriter.cs | Reports EFP0013 for several unsupported expression syntax nodes and primary-constructor parameter references. |
| src/EntityFrameworkCore.Projectables.Generator/SyntaxRewriters/DeclarationSyntaxRewriter.cs | Reports EFP0013 for ref-like parameter types in projectable signatures. |
| src/EntityFrameworkCore.Projectables.Generator/Interpretation/ProjectableInterpreter.cs | Wires SourceProductionContext / owning method info into the rewriters. |
| src/EntityFrameworkCore.Projectables.Generator/Infrastructure/Diagnostics.cs | Adds the EFP0013 DiagnosticDescriptor. |
| src/EntityFrameworkCore.Projectables.Generator/AnalyzerReleases.Unshipped.md | Records the new diagnostic in the analyzer release notes. |
| Diagnostics.UnsupportedExpressionInProjectable, | ||
| node.GetLocation(), | ||
| refLikeType.ToDisplayString(), | ||
| $"Ref-like types cannot be used as parameters in expression trees.")); |
There was a problem hiding this comment.
Reporting EFP0013 for ref-like parameter types is good, but the generator still proceeds to generate Expression<Func<...>> using that ref-like type in the Func<...> type arguments. Ref-like types (e.g. ReadOnlySpan<T>) cannot be used as generic arguments, so this will cause additional compiler errors in the generated .g.cs beyond EFP0013, undermining the goal of a single clear diagnostic. Consider short-circuiting descriptor generation for this member (return false from the body processor / GetDescriptor) or rewriting the parameter type to a safe placeholder solely to keep generated code compiling when EFP0013 is emitted.
| $"Ref-like types cannot be used as parameters in expression trees.")); | |
| $"Ref-like types cannot be used as parameters in expression trees.")); | |
| // Replace the ref-like parameter type with a non-ref-like placeholder to keep generated code compiling. | |
| visitedNode = ((ParameterSyntax)visitedNode).WithType( | |
| SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.ObjectKeyword))); |
This is the ground work for supporting additional C# features. This PR detects C# features that are not yet supported. Subsequent PR's may be issued to attempt to polyfill some of these
Features covered:
Collection expressions [1, 2, 3] (C# 12) — VisitCollectionExpression → EFP0013
Index-from-end operator ^n (C# 8+) — VisitPrefixUnaryExpression → EFP0013
Range operator a..b (C# 8+) — VisitRangeExpression → EFP0013
Primary constructor parameters referenced in projectable properties/methods (C# 12) — VisitIdentifierName → EFP0013
field keyword in property accessors (C# 14) — VisitFieldExpression → EFP0013
Ref-like type parameters (Span, ReadOnlySpan, etc.) in projectable method signatures (C# 13+) — DeclarationSyntaxRewriter.VisitParameter → EFP0013