|
7 | 7 | using System.Collections.Immutable; |
8 | 8 | using System.Composition; |
9 | 9 |
|
10 | | -namespace FluentAssertions.Analyzers |
| 10 | +namespace FluentAssertions.Analyzers; |
| 11 | + |
| 12 | +[DiagnosticAnalyzer(LanguageNames.CSharp)] |
| 13 | +public class CollectionShouldBeEmptyAnalyzer : CollectionAnalyzer |
11 | 14 | { |
12 | | - [DiagnosticAnalyzer(LanguageNames.CSharp)] |
13 | | - public class CollectionShouldBeEmptyAnalyzer : CollectionAnalyzer |
14 | | - { |
15 | | - public const string DiagnosticId = Constants.Tips.Collections.CollectionsShouldBeEmpty; |
16 | | - public const string Category = Constants.Tips.Category; |
| 15 | + public const string DiagnosticId = Constants.Tips.Collections.CollectionsShouldBeEmpty; |
| 16 | + public const string Category = Constants.Tips.Category; |
17 | 17 |
|
18 | | - public const string Message = "Use .Should().BeEmpty() instead."; |
| 18 | + public const string Message = "Use .Should().BeEmpty() instead."; |
19 | 19 |
|
20 | | - protected override DiagnosticDescriptor Rule => new DiagnosticDescriptor(DiagnosticId, Title, Message, Category, DiagnosticSeverity.Info, true); |
21 | | - protected override IEnumerable<FluentAssertionsCSharpSyntaxVisitor> Visitors |
| 20 | + protected override DiagnosticDescriptor Rule => new DiagnosticDescriptor(DiagnosticId, Title, Message, Category, DiagnosticSeverity.Info, true); |
| 21 | + protected override IEnumerable<FluentAssertionsCSharpSyntaxVisitor> Visitors |
| 22 | + { |
| 23 | + get |
22 | 24 | { |
23 | | - get |
24 | | - { |
25 | | - yield return new AnyShouldBeFalseSyntaxVisitor(); |
26 | | - yield return new ShouldHaveCount0SyntaxVisitor(); |
27 | | - } |
| 25 | + yield return new AnyShouldBeFalseSyntaxVisitor(); |
| 26 | + yield return new ShouldHaveCount0SyntaxVisitor(); |
28 | 27 | } |
| 28 | + } |
29 | 29 |
|
30 | | - public class AnyShouldBeFalseSyntaxVisitor : FluentAssertionsCSharpSyntaxVisitor |
| 30 | + public class AnyShouldBeFalseSyntaxVisitor : FluentAssertionsCSharpSyntaxVisitor |
| 31 | + { |
| 32 | + public AnyShouldBeFalseSyntaxVisitor() : base(MemberValidator.MethodNotContainingLambda("Any"), MemberValidator.Should, new MemberValidator("BeFalse")) |
31 | 33 | { |
32 | | - public AnyShouldBeFalseSyntaxVisitor() : base(MemberValidator.MethodNotContainingLambda("Any"), MemberValidator.Should, new MemberValidator("BeFalse")) |
33 | | - { |
34 | | - } |
35 | 34 | } |
| 35 | + } |
36 | 36 |
|
37 | | - public class ShouldHaveCount0SyntaxVisitor : FluentAssertionsCSharpSyntaxVisitor |
| 37 | + public class ShouldHaveCount0SyntaxVisitor : FluentAssertionsCSharpSyntaxVisitor |
| 38 | + { |
| 39 | + public ShouldHaveCount0SyntaxVisitor() : base(MemberValidator.Should, new MemberValidator("HaveCount", HaveCountArgumentsValidator)) |
38 | 40 | { |
39 | | - public ShouldHaveCount0SyntaxVisitor() : base(MemberValidator.Should, new MemberValidator("HaveCount", HaveCountArgumentsValidator)) |
40 | | - { |
41 | | - } |
| 41 | + } |
42 | 42 |
|
43 | | - private static bool HaveCountArgumentsValidator(SeparatedSyntaxList<ArgumentSyntax> arguments, SemanticModel semanticModel) |
44 | | - { |
45 | | - if (!arguments.Any()) return false; |
| 43 | + private static bool HaveCountArgumentsValidator(SeparatedSyntaxList<ArgumentSyntax> arguments, SemanticModel semanticModel) |
| 44 | + { |
| 45 | + if (!arguments.Any()) return false; |
46 | 46 |
|
47 | | - return arguments[0].Expression is LiteralExpressionSyntax literal |
48 | | - && literal.Token.Value is int argument |
49 | | - && argument == 0; |
50 | | - } |
| 47 | + return arguments[0].Expression is LiteralExpressionSyntax literal |
| 48 | + && literal.Token.Value is int argument |
| 49 | + && argument == 0; |
51 | 50 | } |
52 | 51 | } |
| 52 | +} |
53 | 53 |
|
54 | | - [ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(CollectionShouldBeEmptyCodeFix)), Shared] |
55 | | - public class CollectionShouldBeEmptyCodeFix : FluentAssertionsCodeFixProvider |
56 | | - { |
57 | | - public override ImmutableArray<string> FixableDiagnosticIds => ImmutableArray.Create(CollectionShouldBeEmptyAnalyzer.DiagnosticId); |
| 54 | +[ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(CollectionShouldBeEmptyCodeFix)), Shared] |
| 55 | +public class CollectionShouldBeEmptyCodeFix : FluentAssertionsCodeFixProvider |
| 56 | +{ |
| 57 | + public override ImmutableArray<string> FixableDiagnosticIds => ImmutableArray.Create(CollectionShouldBeEmptyAnalyzer.DiagnosticId); |
58 | 58 |
|
59 | | - protected override ExpressionSyntax GetNewExpression(ExpressionSyntax expression, FluentAssertionsDiagnosticProperties properties) |
| 59 | + protected override ExpressionSyntax GetNewExpression(ExpressionSyntax expression, FluentAssertionsDiagnosticProperties properties) |
| 60 | + { |
| 61 | + switch (properties.VisitorName) |
60 | 62 | { |
61 | | - switch (properties.VisitorName) |
62 | | - { |
63 | | - case nameof(CollectionShouldBeEmptyAnalyzer.AnyShouldBeFalseSyntaxVisitor): |
64 | | - return GetNewExpression(expression, NodeReplacement.Remove("Any"), NodeReplacement.Rename("BeFalse", "BeEmpty")); |
65 | | - case nameof(CollectionShouldBeEmptyAnalyzer.ShouldHaveCount0SyntaxVisitor): |
66 | | - return GetNewExpression(expression, new HaveCountNodeReplacement()); |
67 | | - default: |
68 | | - throw new System.InvalidOperationException($"Invalid visitor name - {properties.VisitorName}"); |
69 | | - } |
| 63 | + case nameof(CollectionShouldBeEmptyAnalyzer.AnyShouldBeFalseSyntaxVisitor): |
| 64 | + return GetNewExpression(expression, NodeReplacement.Remove("Any"), NodeReplacement.Rename("BeFalse", "BeEmpty")); |
| 65 | + case nameof(CollectionShouldBeEmptyAnalyzer.ShouldHaveCount0SyntaxVisitor): |
| 66 | + return GetNewExpression(expression, new HaveCountNodeReplacement()); |
| 67 | + default: |
| 68 | + throw new System.InvalidOperationException($"Invalid visitor name - {properties.VisitorName}"); |
70 | 69 | } |
| 70 | + } |
71 | 71 |
|
72 | | - private class HaveCountNodeReplacement : NodeReplacement |
| 72 | + private class HaveCountNodeReplacement : NodeReplacement |
| 73 | + { |
| 74 | + public override bool IsValidNode(LinkedListNode<MemberAccessExpressionSyntax> listNode) => listNode.Value.Name.Identifier.Text == "HaveCount"; |
| 75 | + public override SyntaxNode ComputeOld(LinkedListNode<MemberAccessExpressionSyntax> listNode) => listNode.Value.Parent; |
| 76 | + public override SyntaxNode ComputeNew(LinkedListNode<MemberAccessExpressionSyntax> listNode) |
73 | 77 | { |
74 | | - public override bool IsValidNode(LinkedListNode<MemberAccessExpressionSyntax> listNode) => listNode.Value.Name.Identifier.Text == "HaveCount"; |
75 | | - public override SyntaxNode ComputeOld(LinkedListNode<MemberAccessExpressionSyntax> listNode) => listNode.Value.Parent; |
76 | | - public override SyntaxNode ComputeNew(LinkedListNode<MemberAccessExpressionSyntax> listNode) |
77 | | - { |
78 | | - var invocation = (InvocationExpressionSyntax)listNode.Value.Parent; |
| 78 | + var invocation = (InvocationExpressionSyntax)listNode.Value.Parent; |
79 | 79 |
|
80 | | - invocation = invocation.ReplaceNode(listNode.Value, listNode.Value.WithName(SyntaxFactory.IdentifierName("BeEmpty"))); |
| 80 | + invocation = invocation.ReplaceNode(listNode.Value, listNode.Value.WithName(SyntaxFactory.IdentifierName("BeEmpty"))); |
81 | 81 |
|
82 | | - // remove the 0 argument |
83 | | - var arguments = invocation.ArgumentList.Arguments.RemoveAt(0); |
| 82 | + // remove the 0 argument |
| 83 | + var arguments = invocation.ArgumentList.Arguments.RemoveAt(0); |
84 | 84 |
|
85 | | - return invocation.WithArgumentList(invocation.ArgumentList.WithArguments(arguments)); |
86 | | - } |
| 85 | + return invocation.WithArgumentList(invocation.ArgumentList.WithArguments(arguments)); |
87 | 86 | } |
88 | 87 | } |
89 | 88 | } |
0 commit comments