Skip to content

Commit 83176df

Browse files
committed
Merge pull request #1932 from Noryoko/fix-1930
Add checks for additional local variables in SA1305
2 parents f34bd02 + b04eb69 commit 83176df

2 files changed

Lines changed: 245 additions & 25 deletions

File tree

StyleCop.Analyzers/StyleCop.Analyzers.Test/NamingRules/SA1305UnitTests.cs

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,172 @@ public async Task TestExcludedPrefixesAreNotReportedAsync()
192192
await this.VerifyCSharpDiagnosticAsync(testCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
193193
}
194194

195+
[Fact]
196+
public async Task TestVariableInCatchDeclarationAsync()
197+
{
198+
var testCode = @"
199+
using System;
200+
public class TypeName
201+
{
202+
public void MethodName()
203+
{
204+
try
205+
{
206+
}
207+
catch (Exception exA)
208+
{
209+
}
210+
}
211+
}";
212+
213+
DiagnosticResult[] expected =
214+
{
215+
this.CSharpDiagnostic().WithArguments("variable", "exA").WithLocation(10, 26),
216+
};
217+
218+
await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false);
219+
}
220+
221+
[Fact]
222+
public async Task TestVariableInForEachStatementAsync()
223+
{
224+
var testCode = @"public class TypeName
225+
{
226+
public void MethodName()
227+
{
228+
foreach (var abX in new int[0])
229+
{
230+
}
231+
}
232+
}";
233+
234+
DiagnosticResult[] expected =
235+
{
236+
this.CSharpDiagnostic().WithArguments("variable", "abX").WithLocation(5, 22),
237+
};
238+
239+
await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false);
240+
}
241+
242+
[Fact]
243+
public async Task TestVariableInFromClauseAsync()
244+
{
245+
var testCode = @"
246+
using System.Linq;
247+
public class TypeName
248+
{
249+
public void MethodName()
250+
{
251+
var result =
252+
from abX in new int[0]
253+
select abX;
254+
}
255+
}";
256+
257+
DiagnosticResult[] expected =
258+
{
259+
this.CSharpDiagnostic().WithArguments("variable", "abX").WithLocation(8, 18),
260+
};
261+
262+
await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false);
263+
}
264+
265+
[Fact]
266+
public async Task TestVariableInQueryContinuationAsync()
267+
{
268+
var testCode = @"
269+
using System.Linq;
270+
public class TypeName
271+
{
272+
public void MethodName()
273+
{
274+
var result =
275+
from x in new int[0]
276+
select x into abY
277+
select abY;
278+
}
279+
}";
280+
281+
DiagnosticResult[] expected =
282+
{
283+
this.CSharpDiagnostic().WithArguments("variable", "abY").WithLocation(9, 27),
284+
};
285+
286+
await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false);
287+
}
288+
289+
[Fact]
290+
public async Task TestVariableInLetClauseAsync()
291+
{
292+
var testCode = @"
293+
using System.Linq;
294+
public class TypeName
295+
{
296+
public void MethodName()
297+
{
298+
var result =
299+
from x in new int[0]
300+
let abY = x
301+
select abY;
302+
}
303+
}";
304+
305+
DiagnosticResult[] expected =
306+
{
307+
this.CSharpDiagnostic().WithArguments("variable", "abY").WithLocation(9, 17),
308+
};
309+
310+
await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false);
311+
}
312+
313+
[Fact]
314+
public async Task TestVariableInJoinClauseAsync()
315+
{
316+
var testCode = @"
317+
using System.Linq;
318+
public class TypeName
319+
{
320+
public void MethodName()
321+
{
322+
var result =
323+
from x in new int[0]
324+
join abY in new int[0] on x equals abY
325+
select x;
326+
}
327+
}";
328+
329+
DiagnosticResult[] expected =
330+
{
331+
this.CSharpDiagnostic().WithArguments("variable", "abY").WithLocation(9, 18),
332+
};
333+
334+
await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false);
335+
}
336+
337+
[Fact]
338+
public async Task TestVariableInJoinIntoClauseAsync()
339+
{
340+
var testCode = @"
341+
using System.Linq;
342+
public class TypeName
343+
{
344+
public void MethodName()
345+
{
346+
var result =
347+
from x in new int[0]
348+
join y in new int[0] on x equals y into abZ
349+
select abZ;
350+
}
351+
}";
352+
353+
DiagnosticResult[] expected =
354+
{
355+
this.CSharpDiagnostic().WithArguments("variable", "abZ").WithLocation(9, 53),
356+
};
357+
358+
await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false);
359+
}
360+
195361
protected override IEnumerable<DiagnosticAnalyzer> GetCSharpDiagnosticAnalyzers()
196362
{
197363
yield return new SA1305FieldNamesMustNotUseHungarianNotation();

StyleCop.Analyzers/StyleCop.Analyzers/NamingRules/SA1305FieldNamesMustNotUseHungarianNotation.cs

Lines changed: 79 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,13 @@ internal class SA1305FieldNamesMustNotUseHungarianNotation : DiagnosticAnalyzer
6868

6969
private static readonly Action<CompilationStartAnalysisContext> CompilationStartAction = HandleCompilationStart;
7070
private static readonly Action<SyntaxNodeAnalysisContext, StyleCopSettings> VariableDeclarationAction = Analyzer.HandleVariableDeclaration;
71+
private static readonly Action<SyntaxNodeAnalysisContext, StyleCopSettings> CatchDeclarationAction = Analyzer.HandleCatchDeclaration;
72+
private static readonly Action<SyntaxNodeAnalysisContext, StyleCopSettings> QueryContinuationAction = Analyzer.HandleQueryContinuation;
73+
private static readonly Action<SyntaxNodeAnalysisContext, StyleCopSettings> FromClauseAction = Analyzer.HandleFromClause;
74+
private static readonly Action<SyntaxNodeAnalysisContext, StyleCopSettings> LetClauseAction = Analyzer.HandleLetClause;
75+
private static readonly Action<SyntaxNodeAnalysisContext, StyleCopSettings> JoinClauseAction = Analyzer.HandleJoinClause;
76+
private static readonly Action<SyntaxNodeAnalysisContext, StyleCopSettings> JoinIntoClauseAction = Analyzer.HandleJoinIntoClause;
77+
private static readonly Action<SyntaxNodeAnalysisContext, StyleCopSettings> ForEachStatementAction = Analyzer.HandleForEachStatement;
7178

7279
/// <inheritdoc/>
7380
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get; } =
@@ -82,6 +89,13 @@ public override void Initialize(AnalysisContext context)
8289
private static void HandleCompilationStart(CompilationStartAnalysisContext context)
8390
{
8491
context.RegisterSyntaxNodeActionHonorExclusions(VariableDeclarationAction, SyntaxKind.VariableDeclaration);
92+
context.RegisterSyntaxNodeActionHonorExclusions(CatchDeclarationAction, SyntaxKind.CatchDeclaration);
93+
context.RegisterSyntaxNodeActionHonorExclusions(QueryContinuationAction, SyntaxKind.QueryContinuation);
94+
context.RegisterSyntaxNodeActionHonorExclusions(FromClauseAction, SyntaxKind.FromClause);
95+
context.RegisterSyntaxNodeActionHonorExclusions(LetClauseAction, SyntaxKind.LetClause);
96+
context.RegisterSyntaxNodeActionHonorExclusions(JoinClauseAction, SyntaxKind.JoinClause);
97+
context.RegisterSyntaxNodeActionHonorExclusions(JoinIntoClauseAction, SyntaxKind.JoinIntoClause);
98+
context.RegisterSyntaxNodeActionHonorExclusions(ForEachStatementAction, SyntaxKind.ForEachStatement);
8599
}
86100

