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
18 changes: 17 additions & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,20 @@ resharper_redundant_nullable_warning_suppression_highlighting = none

[**/src/**/*.cs]
# CA1859 requires concrete types for performance; Rider's suggestion to widen conflicts
resharper_parameter_type_can_be_enumerable_local_highlighting = none
resharper_parameter_type_can_be_enumerable_local_highlighting = none

# ============================================================================
# Generator-Specific Suppressions
# ============================================================================

# Polyfills.cs: Types MUST live in System.* namespaces for netstandard2.0
# compatibility (e.g., System.Runtime.CompilerServices.IsExternalInit).
# The namespace intentionally does not match the folder structure.
[**/ErrorOrX.Generators/Polyfills.cs]
dotnet_diagnostic.IDE0130.severity = none

# Extractor.cs: AL0029 flags foreach-over-GetAttributes() loops, suggesting
# HasAttribute() instead. These loops legitimately need to extract constructor
# arguments and named arguments from AttributeData, not just check existence.
[**/ErrorOrX.Generators/Core/ErrorOrEndpointGenerator.Extractor.cs]
dotnet_diagnostic.AL0029.severity = none
22 changes: 19 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,25 @@ All notable changes to this project are documented in this file.

## [Unreleased]

## [3.4.0] - 2026-02-07

### Changed

- **Test suite cleanup**: Removed redundant assertion-based tests (-7,823 lines), consolidated shared boilerplate into
dedicated snapshot tests. 446 tests remain with identical coverage.

- **Updated dependencies**: ANcpLua.Roslyn.Utilities 1.28.0 → 1.30.2, cleaned up .editorconfig with generator-specific
suppression rationale.

- **Generator code cleanup**: Removed unused `ParameterSource` properties, simplified constructor signatures, added
documentation comments for suppressed warnings in .csproj.

### Fixed

- **Integration tests missing from solution**: Added `ErrorOrX.Integration.Tests` to `ErrorOrX.slnx`.

- **Documentation accuracy**: Fixed README analyzer count (38 → 41), corrected CLAUDE.md dependency versions.

## [3.3.0] - 2026-02-04

### Removed
Expand Down Expand Up @@ -47,9 +66,6 @@ All notable changes to this project are documented in this file.

### Added

- **EOE055 Diagnostic**: Warning when multiple method parameters bind to the same route parameter name. Helps catch
configuration errors early instead of silent "first wins" behavior.

- **BugRegressionTests**: New test class with regression tests for BUG-001 through BUG-005 to prevent future regressions.

- **DiagnosticTests**: Comprehensive test class covering 26 diagnostic scenarios including EOE003 (route parameter not bound),
Expand Down
4 changes: 2 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -215,8 +215,8 @@ tests/

| Package | Version | Purpose |
|----------------------------------|---------|---------------------------------|
| ANcpLua.Roslyn.Utilities | 1.28.0 | Incremental generator utilities |
| ANcpLua.Roslyn.Utilities.Testing | 1.28.0 | Generator testing framework |
| ANcpLua.Roslyn.Utilities | 1.31.0 | Incremental generator utilities |
| ANcpLua.Roslyn.Utilities.Testing | 1.31.0 | Generator testing framework |
| ANcpLua.Analyzers | 1.13.0 | Code quality analyzers |
| Microsoft.CodeAnalysis.CSharp | 5.0.0 | Roslyn APIs |
| xunit.v3 | 3.2.2 | Testing framework |
Expand Down
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<Import Project="$(MSBuildThisFileDirectory)version.props"/>

<PropertyGroup>
<ANcpLuaRoslynUtilitiesVersion>1.28.0</ANcpLuaRoslynUtilitiesVersion>
<ANcpLuaRoslynUtilitiesVersion>1.31.0</ANcpLuaRoslynUtilitiesVersion>
</PropertyGroup>

