Skip to content

feat!: Report operators that lead a wrapped line (NOTA0003) - #15

Merged
nanchen2483 merged 1 commit into
Notalib:mainfrom
henrikottesorensen:feat/operator-placement
Oct 8, 2026
Merged

nanchen2483 merged 1 commit into
Notalib:mainfrom
henrikottesorensen:feat/operator-placement

Conversation

@henrikottesorensen

@henrikottesorensen henrikottesorensen commented Oct 7, 2026 •

Copy link
Copy Markdown
Collaborator

What

Adds NOTA0003 (warning): when an expression wraps, the operator ends the line and the next line starts with the operand.

  • Nota.CodeAnalysis.Analysers + .CodeFixes: the analyser and a code fix that moves only the operator (whitespace-only, so dotnet format can bulk-convert). Both assemblies are packed into analyzers/dotnet/cs, and the package gains no dependencies. Built against Roslyn 4.8 so SDK 8 consumers don't skip them with CS9057.
  • Nota.CodeAnalysis.Analysers.Test: 40 unit tests. CI now runs dotnet test.
  • Globalconfig changes:
    • dotnet_style_operator_placement_when_wrapping flips from beginning_of_line to end_of_line.
    • Rider's csharp_wrap_before_binary_opsign / _binary_pattern_op / _ternary_opsigns are set to false.
    • csharp_style_expression_bodied_operators goes from false:silent to false:warning, so IDE0024 reports at build.

Breaking

Existing leading operators (NOTA0003) and expression-bodied operator overloads (IDE0024) start warning. Repos with TreatWarningsAsErrors will fail until converted. The README's new "Upgrading from 2.3" section has the commands:

dotnet format analyzers --diagnostics NOTA0003 --severity warn
dotnet format style --diagnostics IDE0024 --severity warn

Verification

  • verify.sh: NOTA0003 must report on Samples/LeadingOperator.cs. The script also fails if anything reports on the trailing form the fix produces, so a StyleCop or IDE0055 rule can't start fighting the fix unnoticed.
  • verify-package.sh: NOTA0003 must reach a consumer installing the packed package, which proves the assemblies were packed.
  • I broke each new check on purpose (severity none, an extra diagnostic on the trailing form, analysers left out of the package), and each one failed as intended.
  • dotnet format with the packed package cleared every NOTA0003. dotnet format style converted an IDE0024 case.
  • After rebasing onto Stop NOTA0001 and NOTA0002 reporting files nobody can fix #14, I reran the build, the tests and all three scripts locally. All pass.

Unverified

I haven't checked whether Rider reads the csharp_wrap_before_* keys from a global analyzer config. If it doesn't, consumers need the three lines in their own .editorconfig. The README and a globalconfig comment both say so.

🤖 Generated with Claude Code

A new analyser, a code fix that moves only the operator, and their unit
tests. Both assemblies ship inside the package under analyzers/dotnet/cs,
built against Roslyn 4.8 so SDK 8 consumers do not skip them with CS9057.

The convention flips to match: dotnet_style_operator_placement_when_wrapping
is end_of_line, and Rider's three csharp_wrap_before_* keys are set the
same way. IDE0024 is also raised to a warning, so operator overloads get
block bodies.

Breaking: existing leading operators and expression-bodied operators
become warnings. dotnet format converts both; the README's upgrade
section has the commands.

verify.sh and verify-package.sh now assert NOTA0003 reports, and that
nothing reports the trailing form the fix produces.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@nanchen2483
nanchen2483 merged commit b0960d5 into Notalib:main Oct 8, 2026
1 check 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.

3 participants