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
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ ExpressiveSharp.EntityFrameworkCore.CodeFixers (Roslyn analyzer, netstandard2.0)

### Diagnostics

22 diagnostic codes (EXP0001–EXP0012, EXP0018 in `src/ExpressiveSharp.Generator/Infrastructure/Diagnostics.cs`, EXP0013 in CodeFixers, EXP0014–EXP0020 for `[ExpressiveFor]` validation, EXP0036/EXP0037 in `WindowFunctionLiteralArgsAnalyzer`). Key ones: EXP0001 (requires body), EXP0004 (block body requires opt-in), EXP0008 (unsupported operation, default value used), EXP0018 (unsupported operation ignored, e.g. alignment specifiers), EXP0019 (`[ExpressiveFor]` conflicts with `[Expressive]`), EXP0036 (`Ntile` non-positive literal), EXP0037 (`Lag`/`Lead` negative literal offset).
34 diagnostic codes: a contiguous `EXP0001–EXP0031` plus the migration band `EXP1001–EXP1003`. Generator diagnostics live in `src/ExpressiveSharp.Generator/Infrastructure/Diagnostics.cs` (`EXP0001–EXP0012` core `[Expressive]`, `EXP0013–EXP0017` `[ExpressiveFor]`, `EXP0018–EXP0022` `[ExpressiveProperty]`, `EXP0023` ignored operation, `EXP0024` virtual member); analyzer diagnostics `EXP0025–EXP0029` in `ExpressiveSharp.CodeFixers`; window-function diagnostics `EXP0030`/`EXP0031` in `WindowFunctionLiteralArgsAnalyzer` (`EntityFrameworkCore.CodeFixers`); migration `EXP1001–EXP1003` in `MigrationAnalyzer`. The canonical reference is `docs/reference/diagnostics.md`. Key ones: EXP0001 (requires body), EXP0004 (block body requires opt-in), EXP0008 (unsupported operation, default value used), EXP0023 (unsupported operation ignored, e.g. alignment specifiers), EXP0016 (`[ExpressiveFor]` conflicts with `[Expressive]`), EXP0030 (`Ntile` non-positive literal), EXP0031 (`Lag`/`Lead` negative literal offset).

## Testing

Expand Down
10 changes: 5 additions & 5 deletions docs/advanced/limitations.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,20 +115,20 @@ static bool IsNullOrWhiteSpace(string? s)

Expression-tree expansion happens at **compile time** and works purely from the **static (declared) type** of each receiver. It has no runtime instance to inspect, so it cannot honor C# virtual dispatch.

If you mark a `virtual`, `abstract`, or `override` member `[Expressive]` (a default interface member counts too -- it is implicitly virtual), the generator reports [EXP0038](../reference/diagnostics#exp0038). When the member is expanded for a query provider (EF Core, MongoDB), the call is resolved against the declared type and the **base** body is always inlined -- an overridden body in a derived type is never used:
If you mark a `virtual`, `abstract`, or `override` member `[Expressive]` (a default interface member counts too -- it is implicitly virtual), the generator reports [EXP0024](../reference/diagnostics#exp0024). When the member is expanded for a query provider (EF Core, MongoDB), the call is resolved against the declared type and the **base** body is always inlined -- an overridden body in a derived type is never used:

```csharp
public class Animal
{
public string Name { get; set; } = "";

[Expressive] // EXP0038
[Expressive] // EXP0024
public virtual string Describe() => $"Animal: {Name}";
}

public class Dog : Animal
{
[Expressive] // EXP0038
[Expressive] // EXP0024
public override string Describe() => $"Dog: {Name}";
}

Expand All @@ -152,7 +152,7 @@ db.Animals.AsExpressive().Select(a => a switch

### Recommended: use a non-virtual static/extension method

Move the logic into a single non-virtual `[Expressive]` method that performs the type test itself. This keeps the polymorphic shape in one place and produces no EXP0038:
Move the logic into a single non-virtual `[Expressive]` method that performs the type test itself. This keeps the polymorphic shape in one place and produces no EXP0024:

```csharp
public static class AnimalExpressions
Expand All @@ -169,7 +169,7 @@ db.Animals.AsExpressive().Select(a => a.Describe());
```

::: tip
Declaring entity members `virtual` is common in EF Core because it enables lazy-loading proxies. That remains fine for plain navigation and scalar properties -- EXP0038 only concerns members you *also* mark `[Expressive]`.
Declaring entity members `virtual` is common in EF Core because it enables lazy-loading proxies. That remains fine for plain navigation and scalar properties -- EXP0024 only concerns members you *also* mark `[Expressive]`.
:::

## Performance: First-Execution Overhead
Expand Down
2 changes: 1 addition & 1 deletion docs/guide/window-functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ The package was previously labeled experimental. Upgrading is API-compatible; th

- Direct invocation of a `WindowFunction.*` stub (i.e. outside an EF Core query) now throws an exception that names the method and points at this guide.
- `Ntile(0)` / `Ntile(-1)`, negative literal `Lag`/`Lead` offsets, and `NthValue(0)` now throw `InvalidOperationException` at translation time. Previously these reached the database and produced a provider-specific error.
- New analyzer warnings **EXP0036** (`Ntile` non-positive literal buckets) and **EXP0037** (`Lag`/`Lead` negative literal offsets) may surface on existing code.
- New analyzer warnings **EXP0030** (`Ntile` non-positive literal buckets) and **EXP0031** (`Lag`/`Lead` negative literal offsets) may surface on existing code.

## Next Steps

Expand Down
2 changes: 1 addition & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ features:

- icon: "\U0001FA7A"
title: Roslyn Analyzers & Code Fixes
details: EXP0001–EXP0036 diagnostics catch projection errors at compile time. Quick-fix actions and migration fixers from Projectables included.
details: EXP0001–EXP0031 diagnostics catch projection errors at compile time. Quick-fix actions and migration fixers from Projectables included.
---

## At a Glance
Expand Down
12 changes: 6 additions & 6 deletions docs/recipes/external-member-mapping.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Use `[ExpressiveFor]` when:
- You want to override how a specific member translates to SQL

::: info
If a member already has `[Expressive]`, adding `[ExpressiveFor]` targeting it is a compile error (EXP0019). `[ExpressiveFor]` is specifically for members that **do not** have `[Expressive]`.
If a member already has `[Expressive]`, adding `[ExpressiveFor]` targeting it is a compile error (EXP0016). `[ExpressiveFor]` is specifically for members that **do not** have `[Expressive]`.
:::

## Static Method: `Math.Clamp`
Expand Down Expand Up @@ -189,11 +189,11 @@ static class DateTimeMappings

| Code | Description |
|------|-------------|
| EXP0014 | `[ExpressiveFor]` target type not found |
| EXP0015 | `[ExpressiveFor]` target member not found on the specified type |
| EXP0017 | Return type of stub does not match target member's return type |
| EXP0019 | Target member already has `[Expressive]` -- use `[Expressive]` directly instead |
| EXP0020 | Duplicate `[ExpressiveFor]` mapping for the same target member |
| EXP0013 | `[ExpressiveFor]` target type not found |
| EXP0014 | `[ExpressiveFor]` target member not found on the specified type |
| EXP0015 | Return type of stub does not match target member's return type |
| EXP0016 | Target member already has `[Expressive]` -- use `[Expressive]` directly instead |
| EXP0017 | Duplicate `[ExpressiveFor]` mapping for the same target member |

## Tips

Expand Down
Loading
Loading