Repository navigation
Add Nullable.Extended.Analyzer to the StandardAnalyzers module - #412
Conversation
A null-forgiving operator silences a nullable warning on an invariant that no type states, and Buildvana SDK reported none of them. Unless a `// !` comment above an operator states the invariant, the analyzer reports it. `UseNullableExtendedAnalyzer` follows `UseStyleCopAnalyzers`: on by default, and off for a `Microsoft.Build.NoTargets` project. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Only `UseNullableExtendedAnalyzer` had tests in `StandardAnalyzersModuleTargetsTests`. A regression in `EnableNETAnalyzers`, `AnalysisLevel`, `AnalysisMode`, `EnforceCodeStyleInBuild`, `UseStyleCopAnalyzers`, `UsePublicApiAnalyzers`, or the search for `stylecop.json` in `Module.UseStyleCopAnalyzers.targets` would pass the build. `EnableNETAnalyzers` and the three `Use*` properties share one pattern of defaults and stored values, so one matrix of tests covers all four. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The StyleCop and Public API sections of `.globalconfig` warned against setting severities in `.DotSettings` files. Only ReSharper reads those files, so the warning belongs in the ReSharper section of `.editorconfig` alone. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Also temporarily disable the analyzer in `Common.props`, lest the solution fail to build. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Dealing with null-forgiving operators is easier with a specialized MCP server. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
It was still at 1.18.0, while `Nullable.Extended.Mcp` was at 1.18.2. They are versioned together, so they're better kept at the same version. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #412 +/- ##
=======================================
Coverage 87.28% 87.28%
=======================================
Files 321 321
Lines 9514 9514
Branches 1793 1793
=======================================
Hits 8304 8304
Misses 911 911
Partials 299 299 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
rdeago
left a comment
There was a problem hiding this comment.
Review by Claude. Self-review.
No blocking findings.
Non-blocking
- PR text, "This repository" section. The first bullet says that the new
.globalconfigsection lists NX0001 to NX0004 at the default severity, "as the sections of the other analyzers do". The public API analyzers section does the opposite: its header says "We only list non-default severities here." Drop the comparison, or name only the sections that list every rule.
The rules table in docs/sdk-modules/standard-analyzers.md said that NX0002 covers a `null` or `default` literal, and NX0004 an init-only property assignment. In Nullable.Extended.Analyzer, `IsNullOrDefaultExpression` also matches `default(T)`, and `IsInitOnlyPropertyAssignment` matches only the initializer of a property with an `init` accessor. The analyzer checks both rules before NX0003, so `null!` inside a lambda expression gets NX0002. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The comments in .globalconfig held the titles of NX0001 to NX0004, which no build output shows. A search for the text of a warning found no line there. The four rules share one message. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Fixed in the PR text. The bullet drops the comparison. No section of Two other changes:
|
rdeago
left a comment
There was a problem hiding this comment.
Review by Claude. Self-review.
👍 Approved.
No blocking findings. The PR text no longer compares the Nullable.Extended.Analyzer section of .globalconfig with the other sections.
Checklist of related issues / discussions
Proposed changes
#408 asks whether an analyzer can report the null-forgiving operator (
!), so that the rule against it needs no review to enforce it. Nullable.Extended.Analyzer reports every null-forgiving operator as a warning. A comment that starts with// !, on the line above the statement, clears the warning and states the invariant.This PR adds the analyzer to Buildvana SDK, and prepares this repository for the removal of its operators. The removal comes in a second PR. Buildvana builds itself with the last published release of its own packages, so the analyzer reaches this repository only after a release.
Buildvana SDK
The
StandardAnalyzersmodule has a fourth switch,UseNullableExtendedAnalyzer. It followsUseStyleCopAnalyzers:true, except for a project that uses theMicrosoft.Build.NoTargetsSDK.yes, counts astrue, and any other value counts asfalse.true,Module.UseNullableExtendedAnalyzer.targetsadds aPackageReferencetoNullable.Extended.AnalyzerwithPrivateAssets="All".PackageVersions.propspins the package at 1.18.2.docs/sdk-modules/standard-analyzers.mddocuments the switch, the four rules NX0001 to NX0004, and the// !comment.The change is breaking. A project with a null-forgiving operator and no
// !comment gets a warning it did not get before, and an error when it treats warnings as errors.This repository
.globalconfighas a section for Nullable.Extended.Analyzer. It lists NX0001 to NX0004 atwarning, the default severity.Common.propssetsUseNullableExtendedAnalyzertofalse. The repository holds about 50 operators undersrc/and about 470 lines with one undertests/, none with a// !comment. Without the setting, the first build with the next release of Buildvana SDK would fail. The second PR removes the setting..claude/scratchpad/Common.propssetsUseNullableExtendedAnalyzertofalsefor good. Scratch code is not held to the rule.MCP server
dotnet-tools.jsonaddsNullable.Extended.Mcp1.18.2 as a local tool..mcp.json, at the root of the repository, runs it as an MCP server, with--root .and--solution Buildvana.slnx. The server finds the null-forgiving operators of the solution from the syntax, without a build. The second PR uses it to survey the operators and plan their removal.Additional changes
StandardAnalyzersmodule.StandardAnalyzersModuleTargetsTestscovers every switch and default ofModule.targets, not onlyUseNullableExtendedAnalyzer. A regression inEnableNETAnalyzers,AnalysisLevel,AnalysisMode,EnforceCodeStyleInBuild,UseStyleCopAnalyzers,UsePublicApiAnalyzers, or the search forstylecop.jsonused to pass the build..globalconfigsection headers. The StyleCop and public API sections warned against setting severities in.DotSettingsfiles. Only ReSharper reads those files, so the warning belongs in the ReSharper section of.editorconfigalone.Types of changes
This pull request introduces the following types of changes:
.gitattributes,.gitignore)Breaking changes
This pull request introduces breaking changes:
Checklist
🤖 Generated with Claude Code