Skip to content

refactor: convert NoMethodsInPropertySetupAnalyzer to IOperation#955

Merged
rjmurillo merged 5 commits intomainfrom
refactor/convert-no-methods-in-property-setup-to-ioperation
Mar 1, 2026
Merged

refactor: convert NoMethodsInPropertySetupAnalyzer to IOperation#955
rjmurillo merged 5 commits intomainfrom
refactor/convert-no-methods-in-property-setup-to-ioperation

Conversation

@rjmurillo
Copy link
Copy Markdown
Owner

@rjmurillo rjmurillo commented Mar 1, 2026

Summary

  • Convert NoMethodsInPropertySetupAnalyzer from RegisterSyntaxNodeAction to RegisterCompilationStartAction + RegisterOperationAction with IInvocationOperation, matching the pattern established by AsShouldBeUsedOnlyForInterfaceAnalyzer
  • Replace string-based method name matching ("SetupGet", "SetupSet", "SetupProperty") with symbol-based detection using MoqKnownSymbols and IsInstanceOf
  • Add Mock1SetupGet, Mock1SetupSet, and Mock1SetupProperty properties to MoqKnownSymbols for resolving property setup method symbols

Fixes #337

Test plan

  • All existing NoMethodsInPropertySetupAnalyzerTests pass without modification (behavior is identical)
  • Build succeeds with no new warnings
  • Doppelganger/custom mock class tests still pass

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes

    • More accurate detection of Moq property setup invocations, improving diagnostic relevance for property-setup issues.
  • Tests

    • Added tests ensuring the analyzer does not run when Moq is not referenced.
    • Updated test references to include a .NET 8.0 scenario without Moq.

Replace RegisterSyntaxNodeAction with RegisterCompilationStartAction and
RegisterOperationAction using IInvocationOperation. Use MoqKnownSymbols
for symbol-based detection of SetupGet, SetupSet, and SetupProperty
methods instead of string-based matching.

Add Mock1SetupGet, Mock1SetupSet, and Mock1SetupProperty properties to
MoqKnownSymbols for resolving property setup method symbols.

Fixes #337

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings March 1, 2026 20:06
@rjmurillo rjmurillo added analyzers Change that impacts an analyzer behavior releasable labels Mar 1, 2026
@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly refactors the NoMethodsInPropertySetupAnalyzer to improve its robustness and maintainability. By transitioning from syntax-node-based analysis to IOperation-based analysis and leveraging symbol-based method identification, the analyzer now more accurately detects invalid method calls within Moq property setups. This change enhances the reliability of the analyzer and standardizes its implementation with other existing analyzers.

Highlights

  • Analyzer Refactoring: The NoMethodsInPropertySetupAnalyzer has been refactored to use IOperation analysis, aligning with the pattern set by AsShouldBeUsedOnlyForInterfaceAnalyzer.
  • Symbol-Based Method Detection: String-based method name matching for "SetupGet", "SetupSet", and "SetupProperty" has been replaced with more robust symbol-based detection using MoqKnownSymbols and IsInstanceOf.
  • MoqKnownSymbols Enhancement: New properties (Mock1SetupGet, Mock1SetupSet, Mock1SetupProperty) were added to MoqKnownSymbols to facilitate the resolution of property setup method symbols.
Changelog
  • src/Analyzers/NoMethodsInPropertySetupAnalyzer.cs
    • Updated the analyzer to use RegisterCompilationStartAction and RegisterOperationAction instead of RegisterSyntaxNodeAction.
    • Implemented symbol-based checking for SetupGet, SetupSet, and SetupProperty methods using MoqKnownSymbols.
    • Added necessary using directives for System.Diagnostics and Microsoft.CodeAnalysis.Operations.
  • src/Common/WellKnown/MoqKnownSymbols.cs
    • Added new ImmutableArray properties: Mock1SetupGet, Mock1SetupSet, and Mock1SetupProperty to retrieve method symbols for Moq's property setup methods.
    • Introduced ILogger and ILogger1 properties to get Microsoft.Extensions.Logging interface symbols.
Activity
  • The pull request includes a detailed test plan to ensure existing analyzer tests pass and the build succeeds without new warnings.
  • The changes were generated with the assistance of "Claude Code".
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 1, 2026

