Skip to content

fix(analyzers): teach regex quantifier heuristics character classes - #156

Merged
e128 merged 3 commits into
mainfrom
fix/regex-quantifier-classes
Nov 12, 2026
Merged

e128 merged 3 commits into
mainfrom
fix/regex-quantifier-classes

Conversation

@e128

@e128 e128 commented Nov 12, 2026

Copy link
Copy Markdown
Owner

Executive Summary

The 2.9.7 GeneratedRegexAnalyzer audit left three follow-ups in the roadmap. This PR delivers two of them.

E128014 false-positive cause: GeneratedRegexHelpers.GroupContainsInnerQuantifier counted * and + inside a character class as quantifiers, so a group holding [-*_] followed by + reported a nested-quantifier warning on a pattern that cannot backtrack. Class contents also broke the paren-matching scans. Fix: BuildCharacterClassMask marks every index inside a [...] class in one pass (leading ^, leading literal ], escapes, unterminated class), and all five scans skip masked indices. No public RegexParser API exists, so a full parse is not available.

Descriptor coverage cause: the same audit found descriptors that never reached SupportedDiagnostics, so rules could not report even when the node was reached. Fix: SupportedDiagnosticsCoverageTests enumerates all 208 analyzers and asserts the set is non-empty and covers every static DiagnosticDescriptor field. Reflection lives in helper methods because E128090 bans it in test methods. The scan covers fields only; a descriptor built inline in a getter would evade it, and none exists today.

Release: the branch carries the two unpushed main commits (the 2.9.7 version bump and the roadmap audit), so the version-bump gate keeps 2.9.7 and this PR delivers 2.9.7 with both fixes.

Code Changes

  • src/E128.Analyzers/Reliability/GeneratedRegexHelpers.cs: class mask plus class-aware scans
  • tests/E128.Analyzers.Tests/GeneratedRegexE128AnalyzerTests.cs: five class fixtures
  • tests/E128.Analyzers.Tests/SupportedDiagnosticsCoverageTests.cs: new sweep test
  • src/E128.Analyzers/README.md: install snippet version 2.9.0 to 2.9.7
  • lode/dotnet/analyzers/rule-details-reliability.md, lode/dotnet/analyzers/testing.md, plans/roadmap.md: docs

Tests and Tooling

  • New fixtures were RED before the fix and green after.
  • scripts/test.sh GeneratedRegexE128AnalyzerTests: 31/31. Sweep: 208/208.
  • scripts/check.sh --all: all green. Full suite: 2889 passed, 0 failed, 2 pre-existing skips.
  • Not run: coverage collection, benchmarks, Podman suite.

Review Guide

Start with BuildCharacterClassMask and the mask checks in GeneratedRegexHelpers, then the sweep test. The fixture names in GeneratedRegexE128AnalyzerTests map one to one to each false-positive shape.

Rollback

Revert the single squashed commit; the release files and the README revert with it.

Links

  • Roadmap audit: plans/roadmap.md, Analyzer Detection and Code Fix section

🤖 Generated with Claude Code

e128 and others added 3 commits November 11, 2026 22:00
…ial properties

Roslyn never delivers an attribute attached to a source-generated partial
property to a SyntaxKind.Attribute node action, and symbol actions skip the
property symbol. Registering on SyntaxKind.CompilationUnit and resolving each
descendant attribute through SemanticModel reaches every shape, including the
273 partial properties in pugworks that no rule had ever seen.

SupportedDiagnostics now lists all four descriptors, so E128013 and E128014
can report once reached.

Version 2.9.7.

Co-Authored-By: Claude Code <noreply@anthropic.com>
…xposed

Co-Authored-By: Claude Code <noreply@anthropic.com>
GeneratedRegexHelpers marks every index inside a regex character class and
skips marked indices in all scans, so a class holding * or + no longer reports
E128014 or E128013 on a pattern that cannot backtrack.
SupportedDiagnosticsCoverageTests sweeps every analyzer and asserts each static
DiagnosticDescriptor field reaches SupportedDiagnostics. The analyzer README
install snippet now matches version 2.9.7.

Co-Authored-By: Claude
@e128
e128 merged commit 672b0f8 into main Nov 12, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant