Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove ECS0200 suppression and update WellKnownTypes to not trigger ECS0600 #236

Merged
merged 5 commits into from
Oct 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/Analyzers/AsShouldBeUsedOnlyForInterfaceAnalyzer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ private static void RegisterCompilationStartAction(CompilationStartAnalysisConte
// Look for the Mock.As() method and provide it to Analyze to avoid looking it up multiple times.
#pragma warning disable ECS0900 // Minimize boxing and unboxing
ImmutableArray<IMethodSymbol> asMethods = mockTypes
.SelectMany(mockType => mockType.GetMembers(WellKnownTypeNames.As))
.SelectMany(mockType => mockType.GetMembers(WellKnownMoqNames.AsMethodName))
.OfType<IMethodSymbol>()
.Where(method => method.IsGenericMethod)
.ToImmutableArray();
rjmurillo marked this conversation as resolved.
Show resolved Hide resolved
Expand Down
32 changes: 16 additions & 16 deletions src/Analyzers/ConstructorArgumentsShouldMatchAnalyzer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@
if (expression is MemberAccessExpressionSyntax memberAccessExpressionSyntax)
{
if (memberAccessExpressionSyntax.Expression is IdentifierNameSyntax identifierNameSyntax
&& string.Equals(identifierNameSyntax.Identifier.ValueText, WellKnownTypeNames.MockBehavior, StringComparison.Ordinal))
&& string.Equals(identifierNameSyntax.Identifier.ValueText, WellKnownMoqNames.MockBehaviorTypeName, StringComparison.Ordinal))
rjmurillo marked this conversation as resolved.
Show resolved Hide resolved
{
return true;
}
Expand Down Expand Up @@ -107,14 +107,14 @@
}

if (typeSymbol != null
&& string.Equals(typeSymbol.Name, WellKnownTypeNames.MockBehavior, StringComparison.Ordinal))
&& string.Equals(typeSymbol.Name, WellKnownMoqNames.MockBehaviorTypeName, StringComparison.Ordinal))
{
return true;
}
}

// Crude fallback to check if the expression is a Moq.MockBehavior enum
if (expression.ToString().StartsWith(WellKnownTypeNames.MoqBehavior, StringComparison.Ordinal))
if (expression.ToString().StartsWith(WellKnownMoqNames.FullyQualifiedMoqBehaviorTypeName, StringComparison.Ordinal))
{
return true;
}
Expand Down Expand Up @@ -205,18 +205,18 @@
return;
}

switch (genericNameSyntax.Identifier.Value)
if (genericNameSyntax.Identifier.Value is not string genericNameSyntaxIdentifierValue)
{
case WellKnownTypeNames.Create:
AnalyzeInvocation(context, invocationExpressionSyntax, WellKnownTypeNames.MockFactory, true, true);
break;

case WellKnownTypeNames.Of:
AnalyzeInvocation(context, invocationExpressionSyntax, WellKnownTypeNames.MockName, false, true);
break;
return;
}
rjmurillo marked this conversation as resolved.
Show resolved Hide resolved

default:
return;
if (string.Equals(genericNameSyntaxIdentifierValue, WellKnownMoqNames.CreateMethodName, StringComparison.Ordinal))
{
AnalyzeInvocation(context, invocationExpressionSyntax, WellKnownMoqNames.MockFactoryTypeName, true, true);
}
else if (string.Equals(genericNameSyntaxIdentifierValue, WellKnownMoqNames.OfMethodName, StringComparison.Ordinal))

Check failure on line 217 in src/Analyzers/ConstructorArgumentsShouldMatchAnalyzer.cs

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

src/Analyzers/ConstructorArgumentsShouldMatchAnalyzer.cs#L217

Add the missing 'else' clause with either the appropriate action or a suitable comment as to why no action is taken.
{
AnalyzeInvocation(context, invocationExpressionSyntax, WellKnownMoqNames.MockTypeName, false, true);
rjmurillo marked this conversation as resolved.
Show resolved Hide resolved
}
}