87101
private static class Analyzer
@@ -109,37 +123,77 @@ public static void HandleVariableDeclaration(SyntaxNodeAnalysisContext context,
109123
}
110124

111125
var identifier = variableDeclarator.Identifier;
112-
if (identifier.IsMissing)
113-
{
114-
continue;
115-
}
126+
CheckIdentifier(context, identifier, settings, fieldDeclaration);
127+
}
128+
}
116129

117-
string name = identifier.ValueText;
118-
if (string.IsNullOrEmpty(name))
119-
{
120-
continue;
121-
}
130+
public static void HandleCatchDeclaration(SyntaxNodeAnalysisContext context, StyleCopSettings settings)
131+
{
132+
CheckIdentifier(context, ((CatchDeclarationSyntax)context.Node).Identifier, settings);
133+
}
122134

123-
var match = HungarianRegex.Match(name);
124-
if (!match.Success)
125-
{
126-
continue;
127-
}
135+
public static void HandleQueryContinuation(SyntaxNodeAnalysisContext context, StyleCopSettings settings)
136+
{
137+
CheckIdentifier(context, ((QueryContinuationSyntax)context.Node).Identifier, settings);
138+
}
128139

129-
var notationValue = match.Groups["notation"].Value;
130-
if (settings.NamingRules.AllowCommonHungarianPrefixes && CommonPrefixes.Contains(notationValue))
131-
{
132-
continue;
133-
}
140+
public static void HandleFromClause(SyntaxNodeAnalysisContext context, StyleCopSettings settings)
141+
{
142+
CheckIdentifier(context, ((FromClauseSyntax)context.Node).Identifier, settings);
143+
}
134144