<PropertyGroup>
Expand Down
5 changes: 2 additions & 3 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
<PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="3.11.0"/>
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="5.0.0"/>
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="5.0.0"/>
<PackageVersion Include="ANcpLua.Roslyn.Utilities" Version="1.30.1"/>
<PackageVersion Include="ANcpLua.Roslyn.Utilities.Testing" Version="1.30.1"/>
<PackageVersion Include="ANcpLua.Roslyn.Utilities" Version="1.31.0"/>
<PackageVersion Include="ANcpLua.Roslyn.Utilities.Testing" Version="1.31.0"/>
<PackageVersion Update="Microsoft.CodeAnalysis.BannedApiAnalyzers" Version="3.3.4"/>
<PackageVersion Update="Microsoft.Sbom.Targets" Version="4.1.5"/>
<PackageVersion Include="ErrorProne.NET.CoreAnalyzers" Version="0.8.2-beta.1"/>
Expand All @@ -20,7 +20,6 @@
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="10.0.102"/>
<PackageVersion Include="Microsoft.Bcl.HashCode" Version="6.0.0"/>
<PackageVersion Include="Verify.XunitV3" Version="31.10.0"/>
<PackageVersion Include="Verify.SourceGenerators" Version="2.5.0"/>
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp.SourceGenerators.Testing" Version="1.1.3"/>
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp.Analyzer.Testing" Version="1.1.3"/>
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp.CodeFix.Testing" Version="1.1.3"/>
Expand Down
1 change: 1 addition & 0 deletions ErrorOrX.slnx
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,6 @@
<Folder Name="/tests/">
<Project Path="tests/ErrorOrX.Tests/ErrorOrX.Tests.csproj"/>
<Project Path="tests/ErrorOrX.Generators.Tests/ErrorOrX.Generators.Tests.csproj"/>
<Project Path="tests/ErrorOrX.Integration.Tests/ErrorOrX.Integration.Tests.csproj"/>
</Folder>
</Solution>
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Native AOT support.
- **Middleware Support** - Translates ASP.NET Core attributes to Minimal API fluent calls (authorization, rate limiting,
caching)
- **API Versioning** - Integrates with Asp.Versioning.Http for versioned endpoint groups
- **38 Analyzers** - Real-time IDE feedback for route conflicts, binding errors, AOT compatibility
- **41 Analyzers** - Real-time IDE feedback for route conflicts, binding errors, AOT compatibility

## What the Generator Produces

Expand Down
28 changes: 14 additions & 14 deletions global.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
{
"sdk": {
"version": "10.0.102",
"rollForward": "minor",
"allowPrerelease": true
},
"msbuild-sdks": {
"ANcpLua.NET.Sdk": "2.0.2",
"ANcpLua.NET.Sdk.Web": "2.0.2",
"ANcpLua.NET.Sdk.Test": "2.0.2"
},
"test": {
"runner": "Microsoft.Testing.Platform"
}
}
"sdk": {
"version": "10.0.102",
"rollForward": "minor",
"allowPrerelease": true
},
"msbuild-sdks": {
"ANcpLua.NET.Sdk": "2.0.5",
"ANcpLua.NET.Sdk.Web": "2.0.5",
"ANcpLua.NET.Sdk.Test": "2.0.5"
},
"test": {
"runner": "Microsoft.Testing.Platform"
}
}
2 changes: 2 additions & 0 deletions samples/DiagnosticsDemos/Demos/EOE001_InvalidReturnType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ public static class EOE001_InvalidReturnType
public static ErrorOr<string> GetValidSync()
{
return "valid response";


}
Comment on lines 34 to 37
Copy link

Copilot AI Feb 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are two consecutive blank lines inside GetValidSync() after the return statement. This looks accidental and adds noise in the demo file; consider removing the extra empty lines so the method body matches the surrounding style.

Copilot uses AI. Check for mistakes.