Expand Down Expand Up @@ -252,7 +252,7 @@

// We are calling MockRepository.Create<T> or Mock.Of<T>, determine which
ArgumentListSyntax? argumentList = null;
if (WellKnownTypeNames.Of.Equals(method.Name, StringComparison.Ordinal))
if (WellKnownMoqNames.OfMethodName.Equals(method.Name, StringComparison.Ordinal))
{
// Mock.Of<T> can specify condition for construction and MockBehavior, but
// cannot specify constructor parameters
Expand Down Expand Up @@ -286,7 +286,7 @@
// Quick check
if (!string.Equals(
genericNameSyntax.Identifier.ValueText,
WellKnownTypeNames.MockName,
WellKnownMoqNames.MockTypeName,
rjmurillo marked this conversation as resolved.
Show resolved Hide resolved
StringComparison.Ordinal))
{
return;
Expand All @@ -297,7 +297,7 @@

if (symbolInfo.Symbol is not IMethodSymbol mockConstructorMethod
|| mockConstructorMethod.MethodKind != MethodKind.Constructor
|| !string.Equals(mockConstructorMethod.ContainingType.ConstructedFrom.ContainingSymbol.Name, WellKnownTypeNames.Moq, StringComparison.Ordinal))
|| !string.Equals(mockConstructorMethod.ContainingType.ConstructedFrom.ContainingSymbol.Name, WellKnownMoqNames.MoqSymbolName, StringComparison.Ordinal))
{
return;
}
Expand Down
4 changes: 2 additions & 2 deletions src/Analyzers/SetExplicitMockBehaviorAnalyzer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ private static void RegisterCompilationStartAction(CompilationStartAnalysisConte
}

// Look for the MockBehavior type and provide it to Analyze to avoid looking it up multiple times.
INamedTypeSymbol? mockBehaviorSymbol = context.Compilation.GetTypeByMetadataName(WellKnownTypeNames.MoqBehavior);
INamedTypeSymbol? mockBehaviorSymbol = context.Compilation.GetTypeByMetadataName(WellKnownMoqNames.FullyQualifiedMoqBehaviorTypeName);
if (mockBehaviorSymbol is null)
{
return;
Expand All @@ -51,7 +51,7 @@ private static void RegisterCompilationStartAction(CompilationStartAnalysisConte
// Look for the Mock.Of() method and provide it to Analyze to avoid looking it up multiple times.
#pragma warning disable ECS0900 // Minimize boxing and unboxing
ImmutableArray<IMethodSymbol> ofMethods = mockTypes
.SelectMany(mockType => mockType.GetMembers(WellKnownTypeNames.Of))
.SelectMany(mockType => mockType.GetMembers(WellKnownMoqNames.OfMethodName))
.OfType<IMethodSymbol>()
.Where(method => method.IsGenericMethod)
.ToImmutableArray();
Expand Down
2 changes: 1 addition & 1 deletion src/Common/CompilationExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,6 @@ public static ImmutableArray<INamedTypeSymbol> GetTypesByMetadataNames(this Comp
/// </returns>
public static ImmutableArray<INamedTypeSymbol> GetMoqMock(this Compilation compilation)
{
return compilation.GetTypesByMetadataNames([WellKnownTypeNames.MoqMock, WellKnownTypeNames.MoqMock1, WellKnownTypeNames.MoqRepository]);
return compilation.GetTypesByMetadataNames([WellKnownMoqNames.FullyQualifiedMoqMockTypeName, WellKnownMoqNames.FullyQualifiedMoqMock1TypeName, WellKnownMoqNames.FullyQualifiedMoqRepositoryTypeName]);
rjmurillo marked this conversation as resolved.
Show resolved Hide resolved
}
}
4 changes: 2 additions & 2 deletions src/Common/MoqMethodDescriptorBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
/// </remarks>
internal abstract class MoqMethodDescriptorBase
{
private static readonly string ContainingNamespace = WellKnownTypeNames.Moq;
private static readonly string ContainingType = WellKnownTypeNames.MockName;
private static readonly string ContainingNamespace = WellKnownMoqNames.MoqNamespace;
private static readonly string ContainingType = WellKnownMoqNames.MockTypeName;
rjmurillo marked this conversation as resolved.
Show resolved Hide resolved

public abstract bool IsMatch(SemanticModel semanticModel, MemberAccessExpressionSyntax memberAccessSyntax, CancellationToken cancellationToken);

rjmurillo marked this conversation as resolved.
Show resolved Hide resolved
Expand Down
74 changes: 74 additions & 0 deletions src/Common/WellKnownMoqNames.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
namespace Moq.Analyzers.Common;

Check failure on line 1 in src/Common/WellKnownMoqNames.cs

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

src/Common/WellKnownMoqNames.cs#L1

Provide an 'AssemblyVersion' attribute for assembly 'srcassembly.dll'.
rjmurillo marked this conversation as resolved.
Show resolved Hide resolved

/// <summary>
/// Provides well-known names and fully qualified names for commonly used Moq types, namespaces, and members.
/// </summary>
internal static class WellKnownMoqNames
{
/// <summary>
/// Represents the namespace for the Moq library.
/// </summary>
internal static readonly string MoqNamespace = "Moq";

/// <summary>
/// Symbol name for Moq.
/// </summary>
internal static readonly string MoqSymbolName = "Moq";

/// <summary>
/// The name of the 'Moq.Mock' type.
/// </summary>
internal static readonly string MockTypeName = "Mock";

/// <summary>
/// The name of the 'Moq.MockBehavior' type.
/// This type specifies the behavior of the mock (Strict, Loose, etc.).
/// </summary>
internal static readonly string MockBehaviorTypeName = "MockBehavior";

/// <summary>
/// The name of the 'Moq.MockFactory' type.
/// This factory is used for creating multiple mock objects with a shared configuration.
/// </summary>
internal static readonly string MockFactoryTypeName = "MockFactory";

rjmurillo marked this conversation as resolved.
Show resolved Hide resolved
/// <summary>
/// Fully qualified name for the 'Moq.Mock' type.
/// </summary>
internal static readonly string FullyQualifiedMoqMockTypeName = $"{MoqNamespace}.{MockTypeName}";

/// <summary>
/// Fully qualified name for the generic version of 'Moq.Mock{T}'.
/// Represents mocks for specific types.
/// </summary>
internal static readonly string FullyQualifiedMoqMock1TypeName = $"{FullyQualifiedMoqMockTypeName}`1";

/// <summary>
/// Fully qualified name for the 'Moq.MockBehavior' type.
/// </summary>
internal static readonly string FullyQualifiedMoqBehaviorTypeName = $"{MoqNamespace}.{MockBehaviorTypeName}";

/// <summary>
/// Fully qualified name for the 'Moq.MockRepository' type.
/// This type acts as a container for multiple mocks and shared mock configurations.
/// </summary>
internal static readonly string FullyQualifiedMoqRepositoryTypeName = $"{MoqNamespace}.MockRepository";

rjmurillo marked this conversation as resolved.
Show resolved Hide resolved
/// <summary>
/// Represents the method name for the `As` method in Moq.
/// This method is used to cast mocks to interfaces.
/// </summary>
internal static readonly string AsMethodName = "As";

/// <summary>
/// Represents the method name for the `Create` method in Moq.
/// This method is used to create instances of mocks.
/// </summary>
internal static readonly string CreateMethodName = "Create";

/// <summary>
/// Represents the method name for the `Of` method in Moq.
/// This method is used to create a mock from a type without directly specifying the constructor.
/// </summary>
internal static readonly string OfMethodName = "Of";
}
18 changes: 0 additions & 18 deletions src/Common/WellKnownTypeNames.cs

This file was deleted.