Skip to content

Commit

Permalink
Merge pull request #652 from viceroypenguin/ca1036
Browse files Browse the repository at this point in the history
Add CA1036 Suppressor
  • Loading branch information
SteveDunn authored Jul 30, 2024
2 parents 7c342a5 + 7452c02 commit 9f22002
Show file tree
Hide file tree
Showing 2 changed files with 121 additions and 0 deletions.
57 changes: 57 additions & 0 deletions src/Vogen/Suppressors/CA1036ComparisonSuppressor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
using System.Collections.Immutable;
using System.Diagnostics.CodeAnalysis;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Diagnostics;

namespace Vogen.Suppressors;

[DiagnosticAnalyzer(LanguageNames.CSharp)]
[SuppressMessage("ReSharper", "InconsistentNaming")]
public sealed class CA1036ComparisonSuppressor : DiagnosticSuppressor
{
private static readonly SuppressionDescriptor _suppressIComparableWarning = new(
id: "VOGS0003",
suppressedDiagnosticId: "CA1036",
justification: "Suppress CA1036 on value objects.");

// ReSharper disable once UseCollectionExpression
public override ImmutableArray<SuppressionDescriptor> SupportedSuppressions =>
ImmutableArray.Create(_suppressIComparableWarning);

public override void ReportSuppressions(SuppressionAnalysisContext context)
{
var attributeSymbol = context.Compilation.GetBestTypeByMetadataName("Vogen.ValueObjectAttribute");

if (attributeSymbol is null)
{
return;
}

foreach (var diagnostic in context.ReportedDiagnostics)
{
ProcessDiagnostic(context, diagnostic);
}
}

private static void ProcessDiagnostic(SuppressionAnalysisContext context, Diagnostic diagnostic)
{
var node = diagnostic.TryFindNode(context.CancellationToken);

if (node is null)
{
return;
}

var semanticModel = context.GetSemanticModel(node.SyntaxTree);

var valueObjectSymbol = semanticModel.GetDeclaredSymbol(node, context.CancellationToken) as INamedTypeSymbol;

if (!VoFilter.IsTarget(valueObjectSymbol))
{
return;
}

var suppression = Suppression.Create(_suppressIComparableWarning, diagnostic);
context.ReportSuppression(suppression);
}
}
64 changes: 64 additions & 0 deletions tests/AnalyzerTests/CA1036SuppressionTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
using System.Collections.Immutable;
using System.Threading.Tasks;
using FluentAssertions;
using Microsoft.CodeAnalysis;
using Shared;
using Vogen;
using Vogen.Suppressors;

namespace AnalyzerTests;

public class CA1036SuppressionTests
{
[Fact]
public async Task Suppressed_for_value_object()
{
var source = $$"""
using System;
using Vogen;

namespace Whatever;

[ValueObject<int>]
public partial class CustomerId : IComparable<CustomerId>
{
}
""";

(ImmutableArray<Diagnostic> Diagnostics, SyntaxTree[] GeneratedSource) r =
await CreateBuilder(source).GetGeneratedOutput<ValueObjectGenerator>(ignoreInitialCompilationErrors: false);

r.Diagnostics.Should().HaveCount(0);
}

[Fact]
public async Task Does_not_suppress_other_types()
{
var source = $$"""
using System;
using Vogen;

namespace Whatever;

public partial class CustomerId : IComparable<CustomerId>
{
public int CompareTo(CustomerId other)
{
return 1;
}
}
""";

(ImmutableArray<Diagnostic> Diagnostics, SyntaxTree[] GeneratedSource) r =
await CreateBuilder(source).GetGeneratedOutput<ValueObjectGenerator>(ignoreInitialCompilationErrors: false);

r.Diagnostics.Should().HaveCount(1);
r.Diagnostics[0].Id.Should().Be("CA1036");
}

private static ProjectBuilder CreateBuilder(string source) => new ProjectBuilder()
.WithUserSource(source)
.WithAnalyzer<CA1036ComparisonSuppressor>()
.WithTargetFramework(TargetFramework.Net8_0)
.WithMicrosoftCodeAnalysisNetAnalyzers("CA1036");
}

0 comments on commit 9f22002

Please sign in to comment.