Skip to content

Deduplicate String/Collection assert analyzer scaffolding via shared base class#8846

Merged
Evangelink merged 3 commits into
mainfrom
copilot/duplicate-code-structural-boilerplate
Jun 5, 2026
Merged

Deduplicate String/Collection assert analyzer scaffolding via shared base class#8846
Evangelink merged 3 commits into
mainfrom
copilot/duplicate-code-structural-boilerplate

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Jun 5, 2026

CollectionAssertToAssertAnalyzer and StringAssertToAssertAnalyzer had near-identical structural boilerplate (diagnostic property key, SupportedDiagnostics, Initialize, and invocation preamble). This change extracts that shared analyzer scaffolding while preserving each analyzer’s rule-specific mapping logic.

  • Shared analyzer infrastructure

    • Added AssertToAssertAnalyzerBase to centralize:
      • ProperAssertMethodNameKey
      • common SupportedDiagnostics implementation
      • common Initialize registration flow (CompilationStart + OperationKind.Invocation)
      • common invocation/type guard helper (TryGetTargetMethod)
  • Analyzer refactor

    • Updated:
      • StringAssertToAssertAnalyzer
      • CollectionAssertToAssertAnalyzer
    • Both now provide only rule-specific pieces (DiagnosticRule, source assert type metadata name, and analyzer-specific invocation mapping).
  • Code-fix alignment

    • Updated both fixers to read ProperAssertMethodNameKey from the shared base class, removing duplicated key ownership assumptions.
public abstract class AssertToAssertAnalyzerBase : DiagnosticAnalyzer
{
    internal const string ProperAssertMethodNameKey = nameof(ProperAssertMethodNameKey);

    public sealed override void Initialize(AnalysisContext context)
    {
        context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
        context.EnableConcurrentExecution();
        context.RegisterCompilationStartAction(context =>
        {
            if (!context.Compilation.TryGetOrCreateTypeByMetadataName(SourceAssertTypeMetadataName, out INamedTypeSymbol? sourceAssertTypeSymbol))
                return;

            context.RegisterOperationAction(
                context => AnalyzeInvocationOperation(context, sourceAssertTypeSymbol),
                OperationKind.Invocation);
        });
    }
}

Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
Copilot AI requested review from Copilot and removed request for Copilot June 5, 2026 06:08
Copilot AI changed the title [WIP] Refactor duplicate code in StringAssertToAssertAnalyzer and CollectionAssertToAssertAnalyzer Deduplicate String/Collection assert analyzer scaffolding via shared base class Jun 5, 2026
Copilot AI requested a review from Evangelink June 5, 2026 06:09
@Evangelink Evangelink marked this pull request as ready for review June 5, 2026 07:26
Copilot AI review requested due to automatic review settings June 5, 2026 07:26
@Evangelink Evangelink enabled auto-merge (squash) June 5, 2026 07:26
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

This PR refactors MSTest analyzer infrastructure by extracting shared scaffolding from the StringAssertToAssertAnalyzer and CollectionAssertToAssertAnalyzer into a common base class, while keeping each analyzer’s rule-specific mapping logic intact.

Changes:

  • Introduced AssertToAssertAnalyzerBase to centralize common analyzer setup (supported diagnostics, initialization, and invocation filtering).
  • Refactored StringAssertToAssertAnalyzer and CollectionAssertToAssertAnalyzer to inherit from the new base and only implement rule-specific behavior.
  • Updated both code-fix providers to read the diagnostic property key from the shared base instead of each analyzer type.
Show a summary per file
File Description
src/Analyzers/MSTest.Analyzers/AssertToAssertAnalyzerBase.cs Adds shared analyzer scaffolding for “legacy assert type → Assert” migration analyzers.
src/Analyzers/MSTest.Analyzers/StringAssertToAssertAnalyzer.cs Refactors analyzer to inherit from shared base and provide only string-assert-specific mapping.
src/Analyzers/MSTest.Analyzers/CollectionAssertToAssertAnalyzer.cs Refactors analyzer to inherit from shared base and provide only collection-assert-specific mapping.
src/Analyzers/MSTest.Analyzers.CodeFixes/StringAssertToAssertFixer.cs Switches property-key lookup to use the shared base constant.
src/Analyzers/MSTest.Analyzers.CodeFixes/CollectionAssertToAssertFixer.cs Switches property-key lookup to use the shared base constant.

Copilot's findings

  • Files reviewed: 5/5 changed files
  • Comments generated: 1

Comment thread src/Analyzers/MSTest.Analyzers/AssertToAssertAnalyzerBase.cs Outdated
@Evangelink Evangelink marked this pull request as draft June 5, 2026 08:30
auto-merge was automatically disabled June 5, 2026 08:30

Pull request was converted to draft

@Evangelink Evangelink marked this pull request as ready for review June 5, 2026 09:34
Replace the new public abstract AssertToAssertAnalyzerBase with an internal static AssertToAssertAnalyzerHelpers class. The concrete analyzers now inherit DiagnosticAnalyzer directly and call into the helper, avoiding adding new public API surface area.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@Evangelink Evangelink enabled auto-merge (squash) June 5, 2026 11:13
@Evangelink Evangelink merged commit 5961762 into main Jun 5, 2026
27 checks passed
@Evangelink Evangelink deleted the copilot/duplicate-code-structural-boilerplate branch June 5, 2026 12:06
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.

[duplicate-code] Duplicate Code: Structural Boilerplate in StringAssertToAssertAnalyzer and CollectionAssertToAssertAnalyzer

5 participants