📝 Walkthrough

Walkthrough

Converts NoMethodsInPropertySetupAnalyzer from syntax-node to compilation-start + IOperation analysis, adds semantic-symbol checks for Moq property setup methods, and exposes three new MoqKnownSymbols properties for SetupGet/SetupSet/SetupProperty. Adds tests and a reference-assembly entry for .NET 8 without Moq.

Changes

Cohort / File(s) Summary
Analyzer (operation-based)
src/Analyzers/NoMethodsInPropertySetupAnalyzer.cs
Replaced syntax-node registration with RegisterCompilationStartAction; collect property-setup method symbols and register an Invocation operation action. Analyze now accepts OperationAnalysisContext and precomputed IMethodSymbol array; uses semantic-model symbol resolution and null-safety checks before reporting diagnostics.
MoqKnownSymbols expansion
src/Common/WellKnown/MoqKnownSymbols.cs
Added internal properties Mock1SetupGet, Mock1SetupSet, and Mock1SetupProperty returning method-symbol arrays for Moq.Mock\1` (null-conditional with empty-array fallback).
Tests & test infra
tests/Moq.Analyzers.Test/NoMethodsInPropertySetupAnalyzerTests.cs, tests/Moq.Analyzers.Test/Helpers/ReferenceAssemblyCatalog.cs
Added a test asserting no analysis when Moq is not referenced; added ReferenceAssemblyCatalog.Net80 entry for a Moq-free .NET 8.0 reference group; minor using/import addition.

Sequence Diagram(s)

sequenceDiagram
    participant Comp as CompilationStart
    participant Analyzer as NoMethodsInPropertySetupAnalyzer
    participant Known as MoqKnownSymbols
    participant Op as InvocationOperation
    participant SM as SemanticModel
    participant Reporter as DiagnosticReporter

    Comp->>Analyzer: RegisterCompilationStartAction(context)
    Analyzer->>Known: Resolve Mock`1 and collect Setup* method symbols
    Analyzer-->>Comp: If no Moq symbols, skip registering Op handler
    Comp->>Analyzer: Invocation operation occurs (IInvocationOperation)
    Analyzer->>Op: OperationAction invoked with IInvocationOperation
    Analyzer->>SM: Obtain SemanticModel from operation
    Op->>SM: Resolve mocked method symbol from invocation
    Analyzer->>Reporter: Create/report diagnostic using resolved method symbol (if violation)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • MattKotsenas
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main refactoring effort: converting NoMethodsInPropertySetupAnalyzer from syntax-node-based to IOperation-based analysis.
Linked Issues check ✅ Passed All coding requirements from issue #337 are met: analyzer converted to IOperation, string-based checks replaced with symbol-based detection, new properties added to MoqKnownSymbols, and existing behavior preserved.
Out of Scope Changes check ✅ Passed All changes directly support the refactoring objective: analyzer conversion, symbol additions, test infrastructure enhancement, and test coverage for the Moq-not-referenced guard branch.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch refactor/convert-no-methods-in-property-setup-to-ioperation

Comment @coderabbitai help to get the list of available commands and usage tips.

@deepsource-io
Copy link
Copy Markdown

deepsource-io bot commented Mar 1, 2026

DeepSource Code Review

We reviewed changes in f3a8c8a...962f7b5 on this pull request. Below is the summary for the review, and you can see the individual issues we found as inline review comments.

See full review on DeepSource ↗

PR Report Card

Overall Grade  

Focus Area: Hygiene
Security  

Reliability  

Complexity  

Hygiene  

Code Review Summary

Analyzer Status Updated (UTC) Details
C# Mar 1, 2026 9:17p.m. Review ↗

Replace null-forgiving operator on SemanticModel with explicit null
check, matching the established pattern used by all other IOperation
analyzers in the codebase.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request is a great step forward in modernizing the analyzers by converting NoMethodsInPropertySetupAnalyzer to use the IOperation API. This improves performance and correctness by relying on semantic symbols instead of string matching.

My review includes a suggestion to fully complete the transition to IOperation within the analyzer, which also resolves a potential issue with block-bodied lambdas. I've also noted a minor scope creep issue to help keep commits focused.