135-
if (settings.NamingRules.AllowedHungarianPrefixes.Contains(notationValue))
136-
{
137-
continue;
138-
}
145+
public static void HandleLetClause(SyntaxNodeAnalysisContext context, StyleCopSettings settings)
146+
{
147+
CheckIdentifier(context, ((LetClauseSyntax)context.Node).Identifier, settings);
148+
}
149+
150+
public static void HandleJoinClause(SyntaxNodeAnalysisContext context, StyleCopSettings settings)
151+
{
152+
CheckIdentifier(context, ((JoinClauseSyntax)context.Node).Identifier, settings);
153+
}
154+
155+
public static void HandleJoinIntoClause(SyntaxNodeAnalysisContext context, StyleCopSettings settings)
156+
{
157+
CheckIdentifier(context, ((JoinIntoClauseSyntax)context.Node).Identifier, settings);
158+
}
159+
160+
public static void HandleForEachStatement(SyntaxNodeAnalysisContext context, StyleCopSettings settings)
161+
{
162+
CheckIdentifier(context, ((ForEachStatementSyntax)context.Node).Identifier, settings);
163+
}
139164

140-
// Variable names must begin with lower-case letter
141-
context.ReportDiagnostic(Diagnostic.Create(Descriptor, identifier.GetLocation(), fieldDeclaration ? "field" : "variable", name));
165+
private static void CheckIdentifier(SyntaxNodeAnalysisContext context, SyntaxToken identifier, StyleCopSettings settings, bool fieldDeclaration = false)
166+
{
167+
if (identifier.IsMissing)
168+
{
169+
return;
170+
}
171+
172+
string name = identifier.ValueText;
173+
if (string.IsNullOrEmpty(name))
174+
{
175+
return;
142176
}
177+
178+
var match = HungarianRegex.Match(name);
179+
if (!match.Success)
180+
{
181+
return;
182+
}
183+
184+
var notationValue = match.Groups["notation"].Value;
185+
if (settings.NamingRules.AllowCommonHungarianPrefixes && CommonPrefixes.Contains(notationValue))
186+
{
187+
return;
188+
}
189+
190+
if (settings.NamingRules.AllowedHungarianPrefixes.Contains(notationValue))
191+
{
192+
return;
193+
}
194+
195+
// Variable names must begin with lower-case letter
196+
context.ReportDiagnostic(Diagnostic.Create(Descriptor, identifier.GetLocation(), fieldDeclaration ? "field" : "variable", name));
143197
}
144198
}
145199
}

0 commit comments

Comments
 (0)