Skip to content

Report the contextual keywords in MA0154 - #1516

Merged
meziantou merged 1 commit into
mainfrom
feature/ma0154-missing-keywords-4dab46
Sep 12, 2026
Merged

meziantou merged 1 commit into
mainfrom
feature/ma0154-missing-keywords-4dab46

Conversation

@meziantou

Copy link
Copy Markdown
Owner

What

MA0154 (Use langword in XML comment) matched its <c>/<code> content against a hand-maintained list of the 77 C# reserved keywords. Keywords added to the language since C# 1.0 were missing, so <c>await</c>, <c>nint</c> or <c>record</c> were never reported, while <c>int</c> was.

The following are now reported: async, await, dynamic, init, nameof, nint, nuint, partial, record, required, scoped, var.

The unused using System.Linq.Expressions; in the analyzer is also removed.

Why the list stays hard-coded

Deriving the set from SyntaxFacts.GetKeywordKinds() / GetContextualKeywordKinds() looks tempting, but:

  • nint and nuint have no keyword kind — they are parsed as identifiers — so the main reported gap would remain.
  • The contextual keyword kinds differ between the five supported Roslyn versions, which would make the rule report different diagnostics depending on the Roslyn version in use.
  • The contextual keywords that are also ordinary identifiers (value, from, select, add, remove, get, set) would have to be subtracted by hand anyway to avoid false positives on things like <c>value</c>, so the maintenance burden does not actually go away.

Those ambiguous ones are therefore deliberately excluded; a comment in the analyzer says so.

Tests

  • One ValidateSummary_Invalid case per new keyword, checking both the diagnostic and the code fix output.
  • Four MissingLanguageAttribute cases asserting <c>value</c>, <c>from</c>, <c>get</c> and <c>set</c> still report MA0219 and not MA0154.

UseLangwordInXmlCommentAnalyzerTests runs 42 tests (up from 25), all passing on roslyn5.9 and roslyn4.8. dotnet run --project src/DocumentationGenerator exits 0, so no generated markdown changed; docs/Rules/MA0154.md is updated by hand to document which keywords are recognized and which are not.

The keyword list of MA0154 only contained the 77 reserved keywords, so
<c>await</c>, <c>nint</c> or <c>record</c> were never converted to
<see langword="..."/>, while <c>int</c> was.

Add the contextual keywords and the type keywords that are unlikely to be
used as an identifier: async, await, dynamic, init, nameof, nint, nuint,
partial, record, required, scoped and var.

The list stays hard-coded rather than derived from SyntaxFacts: nint and
nuint are not keyword kinds, as they are parsed as identifiers, so the
main gap would remain; the contextual keyword kinds differ between the
supported Roslyn versions, which would make the rule behave differently
from one version to another; and the contextual keywords that are also
ordinary identifiers (value, from, select, add, remove, get, set) would
have to be excluded by hand anyway to avoid false positives on <c>value</c>.

Also remove the unused System.Linq.Expressions using directive.
@meziantou
meziantou enabled auto-merge (squash) September 12, 2026 20:18
@meziantou
meziantou merged commit 73baf34 into main Sep 12, 2026
13 checks passed
@meziantou
meziantou deleted the feature/ma0154-missing-keywords-4dab46 branch September 12, 2026 20:18
This was referenced Sep 12, 2026
This was referenced Sep 26, 2026
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