Skip to content

Match the annotation attributes by name in MA0060, MA0124 and MA0139 - #1407

Merged
meziantou merged 1 commit into
mainfrom
feature/annotation-attribute-matching-26eb03
Sep 6, 2026
Merged

meziantou merged 1 commit into
mainfrom
feature/annotation-attribute-matching-26eb03

Conversation

@meziantou

Copy link
Copy Markdown
Owner

What

AnnotationAttributes states that the annotation attributes "can be defined in multiple assemblies, so it's identified by its full name only", and the Meziantou.Analyzer.Annotations README documents that users may copy the attribute source into their own project, public or internal. Two rules did not follow that policy and still resolved the attribute with GetBestTypeByMetadataName:

  • MA0060 matched the attribute on a return value or an out parameter by symbol equality, while the assembly-level form already went through AnnotationAttributes — two matching strategies for one attribute within a single file.
  • MA0124/MA0139 looked up StructuredLogFieldAttribute by metadata name; it was the only one of the nine shipped attributes with no name-based matcher.

Changes:

  • Added AnnotationAttributes.IsStructuredLogFieldAttributeSymbol.
  • DoNotIgnoreReturnValueAnalyzer drops the DoNotIgnoreAttributeSymbol field and its is null guards; the out-parameter and return-value paths share a FindDoNotIgnoreAttribute helper backed by AnnotationAttributes.IsDoNotIgnoreAttributeSymbol, so all three forms of MA0060 now match identically.
  • LoggerParameterTypeAnalyzer drops StructuredLogFieldAttributeSymbol and matches by name.

AnalyzeArgument became static — CA1822 fires once it no longer touches instance state.

Why it was a real bug, not only a consistency issue

GetBestTypeByMetadataName returns a type declared in the compilation's own source regardless of accessibility, so copying the attribute into your own project always worked. The case that actually diverged is a referenced assembly that copied the attribute as internal: it is invisible to GetBestTypeByMetadataName, so MA0060 silently reported nothing on that library's annotated members.

Tests

Four new tests in DoNotIgnoreReturnValueAnalyzerTests and one in LoggerParameterTypeAnalyzerTests, all annotating with a hand-copied internal attribute instead of the package one.

Note for the reviewer: three of the four in-project tests pass against the old analyzer too, for the reason above — they are kept as coverage of the README-endorsed usage. The test that proves the fix is Attribute_ReturnValue_NotUsed_AttributeDefinedInAReferencedProject, which puts the internal attribute in an additional referenced project; it fails against the pre-fix analyzer and passes after.

Verification

  • dotnet build — clean, 0 warnings.
  • dotnet test --max-parallel-test-modules 2 — 19,283 passed, 0 failed, across all five Roslyn versions.
  • dotnet run --project src/DocumentationGenerator — exit 0, no markdown changes.

Nothing under src/Meziantou.Analyzer.Annotations changed, so no README update or version bump was needed.

The annotation attributes can be defined in multiple assemblies, as the
Meziantou.Analyzer.Annotations package documents that their source can be
copied into a project, so AnnotationAttributes identifies them by their full
name only. Two rules still resolved them with GetBestTypeByMetadataName:

- MA0060 used symbol equality for the attribute on a return value or an out
  parameter, while the assembly level form already went through
  AnnotationAttributes, so the two documented usages could disagree.
- MA0124/MA0139 had no name based matcher at all for
  StructuredLogFieldAttribute.

GetBestTypeByMetadataName ignores a type that is internal in a referenced
assembly, so MA0060 reported nothing on the members a referenced library
annotated with its own copy of the attribute.

Add AnnotationAttributes.IsStructuredLogFieldAttributeSymbol and route both
rules through AnnotationAttributes.
@meziantou
meziantou enabled auto-merge (squash) September 6, 2026 04:21
@meziantou
meziantou merged commit 1476d41 into main Sep 6, 2026
13 checks passed
@meziantou
meziantou deleted the feature/annotation-attribute-matching-26eb03 branch September 6, 2026 04:21
This was referenced Sep 6, 2026
This was referenced Sep 24, 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