Skip to content

Commit 3829d81

Browse files
committed
Fix #2845: SA1101 is not raised when implementing property with an expression
1 parent c1f17d0 commit 3829d81

3 files changed

Lines changed: 276 additions & 11 deletions

File tree

StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp7/ReadabilityRules/SA1101CSharp7UnitTests.cs

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,5 +33,83 @@ public async Task TestValueTupleAsync()
3333

3434
await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
3535
}
36+
37+
[Fact]
38+
[WorkItem(2845, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/2845")]
39+
public async Task TestPropertyWithExpressionBodiedAccessorAsync()
40+
{
41+
var testCode = @"
42+
public class Foo
43+
{
44+
private int bar;
45+
46+
public int Bar
47+
{
48+
get => bar;
49+
set => bar = value;
50+
}
51+
}
52+
";
53+
54+
var fixedCode = @"
55+
public class Foo
56+
{
57+
private int bar;
58+
59+
public int Bar
60+
{
61+
get => this.bar;
62+
set => this.bar = value;
63+
}
64+
}
65+
";
66+
67+
var expected = new[]
68+
{
69+
Diagnostic().WithLocation(8, 16),
70+
Diagnostic().WithLocation(9, 16),
71+
};
72+
73+
await VerifyCSharpFixAsync(testCode, expected, fixedCode, CancellationToken.None).ConfigureAwait(false);
74+
}
75+
76+
[Fact]
77+
[WorkItem(2845, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/2845")]
78+
public async Task TestIndexerWithExpressionBodiedAccessorAsync()
79+
{
80+
var testCode = @"
81+
public class Foo<T>
82+
{
83+
private T[] arr = new T[100];
84+
85+
public T this[int i]
86+
{
87+
get => arr[i];
88+
set => arr[i] = value;
89+
}
90+
}
91+
";
92+
93+
var fixedCode = @"
94+
public class Foo<T>
95+
{
96+
private T[] arr = new T[100];
97+
98+
public T this[int i]
99+
{
100+
get => this.arr[i];
101+
set => this.arr[i] = value;
102+
}
103+
}
104+
";
105+
106+
var expected = new[]
107+
{
108+
Diagnostic().WithLocation(8, 14),
109+
Diagnostic().WithLocation(9, 14),
110+
};
111+
112+
await VerifyCSharpFixAsync(testCode, expected, fixedCode, CancellationToken.None).ConfigureAwait(false);
113+
}
36114
}
37115
}

StyleCop.Analyzers/StyleCop.Analyzers.Test/ReadabilityRules/SA1101UnitTests.cs

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,194 @@ public class Foo
368368
await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
369369
}
370370

371+
[Fact]
372+
[WorkItem(2845, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/2845")]
373+
public async Task TestExpressionBodiedPropertyAsync()
374+
{
375+
var testCode = @"
376+
public class Foo
377+
{
378+
private readonly int bar = 0;
379+
380+
public int Bar => bar;
381+
}
382+
";
383+
384+
var fixedCode = @"
385+
public class Foo
386+
{
387+
private readonly int bar = 0;
388+
389+
public int Bar => this.bar;
390+
}
391+
";
392+
393+
var expected = new[]
394+
{
395+
Diagnostic().WithLocation(6, 23),
396+
};
397+
398+
await VerifyCSharpFixAsync(testCode, expected, fixedCode, CancellationToken.None).ConfigureAwait(false);
399+
}
400+
401+
[Fact]
402+
[WorkItem(2845, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/2845")]
403+
public async Task TestPropertyWithInitializerAsync()
404+
{
405+
var testCode = @"
406+
public class Foo
407+
{
408+
private static int bar = 0;
409+
410+
public int Bar { get; set; } = bar;
411+
}
412+
";
413+
414+
await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
415+
}
416+
417+
[Fact]
418+
[WorkItem(2845, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/2845")]
419+
public async Task TestIndexerAsync()
420+
{
421+
var testCode = @"
422+
public class Foo<T>
423+
{
424+
private T[] arr = new T[100];
425+
426+
public T this[int i]
427+
{
428+
get { return arr[i]; }
429+
set { arr[i] = value; }
430+
}
431+
}
432+
";
433+
434+
var fixedCode = @"
435+
public class Foo<T>
436+
{
437+
private T[] arr = new T[100];
438+
439+
public T this[int i]
440+
{
441+
get { return this.arr[i]; }
442+
set { this.arr[i] = value; }
443+
}
444+
}
445+
";
446+
447+
var expected = new[]
448+
{
449+
Diagnostic().WithLocation(8, 20),
450+
Diagnostic().WithLocation(9, 13),
451+
};
452+
453+
await VerifyCSharpFixAsync(testCode, expected, fixedCode, CancellationToken.None).ConfigureAwait(false);
454+
}
455+
456+
[Fact]
457+
[WorkItem(2845, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/2845")]
458+
public async Task TestExpressionBodiedIndexerAsync()
459+
{
460+
var testCode = @"
461+
public class Foo<T>
462+
{
463+
private T[] arr = new T[100];
464+
465+
public T this[int i] => arr[i];
466+
}
467+
";
468+
469+
var fixedCode = @"
470+
public class Foo<T>
471+
{
472+
private T[] arr = new T[100];
473+
474+
public T this[int i] => this.arr[i];
475+
}
476+
";
477+
478+
var expected = new[]
479+
{
480+
Diagnostic().WithLocation(6, 28),
481+
};
482+
483+
await VerifyCSharpFixAsync(testCode, expected, fixedCode, CancellationToken.None).ConfigureAwait(false);
484+
}
485+
486+
[Fact]
487+
[WorkItem(2845, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/2845")]
488+
public async Task TestEventAsync()
489+
{
490+
var testCode = @"
491+
using System;
492+
493+
public class Foo<T>
494+
{
495+
private EventHandler bar;
496+
497+
public event EventHandler Bar
498+
{
499+
add { bar += value; }
500+
remove { bar -= value; }
501+
}
502+
}
503+
";
504+
505+
var fixedCode = @"
506+
using System;
507+
508+
public class Foo<T>
509+
{
510+
private EventHandler bar;
511+
512+
public event EventHandler Bar
513+
{
514+
add { this.bar += value; }
515+
remove { this.bar -= value; }
516+
}
517+
}
518+
";
519+
520+
var expected = new[]
521+
{
522+
Diagnostic().WithLocation(10, 15),
523+
Diagnostic().WithLocation(11, 18),
524+
};
525+
526+
await VerifyCSharpFixAsync(testCode, expected, fixedCode, CancellationToken.None).ConfigureAwait(false);
527+
}
528+
529+
[Fact]
530+
[WorkItem(2845, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/2845")]
531+
public async Task TestExpressionBodiedMethodAsync()
532+
{
533+
var testCode = @"
534+
public class Foo
535+
{
536+
private readonly object bar;
537+
538+
public object Bar() => bar;
539+
}
540+
";
541+
542+
var fixedCode = @"
543+
public class Foo
544+
{
545+
private readonly object bar;
546+
547+
public object Bar() => this.bar;
548+
}
549+
";
550+
551+
var expected = new[]
552+
{
553+
Diagnostic().WithLocation(6, 28),
554+
};
555+
556+
await VerifyCSharpFixAsync(testCode, expected, fixedCode, CancellationToken.None).ConfigureAwait(false);
557+
}
558+
371559
[Fact]
372560
[WorkItem(2799, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/2799")]
373561
public async Task TestNameofInConstructorCallAsync()

StyleCop.Analyzers/StyleCop.Analyzers/ReadabilityRules/SA1101PrefixLocalCallsWithThis.cs

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -235,27 +235,26 @@ private static bool HasThis(SyntaxNode node)
235235

236236
case SyntaxKind.FieldDeclaration:
237237
case SyntaxKind.EventFieldDeclaration:
238+
return false;
239+
238240
case SyntaxKind.EventDeclaration:
239-
case SyntaxKind.PropertyDeclaration:
240241
case SyntaxKind.IndexerDeclaration:
241-
return false;
242+
var basePropertySyntax = (BasePropertyDeclarationSyntax)node;
243+
return !basePropertySyntax.Modifiers.Any(SyntaxKind.StaticKeyword);
244+
245+
case SyntaxKind.PropertyDeclaration:
246+
var propertySyntax = (PropertyDeclarationSyntax)node;
247+
return !propertySyntax.Modifiers.Any(SyntaxKind.StaticKeyword)
248+
&& propertySyntax.Initializer == null;
242249

243250
case SyntaxKind.MultiLineDocumentationCommentTrivia:
244251
case SyntaxKind.SingleLineDocumentationCommentTrivia:
245252
return false;
246253

247-
case SyntaxKind.GetAccessorDeclaration:
248-
case SyntaxKind.SetAccessorDeclaration:
249-
case SyntaxKind.AddAccessorDeclaration:
250-
case SyntaxKind.RemoveAccessorDeclaration:
251-
case SyntaxKind.UnknownAccessorDeclaration:
252-
BasePropertyDeclarationSyntax basePropertySyntax = (BasePropertyDeclarationSyntax)node.Parent.Parent;
253-
return !basePropertySyntax.Modifiers.Any(SyntaxKind.StaticKeyword);
254-
255254
case SyntaxKind.ConstructorDeclaration:
256255
case SyntaxKind.DestructorDeclaration:
257256
case SyntaxKind.MethodDeclaration:
258-
BaseMethodDeclarationSyntax baseMethodSyntax = (BaseMethodDeclarationSyntax)node;
257+
var baseMethodSyntax = (BaseMethodDeclarationSyntax)node;
259258
return !baseMethodSyntax.Modifiers.Any(SyntaxKind.StaticKeyword);
260259

261260
case SyntaxKind.Attribute:

0 commit comments

Comments
 (0)