Comment on lines +77 to +96
// The lambda argument to SetupGet/SetupSet/SetupProperty contains the mocked member access.
// If the lambda body is an invocation (method call), that is invalid for property setup.
InvocationExpressionSyntax? mockedMethodCall =
(invocationOperation.Syntax as InvocationExpressionSyntax).FindMockedMethodInvocationFromSetupMethod();

if (setupGetOrSetInvocation.Expression is not MemberAccessExpressionSyntax setupGetOrSetMethod) return;
if (!string.Equals(setupGetOrSetMethod.Name.ToFullString(), "SetupGet", StringComparison.Ordinal)
&& !string.Equals(setupGetOrSetMethod.Name.ToFullString(), "SetupSet", StringComparison.Ordinal)
&& !string.Equals(setupGetOrSetMethod.Name.ToFullString(), "SetupProperty", StringComparison.Ordinal)) return;
if (mockedMethodCall == null)
{
return;
}

InvocationExpressionSyntax? mockedMethodCall = setupGetOrSetInvocation.FindMockedMethodInvocationFromSetupMethod();
if (mockedMethodCall == null) return;
SemanticModel? semanticModel = invocationOperation.SemanticModel;
if (semanticModel == null)
{
return;
}

ISymbol? mockedMethodSymbol = context.SemanticModel.GetSymbolInfo(mockedMethodCall, context.CancellationToken).Symbol;
if (mockedMethodSymbol == null) return;
ISymbol? mockedMethodSymbol = semanticModel.GetSymbolInfo(mockedMethodCall, context.CancellationToken).Symbol;
if (mockedMethodSymbol == null)
{
return;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

This implementation for finding the mocked method call mixes IOperation with SyntaxNode analysis by falling back to FindMockedMethodInvocationFromSetupMethod. This partially defeats the purpose of refactoring to IOperation.

Additionally, the FindMockedMethodInvocationFromSetupMethod helper only works for expression-bodied lambdas (x => x.Method()) and will fail for block-bodied lambdas (x => { return x.Method(); }), as LambdaExpressionSyntax.Body would be a BlockSyntax.

You can implement this logic purely using the IOperation tree, which will be more robust and align better with the refactoring goal. This also provides an opportunity to correctly handle block-bodied lambdas.

        // The lambda argument to SetupGet/SetupSet/SetupProperty contains the mocked member access.
        // If the lambda body is an invocation (method call), that is invalid for property setup.
        if (invocationOperation.Arguments.Length == 0)
        {
            return;
        }

        IOperation argument = invocationOperation.Arguments[0].Value.WalkDownImplicitConversion();
        if (argument is not IAnonymousFunctionOperation lambda)
        {
            return;
        }

        IOperation? body = lambda.Body;
        if (body is IBlockOperation block && block.Operations.Length == 1 && block.Operations[0] is IReturnOperation returnOp)
        {
            body = returnOp.ReturnedValue;
        }

        if (body is IInvocationOperation mockedMethodInvocation)
        {
            IMethodSymbol mockedMethodSymbol = mockedMethodInvocation.TargetMethod;
            Diagnostic diagnostic = mockedMethodInvocation.Syntax.CreateDiagnostic(Rule, mockedMethodSymbol.Name);
            context.ReportDiagnostic(diagnostic);
        }

Comment on lines +422 to +430
/// <summary>
/// Gets the interface <c>Microsoft.Extensions.Logging.ILogger</c>.
/// </summary>
internal INamedTypeSymbol? ILogger => TypeProvider.GetOrCreateTypeByMetadataName("Microsoft.Extensions.Logging.ILogger");

/// <summary>
/// Gets the interface <c>Microsoft.Extensions.Logging.ILogger{T}</c>.
/// </summary>
internal INamedTypeSymbol? ILogger1 => TypeProvider.GetOrCreateTypeByMetadataName("Microsoft.Extensions.Logging.ILogger`1");
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

These additions for ILogger and ILogger<T> seem unrelated to the primary goal of this pull request, which is to refactor NoMethodsInPropertySetupAnalyzer. To maintain clean and focused commits, it would be better to move these changes to a separate pull request.

@coderabbitai coderabbitai bot requested a review from MattKotsenas March 1, 2026 20:07
Remove ILogger and ILogger1 properties that were accidentally included.
These belong to a separate feature branch and should not be part of this
refactoring.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Refactors NoMethodsInPropertySetupAnalyzer to use IOperation-based analysis with compilation-start symbol precomputation, aligning with the repository’s symbol-based detection approach and avoiding string-based method name matching.

Changes:

  • Converted NoMethodsInPropertySetupAnalyzer from RegisterSyntaxNodeAction to RegisterCompilationStartAction + RegisterOperationAction using IInvocationOperation.
  • Added Mock1SetupGet, Mock1SetupSet, and Mock1SetupProperty to MoqKnownSymbols to enable symbol-based identification of property setup APIs.
  • Introduced ILogger / ILogger1 symbol properties in MoqKnownSymbols (currently unused and not described in PR metadata).

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
src/Common/WellKnown/MoqKnownSymbols.cs Adds well-known method symbols for Mock<T>.SetupGet/SetupSet/SetupProperty to support symbol-based analyzer matching; also adds ILogger/ILogger1 symbols.
src/Analyzers/NoMethodsInPropertySetupAnalyzer.cs Refactors analyzer to operation-based invocation analysis and uses MoqKnownSymbols method symbols instead of string comparisons.
Comments suppressed due to low confidence (2)

src/Common/WellKnown/MoqKnownSymbols.cs:430

  • The new ILogger/ILogger1 symbols appear unrelated to this PR’s stated goal (property setup analyzer refactor) and are currently unused in the codebase. Please remove them from MoqKnownSymbols (or move them into a separate PR that also adds the analyzer/code that consumes them) to avoid accumulating dead well-known symbols.
    /// <summary>
    /// Gets the interface <c>Microsoft.Extensions.Logging.ILogger</c>.
    /// </summary>
    internal INamedTypeSymbol? ILogger => TypeProvider.GetOrCreateTypeByMetadataName("Microsoft.Extensions.Logging.ILogger");

    /// <summary>
    /// Gets the interface <c>Microsoft.Extensions.Logging.ILogger{T}</c>.
    /// </summary>
    internal INamedTypeSymbol? ILogger1 => TypeProvider.GetOrCreateTypeByMetadataName("Microsoft.Extensions.Logging.ILogger`1");

src/Analyzers/NoMethodsInPropertySetupAnalyzer.cs:80

  • invocationOperation.Syntax is cast with as InvocationExpressionSyntax but then immediately dereferenced. Since this path assumes the cast succeeds, use a direct cast instead (or add a null-check) to make the expectation explicit and avoid introducing a fragile null-dereference pattern.
        InvocationExpressionSyntax? mockedMethodCall =
            (invocationOperation.Syntax as InvocationExpressionSyntax).FindMockedMethodInvocationFromSetupMethod();

@codacy-production
Copy link
Copy Markdown

codacy-production bot commented Mar 1, 2026

Coverage summary from Codacy

See diff coverage on Codacy

Coverage variation Diff coverage
-0.35% (target: -1.00%) 87.50% (target: 95.00%)
Coverage variation details
Coverable lines Covered lines Coverage
Common ancestor commit (f3a8c8a) 2072 1843 88.95%
Head commit (962f7b5) 2114 (+42) 1873 (+30) 88.60% (-0.35%)

Coverage variation is the difference between the coverage for the head and common ancestor commits of the pull request branch: <coverage of head commit> - <coverage of common ancestor commit>

Diff coverage details
Coverable lines Covered lines Diff coverage
Pull request (#955) 32 28 87.50%

Diff coverage is the percentage of lines that are covered by tests out of the coverable lines that the pull request added or modified: <covered lines added or modified>/<coverable lines added or modified> * 100%

See your quality gate settings    Change summary preferences

coderabbitai[bot]
coderabbitai bot previously approved these changes Mar 1, 2026
Add Net80 reference assembly group (without Moq) to
ReferenceAssemblyCatalog. Add ShouldNotAnalyzeWhenMoqNotReferenced
test to exercise the IsMockReferenced() early exit in
RegisterCompilationStartAction, covering the guard branches that
were causing Codacy diff coverage to fall below the 95% threshold.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The test harness injects a global using Moq directive, causing CS0246
when the Net80 reference assembly (without Moq) is used. Suppress
compiler diagnostics since the test only validates analyzer behavior.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tests/Moq.Analyzers.Test/Helpers/ReferenceAssemblyCatalog.cs`:
- Around line 41-43: The XML <remarks> for the public Catalog (in
ReferenceAssemblyCatalog) is out of date after adding the new key nameof(Net80)
=> ReferenceAssemblies.Net.Net80; update the Catalog XML remarks to list the
Net80 key alongside the existing keys so the public API docs accurately reflect
the available map entries (mention the symbol Net80 and the map entry
nameof(Net80) / ReferenceAssemblies.Net.Net80 when editing the remarks).

ℹ️ Review info

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 681e023 and 962f7b5.

📒 Files selected for processing (2)
  • tests/Moq.Analyzers.Test/Helpers/ReferenceAssemblyCatalog.cs
  • tests/Moq.Analyzers.Test/NoMethodsInPropertySetupAnalyzerTests.cs

Comment on lines +41 to +43
// .NET 8.0 without Moq, used to verify analyzers short-circuit when Moq is not referenced.
{ nameof(Net80), ReferenceAssemblies.Net.Net80 },

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Update Catalog XML remarks to include the new Net80 key.

After adding Net80 to the map, the Catalog remarks still list only two key names, so the public API docs are now stale.

📝 Suggested doc fix
 /// <remarks>
-/// The key is the name of the reference assembly group (<see cref="Net80WithOldMoq"/> and <see cref="Net80WithNewMoq"/>).
+/// The key is the name of the reference assembly group
+/// (<see cref="Net80"/>, <see cref="Net80WithOldMoq"/>, and <see cref="Net80WithNewMoq"/>).
 /// </remarks>

As per coding guidelines, "All public APIs must have complete XML documentation with accurate, up-to-date content."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/Moq.Analyzers.Test/Helpers/ReferenceAssemblyCatalog.cs` around lines 41
- 43, The XML <remarks> for the public Catalog (in ReferenceAssemblyCatalog) is
out of date after adding the new key nameof(Net80) =>
ReferenceAssemblies.Net.Net80; update the Catalog XML remarks to list the Net80
key alongside the existing keys so the public API docs accurately reflect the
available map entries (mention the symbol Net80 and the map entry nameof(Net80)
/ ReferenceAssemblies.Net.Net80 when editing the remarks).

Copy link
Copy Markdown
Collaborator

@rjmurillo-bot rjmurillo-bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All required checks passing. Code changes verified. LGTM.

@rjmurillo rjmurillo merged commit 832c91c into main Mar 1, 2026
40 of 43 checks passed
@rjmurillo rjmurillo deleted the refactor/convert-no-methods-in-property-setup-to-ioperation branch March 1, 2026 22:01
@rjmurillo rjmurillo added this to the vNext milestone Mar 1, 2026
rjmurillo added a commit that referenced this pull request Mar 2, 2026
PRs #955 and #958 each added Net80 to ReferenceAssemblyCatalog
independently. The merge created duplicate property and dictionary
entries, breaking the build with CS0102.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
rjmurillo added a commit that referenced this pull request Mar 2, 2026
## Summary

Main is broken. PRs #955 and #958 each independently added a `Net80`
property and dictionary entry to `ReferenceAssemblyCatalog`. The merge
created duplicates, failing with `CS0102: The type
'ReferenceAssemblyCatalog' already contains a definition for 'Net80'`.

## Changes

Removed the duplicate property (lines 38-41) and duplicate dictionary
entry (lines 73-74) from `ReferenceAssemblyCatalog.cs`. Kept the first
copies which have the more descriptive doc comment.

## Test Plan

- [x] `dotnet build` passes
- [x] 2786 tests pass

🤖 Generated with [Claude Code](https://claude.com/claude-code)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Chores**
* Removed .NET 8.0 reference assembly support from test infrastructure.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

analyzers Change that impacts an analyzer behavior releasable

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Convert NoMethodsInPropertySetupAnalyzer to IOperation

3 participants