Skip to content

Do not suggest instance members in static contexts in MA0166/MA0167 - #1623

Merged
meziantou merged 2 commits into
mainfrom
feature/meziantou-analyzer-793-a714f7
Oct 3, 2026
Merged

meziantou merged 2 commits into
mainfrom
feature/meziantou-analyzer-793-a714f7

Conversation

@meziantou

Copy link
Copy Markdown
Owner

Follow-up to this comment on #793, which reports a false positive in MA0166.

Problem

MA0166 reports when a TimeProvider is available in scope. To find what's available, LookupAvailableSymbols calls SemanticModel.LookupSymbols, which also returns instance members that can't be used at that point. The code that filtered them out (IsInStaticContext) only recognized static methods. As a result, MA0166 reported things like available time providers: _timeProvider, and the code fix would have produced code that doesn't compile, in:

  • static properties (expression-bodied or with a getter) and static event accessors
  • static constructors and static operators
  • static and instance field or property initializers
  • : this(...) / : base(...) constructor initializers
  • members of a nested type, which were offered the outer type's instance fields

Changes

  • OperationExtensions: replace IsInStaticContext with a GetStaticContext helper that handles the contexts above.
  • Instance fields and properties are now only suggested when the current type is the declaring type or derives from it. Interface default implementations can use members of the interfaces they inherit from.
  • Primary constructor parameters, including records', are handled explicitly. They can be used in instance members, instance initializers, base-type arguments and other partial parts of the type. They can't be used in static members or constructor initializers (CS9105).
  • MA0084 (LocalVariablesShouldNotHideSymbolsAnalyzer) used IsInStaticContext, so it now uses CanUsePrimaryConstructorParameters. Side effect: it no longer reports a local in a static property, a static field initializer or a constructor initializer as hiding a primary constructor parameter.
  • docs/Rules/MA0166.md: explain why the rule exists. Overloads without a TimeProvider use TimeProvider.System, so forwarding an injected provider keeps the code testable with a fake clock. This addresses the "outdated" point in the comment.

Tests

  • New UseAnOverloadThatHasTimeProviderAnalyzerTests cases for each context above, plus the primary-constructor cases (available and not available).
  • New LocalVariablesShouldNotHideSymbolsAnalyzerTests cases for static contexts and instance field initializers.
  • The related test classes pass on all five Roslyn versions. The full suite ran 26,959 tests with 18 failures, all JsonSourceGenerationOptionsAnalyzerTests on Roslyn 4.14 with network socket errors. That class passed on a re-run.

LookupAvailableSymbols only recognized static methods as static contexts, so
the instance fields and properties of the type were suggested as the TimeProvider
to forward in static properties, static constructors, static operators, static
event accessors, field and property initializers, and constructor initializers.
The members of a containing type were also suggested in a nested type.

Primary constructor parameters are now handled explicitly: they can be used in
instance members, instance initializers and the arguments of the base type, but
not in static members or in constructor initializers. MA0084 uses the same logic
to decide whether a local hides a primary constructor parameter.

Fixes #793 (comment)
CSharpExtensions.GetDeclaredSymbol and GetSymbolInfo accept a nullable SemanticModel.
@meziantou
meziantou merged commit 2cb38ab into main Oct 3, 2026
14 checks passed
@meziantou
meziantou deleted the feature/meziantou-analyzer-793-a714f7 branch October 3, 2026 18:00
This was referenced Oct 3, 2026
This was referenced Oct 5, 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