// -------------------------------------------------------------------------
Expand Down
9 changes: 0 additions & 9 deletions src/ErrorOrX.Generators/Analyzers/AotSafetyAnalyzer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -243,15 +243,6 @@ private static string GetTypeArgument(IMethodSymbol method, InvocationExpression
return "T";
}

private static string? GetFirstStringArgument(InvocationExpressionSyntax invocation)
{
if (invocation.ArgumentList.Arguments.Count is 0)
return null;

var firstArg = invocation.ArgumentList.Arguments[0].Expression;
return firstArg is LiteralExpressionSyntax { Token.Value: string value } ? value : firstArg.ToString();
}

private static string? GetReceiverTypeName(InvocationExpressionSyntax invocation, SemanticModel semanticModel)
{
if (invocation.Expression is not MemberAccessExpressionSyntax memberAccess)
Expand Down
36 changes: 18 additions & 18 deletions src/ErrorOrX.Generators/Analyzers/ErrorOrEndpointAnalyzer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -196,22 +196,22 @@ private static void CheckForValidationAttributes(
foreach (var param in method.Parameters)
{
foreach (var attr in param.GetAttributes())
{
if (attr.AttributeClass is null)
continue;

// Check if the attribute inherits from ValidationAttribute
if (InheritsFrom(attr.AttributeClass, validationAttributeType))
{
context.ReportDiagnostic(Diagnostic.Create(
Descriptors.ValidationUsesReflection,
param.Locations.FirstOrDefault() ?? method.Locations.FirstOrDefault(),
param.Name,
method.Name));
break; // Only report once per parameter
if (attr.AttributeClass is null)
continue;

// Check if the attribute inherits from ValidationAttribute
if (InheritsFrom(attr.AttributeClass, validationAttributeType))
{
context.ReportDiagnostic(Diagnostic.Create(
Descriptors.ValidationUsesReflection,
param.Locations.FirstOrDefault() ?? method.Locations.FirstOrDefault(),
param.Name,
method.Name));
break; // Only report once per parameter
}
}
Comment on lines 198 to 213
Copy link

Copilot AI Feb 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This foreach loop implicitly filters its target sequence - consider filtering the sequence explicitly using '.Where(...)'.

Copilot uses AI. Check for mistakes.
}
}
}

/// <summary>
Expand Down Expand Up @@ -419,11 +419,11 @@ private static bool IsFormCollection(ISymbol type)
break;
// Generic endpoint attribute - extract HTTP method from first constructor arg
case "ErrorOrEndpointAttribute" or "ErrorOrEndpoint":
{
if (attr.ConstructorArguments is [{ Value: string m }, ..])
httpMethod = m.ToUpperInvariant();
break;
}
{
if (attr.ConstructorArguments is [{ Value: string m }, ..])
httpMethod = m.ToUpperInvariant();
break;
}
}

if (httpMethod is null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ private static void AnalyzeJsonContextCoverage(
foreach (var ctx in userContexts)
{
foreach (var typeFqn in ctx.SerializableTypes)
registeredTypes.Add(typeFqn);
registeredTypes.Add(typeFqn);
}

// Combine all needed types
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ private static void EmitMappings(SourceProductionContext spc, ImmutableArray<End
foreach (var ctx in groupContexts)
{
foreach (var indexed in ctx.Group.Endpoints)
GroupEmitter.EmitGroupedMapCall(code, in indexed, ctx.GroupVariableName, maxArity);
GroupEmitter.EmitGroupedMapCall(code, in indexed, ctx.GroupVariableName, maxArity);
}

// Emit ungrouped endpoint mappings (legacy pattern)
Expand Down Expand Up @@ -797,7 +797,7 @@ private static void EmitJsonContextHelper(SourceProductionContext spc, List<stri
foreach (var ctx in userContexts)
{
foreach (var typeFqn in ctx.SerializableTypes)
registeredTypes.Add(typeFqn);
registeredTypes.Add(typeFqn);
}

// Find missing types
Expand Down
Loading