Skip to content

Commit cd73017

Browse files
Bart KoelmanBart Koelman
authored andcommitted
AV1739: Updated for anonymous methods
1 parent cc6ad5b commit cd73017

File tree

2 files changed

+118
-15
lines changed

2 files changed

+118
-15
lines changed

src/CSharpGuidelinesAnalyzer/CSharpGuidelinesAnalyzer.Test/Specs/Naming/UseUnderscoreForUnusedLambdaParameterSpecs.cs

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,105 @@ public sealed class UseUnderscoreForUnusedLambdaParameterSpecs : CSharpGuideline
99
{
1010
protected override string DiagnosticId => UseUnderscoreForUnusedLambdaParameterAnalyzer.DiagnosticId;
1111

12+
[Fact]
13+
internal void When_anonymous_method_parameter_is_unused_in_body_it_must_be_reported()
14+
{
15+
// Arrange
16+
ParsedSourceCode source = new MemberSourceCodeBuilder()
17+
.InDefaultClass(@"
18+
void M()
19+
{
20+
N(delegate(int [|x|])
21+
{
22+
return true;
23+
});
24+
}
25+
26+
void N(Func<int, bool> f)
27+
{
28+
}
29+
")
30+
.Build();
31+
32+
// Act and assert
33+
VerifyGuidelineDiagnostic(source,
34+
"Unused anonymous method parameter 'x' should be renamed to underscore(s).");
35+
}
36+
37+
[Fact]
38+
internal void When_anonymous_method_parameters_are_unused_in_body_it_must_be_reported()
39+
{
40+
// Arrange
41+
ParsedSourceCode source = new MemberSourceCodeBuilder()
42+
.InDefaultClass(@"
43+
void M()
44+
{
45+
N(delegate(int [|x|], int [|y|])
46+
{
47+
return true;
48+
});
49+
}
50+
51+
void N(Func<int, int, bool> f)
52+
{
53+
}
54+
")
55+
.Build();
56+
57+
// Act and assert
58+
VerifyGuidelineDiagnostic(source,
59+
"Unused anonymous method parameter 'x' should be renamed to underscore(s).",
60+
"Unused anonymous method parameter 'y' should be renamed to underscore(s).");
61+
}
62+
63+
[Fact]
64+
internal void When_unused_anonymous_method_parameter_is_named_underscore_it_must_be_skipped()
65+
{
66+
// Arrange
67+
ParsedSourceCode source = new MemberSourceCodeBuilder()
68+
.InDefaultClass(@"
69+
void M()
70+
{
71+
N(delegate(int _)
72+
{
73+
return true;
74+
});
75+
}
76+
77+
void N(Func<int, bool> f)
78+
{
79+
}
80+
")
81+
.Build();
82+
83+
// Act and assert
84+
VerifyGuidelineDiagnostic(source);
85+
}
86+
87+
[Fact]
88+
internal void When_unused_anonymous_method_parameters_are_named_with_underscores_it_must_be_skipped()
89+
{
90+
// Arrange
91+
ParsedSourceCode source = new MemberSourceCodeBuilder()
92+
.InDefaultClass(@"
93+
void M()
94+
{
95+
N(delegate(int _, int __)
96+
{
97+
return true;
98+
});
99+
}
100+
101+
void N(Func<int, int, bool> f)
102+
{
103+
}
104+
")
105+
.Build();
106+
107+
// Act and assert
108+
VerifyGuidelineDiagnostic(source);
109+
}
110+
12111
[Fact]
13112
internal void When_lambda_parameter_is_unused_in_body_it_must_be_reported()
14113
{

src/CSharpGuidelinesAnalyzer/CSharpGuidelinesAnalyzer/Rules/Naming/UseUnderscoreForUnusedLambdaParameterAnalyzer.cs

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using CSharpGuidelinesAnalyzer.Extensions;
55
using JetBrains.Annotations;
66
using Microsoft.CodeAnalysis;
7+
using Microsoft.CodeAnalysis.CSharp.Syntax;
78
using Microsoft.CodeAnalysis.Diagnostics;
89
using Microsoft.CodeAnalysis.Operations;
910

@@ -15,7 +16,7 @@ public sealed class UseUnderscoreForUnusedLambdaParameterAnalyzer : DiagnosticAn
1516
public const string DiagnosticId = "AV1739";
1617

1718
private const string Title = "Unused lambda parameter should be renamed to underscore(s)";
18-
private const string MessageFormat = "Unused lambda parameter '{0}' should be renamed to underscore(s).";
19+
private const string MessageFormat = "Unused {0} parameter '{1}' should be renamed to underscore(s).";
1920
private const string Description = "Use an underscore for irrelevant lambda parameters.";
2021

2122
[NotNull]
@@ -71,7 +72,10 @@ private static void AnalyzeParameterUsage([ItemNotNull] ImmutableArray<IParamete
7172
{
7273
if (IsRegularParameter(parameter) && !IsParameterUsed(parameter, dataFlowAnalysis))
7374
{
74-
context.ReportDiagnostic(Diagnostic.Create(Rule, parameter.Locations[0], parameter.Name));
75+
string functionKind = context.Operation.Syntax is AnonymousMethodExpressionSyntax
76+
? "anonymous method"
77+
: "lambda";
78+
context.ReportDiagnostic(Diagnostic.Create(Rule, parameter.Locations[0], functionKind, parameter.Name));
7579
}
7680
}
7781
}
@@ -81,19 +85,6 @@ private static bool IsRegularParameter([NotNull] IParameterSymbol parameter)
8185
return !parameter.IsSynthesized() && !ConsistsOfUnderscoresOnly(parameter.Name);
8286
}
8387

84-
[CanBeNull]
85-
private static DataFlowAnalysis TryAnalyzeDataFlow([NotNull] SyntaxNode bodySyntax, [NotNull] Compilation compilation)
86-
{
87-
SemanticModel model = compilation.GetSemanticModel(bodySyntax.SyntaxTree);
88-
return model.SafeAnalyzeDataFlow(bodySyntax);
89-
}
90-
91-
private static bool IsParameterUsed([NotNull] IParameterSymbol parameter, [NotNull] DataFlowAnalysis dataFlowAnalysis)
92-
{
93-
return dataFlowAnalysis.ReadInside.Contains(parameter) || dataFlowAnalysis.WrittenInside.Contains(parameter) ||
94-
dataFlowAnalysis.Captured.Contains(parameter);
95-
}
96-
9788
private static bool ConsistsOfUnderscoresOnly([NotNull] string identifierName)
9889
{
9990
foreach (char ch in identifierName)
@@ -106,5 +97,18 @@ private static bool ConsistsOfUnderscoresOnly([NotNull] string identifierName)
10697

10798
return true;
10899
}
100+
101+
[CanBeNull]
102+
private static DataFlowAnalysis TryAnalyzeDataFlow([NotNull] SyntaxNode bodySyntax, [NotNull] Compilation compilation)
103+
{
104+
SemanticModel model = compilation.GetSemanticModel(bodySyntax.SyntaxTree);
105+
return model.SafeAnalyzeDataFlow(bodySyntax);
106+
}
107+
108+
private static bool IsParameterUsed([NotNull] IParameterSymbol parameter, [NotNull] DataFlowAnalysis dataFlowAnalysis)
109+
{
110+
return dataFlowAnalysis.ReadInside.Contains(parameter) || dataFlowAnalysis.WrittenInside.Contains(parameter) ||
111+
dataFlowAnalysis.Captured.Contains(parameter);
112+
}
109113
}
110114
}

0 commit comments

Comments
 (0)