Skip to content

Commit 8e3eab4

Browse files
authored
Merge pull request #849 from polyadic/refactor-analyzers
2 parents 4d913b5 + 26702d5 commit 8e3eab4

File tree

50 files changed

+342
-256
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+342
-256
lines changed

Funcky.Analyzers/Funcky.Analyzers.CodeFixes/AlternativeMonad/MatchToNullableCodeFix.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
using System.Collections.Immutable;
22
using System.Composition;
3+
using Funcky.Analyzers.CodeAnalysisExtensions;
34
using Microsoft.CodeAnalysis;
45
using Microsoft.CodeAnalysis.CodeActions;
56
using Microsoft.CodeAnalysis.CodeFixes;
67
using Microsoft.CodeAnalysis.CSharp.Syntax;
78
using Microsoft.CodeAnalysis.Editing;
8-
using static Funcky.Analyzers.AlternativeMonadAnalyzer;
9+
using static Funcky.Analyzers.AlternativeMonad.AlternativeMonadAnalyzer;
910
using static Funcky.Analyzers.FunckyWellKnownMemberNames;
1011
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
1112

Funcky.Analyzers/Funcky.Analyzers.CodeFixes/AlternativeMonad/MatchToOrElseCodeFix.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
using System.Collections.Immutable;
22
using System.Composition;
3+
using Funcky.Analyzers.CodeAnalysisExtensions;
34
using Microsoft.CodeAnalysis;
45
using Microsoft.CodeAnalysis.CodeActions;
56
using Microsoft.CodeAnalysis.CodeFixes;
67
using Microsoft.CodeAnalysis.CSharp.Syntax;
78
using Microsoft.CodeAnalysis.Editing;
8-
using static Funcky.Analyzers.AlternativeMonadAnalyzer;
9+
using static Funcky.Analyzers.AlternativeMonad.AlternativeMonadAnalyzer;
910
using static Funcky.Analyzers.FunckyWellKnownMemberNames;
1011
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
1112

Funcky.Analyzers/Funcky.Analyzers.CodeFixes/DiagnosticExtensions.cs Funcky.Analyzers/Funcky.Analyzers.CodeFixes/CodeAnalysisExtensions/DiagnosticExtensions.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
using System.Diagnostics.CodeAnalysis;
22
using Microsoft.CodeAnalysis;
33

4-
namespace Funcky.Analyzers;
4+
namespace Funcky.Analyzers.CodeAnalysisExtensions;
55

66
internal static class DiagnosticExtensions
77
{

Funcky.Analyzers/Funcky.Analyzers.CodeFixes/SyntaxGeneratorExtensions.cs Funcky.Analyzers/Funcky.Analyzers.CodeFixes/CodeAnalysisExtensions/SyntaxGeneratorExtensions.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
using Microsoft.CodeAnalysis;
22
using Microsoft.CodeAnalysis.Editing;
33

4-
namespace Funcky.Analyzers;
4+
namespace Funcky.Analyzers.CodeAnalysisExtensions;
55

66
internal static class SyntaxGeneratorExtensions
77
{
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using Microsoft.CodeAnalysis;
2+
using Microsoft.CodeAnalysis.CSharp;
3+
using Microsoft.CodeAnalysis.CSharp.Syntax;
4+
using Microsoft.CodeAnalysis.Operations;
5+
6+
namespace Funcky.Analyzers.CodeAnalysisExtensions;
7+
8+
internal static partial class SyntaxNodeExtensions
9+
{
10+
public static TNode ReplaceParameterReferences<TNode>(this TNode node, SemanticModel semanticModel, string parameterName, ExpressionSyntax replacement)
11+
where TNode : SyntaxNode
12+
=> (TNode)new ReplaceParameterReferenceRewriter(semanticModel, parameterName, replacement).Visit(node);
13+
14+
private sealed class ReplaceParameterReferenceRewriter(
15+
SemanticModel semanticModel,
16+
string parameterName,
17+
ExpressionSyntax replacement)
18+
: CSharpSyntaxRewriter(visitIntoStructuredTrivia: false)
19+
{
20+
public override SyntaxNode VisitIdentifierName(IdentifierNameSyntax node)
21+
=> semanticModel.GetOperation(node) is IParameterReferenceOperation { Parameter.Name: var name } && name == parameterName
22+
? replacement.WithTriviaFrom(node)
23+
: node;
24+
}
25+
}

Funcky.Analyzers/Funcky.Analyzers.CodeFixes/SyntaxNodeExtensions.cs Funcky.Analyzers/Funcky.Analyzers.CodeFixes/CodeAnalysisExtensions/SyntaxNodeExtensions.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
using Microsoft.CodeAnalysis.CSharp.Syntax;
33
using Microsoft.CodeAnalysis.Text;
44

5-
namespace Funcky.Analyzers;
5+
namespace Funcky.Analyzers.CodeAnalysisExtensions;
66

77
internal static partial class SyntaxNodeExtensions
88
{

Funcky.Analyzers/Funcky.Analyzers.CodeFixes/EnumerableRepeatNeverCodeFix.cs

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System.Collections.Immutable;
22
using System.Composition;
3+
using Funcky.Analyzers.CodeAnalysisExtensions;
34
using Microsoft.CodeAnalysis;
45
using Microsoft.CodeAnalysis.CodeActions;
56
using Microsoft.CodeAnalysis.CodeFixes;

Funcky.Analyzers/Funcky.Analyzers.CodeFixes/EnumerableRepeatOnceCodeFix.cs

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System.Collections.Immutable;
22
using System.Composition;
3+
using Funcky.Analyzers.CodeAnalysisExtensions;
34
using Microsoft.CodeAnalysis;
45
using Microsoft.CodeAnalysis.CodeActions;
56
using Microsoft.CodeAnalysis.CodeFixes;

Funcky.Analyzers/Funcky.Analyzers.CodeFixes/Funcky.Analyzers.CodeFixes.targets

+4
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@
1616
<PropertyGroup>
1717
<AnalyzerLanguage>cs</AnalyzerLanguage>
1818
</PropertyGroup>
19+
<ItemGroup>
20+
<Compile Include="..\Funcky.Analyzers\CodeAnalysisExtensions\SymbolEqualityFunctions.cs" Link="CodeAnalysisExtensions\%(Filename)%(Extension)" />
21+
<Using Include="Funcky.Analyzers.CodeAnalysisExtensions.SymbolEqualityFunctions" Static="true" />
22+
</ItemGroup>
1923
<ItemGroup>
2024
<PackageReference Include="PolySharp" PrivateAssets="all" />
2125
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" VersionOverride="$(AnalyzerRoslynVersion)" PrivateAssets="all" />

Funcky.Analyzers/Funcky.Analyzers.CodeFixes/FunctionalAssertFix.cs

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System.Collections.Immutable;
22
using System.Composition;
3+
using Funcky.Analyzers.CodeAnalysisExtensions;
34
using Microsoft.CodeAnalysis;
45
using Microsoft.CodeAnalysis.CodeActions;
56
using Microsoft.CodeAnalysis.CodeFixes;

Funcky.Analyzers/Funcky.Analyzers.CodeFixes/OptionSomeWhereToFromBooleanRefactoring.cs

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System.Composition;
22
using System.Diagnostics.CodeAnalysis;
3+
using Funcky.Analyzers.CodeAnalysisExtensions;
34
using Microsoft.CodeAnalysis;
45
using Microsoft.CodeAnalysis.CodeActions;
56
using Microsoft.CodeAnalysis.CodeRefactorings;
@@ -52,15 +53,15 @@ private static bool IsWhereInvocation(SyntaxNode syntax, SemanticModel semanticM
5253
{
5354
whereInvocation = null;
5455
return semanticModel.GetOperation(syntax) is IInvocationOperation { TargetMethod.Name: WhereMethodName } operation
55-
&& SymbolEqualityComparer.Default.Equals(symbols.GenericOptionType, operation.TargetMethod.ContainingType.ConstructedFrom)
56+
&& SymbolEquals(symbols.GenericOptionType, operation.TargetMethod.ContainingType.ConstructedFrom)
5657
&& (whereInvocation = operation) is var _;
5758
}
5859

5960
private static bool IsOptionReturnInvocation(IOperation? candidate, Symbols symbols, [NotNullWhen(true)] out IInvocationOperation? returnInvocationOperation)
6061
{
6162
returnInvocationOperation = null;
6263
return candidate is IInvocationOperation { TargetMethod.Name: MonadReturnMethodName or OptionSomeMethodName } operation
63-
&& SymbolEqualityComparer.Default.Equals(symbols.OptionType, operation.TargetMethod.ContainingType)
64+
&& SymbolEquals(symbols.OptionType, operation.TargetMethod.ContainingType)
6465
&& (returnInvocationOperation = operation) is var _;
6566
}
6667

Funcky.Analyzers/Funcky.Analyzers.CodeFixes/ReplaceParameterReferenceRewriter.cs

-25
This file was deleted.

Funcky.Analyzers/Funcky.Analyzers.Test/AlternativeMonadAnalyzerTest.Stubs.cs Funcky.Analyzers/Funcky.Analyzers.Test/AlternativeMonad/AlternativeMonadAnalyzerTest.Stubs.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
namespace Funcky.Analyzers.Test;
1+
namespace Funcky.Analyzers.Test.AlternativeMonad;
22

33
public sealed partial class AlternativeMonadAnalyzerTest
44
{

Funcky.Analyzers/Funcky.Analyzers.Test/AlternativeMonadAnalyzerTest.ToNullable.cs Funcky.Analyzers/Funcky.Analyzers.Test/AlternativeMonad/AlternativeMonadAnalyzerTest.ToNullable.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
#pragma warning disable SA1118 // StyleCop support for collection expressions is missing
22
using Xunit;
3-
using static Funcky.Analyzers.AlternativeMonadAnalyzer;
4-
using VerifyCS = Funcky.Analyzers.Test.CSharpCodeFixVerifier<Funcky.Analyzers.AlternativeMonadAnalyzer, Funcky.Analyzers.AlternativeMonad.MatchToNullableCodeFix>;
3+
using static Funcky.Analyzers.AlternativeMonad.AlternativeMonadAnalyzer;
4+
using VerifyCS = Funcky.Analyzers.Test.CSharpCodeFixVerifier<Funcky.Analyzers.AlternativeMonad.AlternativeMonadAnalyzer, Funcky.Analyzers.AlternativeMonad.MatchToNullableCodeFix>;
55

6-
namespace Funcky.Analyzers.Test;
6+
namespace Funcky.Analyzers.Test.AlternativeMonad;
77

88
public sealed partial class AlternativeMonadAnalyzerTest
99
{

Funcky.Analyzers/Funcky.Analyzers.Test/AlternativeMonadAnalyzerTest.cs Funcky.Analyzers/Funcky.Analyzers.Test/AlternativeMonad/AlternativeMonadAnalyzerTest.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
#pragma warning disable SA1118 // StyleCop support for collection expressions is missing
22
using Xunit;
3-
using static Funcky.Analyzers.AlternativeMonadAnalyzer;
4-
using VerifyCS = Funcky.Analyzers.Test.CSharpCodeFixVerifier<Funcky.Analyzers.AlternativeMonadAnalyzer, Funcky.Analyzers.AlternativeMonad.MatchToOrElseCodeFix>;
3+
using static Funcky.Analyzers.AlternativeMonad.AlternativeMonadAnalyzer;
4+
using VerifyCS = Funcky.Analyzers.Test.CSharpCodeFixVerifier<Funcky.Analyzers.AlternativeMonad.AlternativeMonadAnalyzer, Funcky.Analyzers.AlternativeMonad.MatchToOrElseCodeFix>;
55

6-
namespace Funcky.Analyzers.Test;
6+
namespace Funcky.Analyzers.Test.AlternativeMonad;
77

88
public sealed partial class AlternativeMonadAnalyzerTest
99
{

Funcky.Analyzers/Funcky.Analyzers.Test/NonDefaultableTest.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
using Microsoft.CodeAnalysis.Testing;
22
using Xunit;
3-
using VerifyCS = Funcky.Analyzers.Test.CSharpAnalyzerVerifier<Funcky.Analyzers.NonDefaultableAnalyzer>;
3+
using VerifyCS = Funcky.Analyzers.Test.CSharpAnalyzerVerifier<Funcky.Analyzers.NonDefaultable.NonDefaultableAnalyzer>;
44

55
namespace Funcky.Analyzers.Test;
66

Funcky.Analyzers/Funcky.Analyzers/AlternativeMonadAnalyzer/AlternativeMonadAnalyzer.GetOrElse.cs Funcky.Analyzers/Funcky.Analyzers/AlternativeMonad/AlternativeMonadAnalyzer.GetOrElse.cs

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
using Microsoft.CodeAnalysis;
22
using Microsoft.CodeAnalysis.Operations;
33
using static Funcky.Analyzers.FunckyWellKnownMemberNames;
4-
using static Funcky.Analyzers.IdentityFunctionMatching;
4+
using static Funcky.Analyzers.Functions.IdentityFunctionMatching;
55

6-
namespace Funcky.Analyzers;
6+
namespace Funcky.Analyzers.AlternativeMonad;
77

88
public partial class AlternativeMonadAnalyzer
99
{
@@ -18,8 +18,8 @@ public partial class AlternativeMonadAnalyzer
1818

1919
/// <summary>Tests for a <c>Match</c> invocation of the shape <c>Match(none: A, some: Identity)</c>.</summary>
2020
private static bool IsGetOrElseEquivalent(INamedTypeSymbol receiverType, IArgumentOperation errorStateArgument, IArgumentOperation successStateArgument)
21-
=> SymbolEqualityComparer.IncludeNullability.Equals(receiverType.TypeArguments.Last(), GetTypeOrDelegateReturnType(errorStateArgument.Value))
22-
&& SymbolEqualityComparer.Default.Equals(receiverType.TypeArguments.Last(), GetTypeOrDelegateReturnType(successStateArgument.Value))
21+
=> SymbolEqualsIncludeNullability(receiverType.TypeArguments.Last(), GetTypeOrDelegateReturnType(errorStateArgument.Value))
22+
&& SymbolEquals(receiverType.TypeArguments.Last(), GetTypeOrDelegateReturnType(successStateArgument.Value))
2323
&& IsIdentityFunction(successStateArgument.Value);
2424

2525
private static ITypeSymbol? GetTypeOrDelegateReturnType(IOperation operation)

Funcky.Analyzers/Funcky.Analyzers/AlternativeMonadAnalyzer/AlternativeMonadAnalyzer.OrElse.cs Funcky.Analyzers/Funcky.Analyzers/AlternativeMonad/AlternativeMonadAnalyzer.OrElse.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
using Microsoft.CodeAnalysis;
22
using Microsoft.CodeAnalysis.Operations;
3+
using static Funcky.Analyzers.AlternativeMonad.MonadReturnMatching;
34
using static Funcky.Analyzers.FunckyWellKnownMemberNames;
4-
using static Funcky.Analyzers.MonadReturnMatching;
55

6-
namespace Funcky.Analyzers;
6+
namespace Funcky.Analyzers.AlternativeMonad;
77

88
public partial class AlternativeMonadAnalyzer
99
{
@@ -18,6 +18,6 @@ public partial class AlternativeMonadAnalyzer
1818

1919
/// <summary>Tests for a <c>Match</c> invocation of the shape <c>Match(none: A, some: Option.Return)</c>.</summary>
2020
private static bool IsOrElseEquivalent(AlternativeMonadType alternativeMonadType, IInvocationOperation matchInvocation, INamedTypeSymbol receiverType, IArgumentOperation successStateArgument)
21-
=> SymbolEqualityComparer.IncludeNullability.Equals(receiverType, matchInvocation.Type)
21+
=> SymbolEqualsIncludeNullability(receiverType, matchInvocation.Type)
2222
&& IsReturnFunction(alternativeMonadType, successStateArgument.Value);
2323
}

Funcky.Analyzers/Funcky.Analyzers/AlternativeMonadAnalyzer/AlternativeMonadAnalyzer.SelectMany.cs Funcky.Analyzers/Funcky.Analyzers/AlternativeMonad/AlternativeMonadAnalyzer.SelectMany.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
using Microsoft.CodeAnalysis;
22
using Microsoft.CodeAnalysis.Operations;
3-
using static Funcky.Analyzers.AlternativeMonadErrorStateConstructorMatching;
3+
using static Funcky.Analyzers.AlternativeMonad.AlternativeMonadErrorStateConstructorMatching;
44
using static Funcky.Analyzers.FunckyWellKnownMemberNames;
55

6-
namespace Funcky.Analyzers;
6+
namespace Funcky.Analyzers.AlternativeMonad;
77

88
public partial class AlternativeMonadAnalyzer
99
{
@@ -18,6 +18,6 @@ public partial class AlternativeMonadAnalyzer
1818

1919
/// <summary>Tests for a <c>Match</c> invocation of the shape <c>Match(none: Option&lt;T&gt;>.None, some: A)</c>.</summary>
2020
private static bool IsSelectManyEquivalent(AlternativeMonadType alternativeMonadType, IInvocationOperation matchInvocation, INamedTypeSymbol receiverType, IArgumentOperation errorStateArgument)
21-
=> SymbolEqualityComparer.IncludeNullability.Equals(receiverType, matchInvocation.Type)
21+
=> SymbolEqualsIncludeNullability(receiverType, matchInvocation.Type)
2222
&& IsErrorStateConstructorReference(alternativeMonadType, errorStateArgument.Value);
2323
}

Funcky.Analyzers/Funcky.Analyzers/AlternativeMonadAnalyzer/AlternativeMonadAnalyzer.ToNullable.cs Funcky.Analyzers/Funcky.Analyzers/AlternativeMonad/AlternativeMonadAnalyzer.ToNullable.cs

+6-5
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1+
using Funcky.Analyzers.CodeAnalysisExtensions;
12
using Microsoft.CodeAnalysis;
23
using Microsoft.CodeAnalysis.Operations;
3-
using static Funcky.Analyzers.ConstantFunctionMatching;
44
using static Funcky.Analyzers.FunckyWellKnownMemberNames;
5-
using static Funcky.Analyzers.IdentityFunctionMatching;
5+
using static Funcky.Analyzers.Functions.ConstantFunctionMatching;
6+
using static Funcky.Analyzers.Functions.IdentityFunctionMatching;
67

7-
namespace Funcky.Analyzers;
8+
namespace Funcky.Analyzers.AlternativeMonad;
89

910
public partial class AlternativeMonadAnalyzer
1011
{
@@ -29,13 +30,13 @@ private static bool IsToNullableEquivalent(
2930

3031
bool IsToNullableReferenceType()
3132
=> itemType.IsReferenceType
32-
&& SymbolEqualityComparer.Default.Equals(receiverType.TypeArguments.Single(), matchInvocation.Type)
33+
&& SymbolEquals(receiverType.TypeArguments.Single(), matchInvocation.Type)
3334
&& IsNullOrNullFunction(noneArgument.Value)
3435
&& IsIdentityFunction(someArgument.Value);
3536

3637
bool IsToNullableValueType()
3738
=> itemType.IsValueType
38-
&& SymbolEqualityComparer.Default.Equals(matchInvocation.SemanticModel?.NullableOfT(itemType), matchInvocation.Type)
39+
&& SymbolEquals(matchInvocation.SemanticModel?.NullableOfT(itemType), matchInvocation.Type)
3940
&& IsNullOrNullFunction(noneArgument.Value)
4041
&& IsIdentityFunctionWithNullConversion(someArgument.Value);
4142

0 commit comments

Comments
 (0)