Skip to content

Commit 139e715

Browse files
committed
Merge pull request #1985 from sharwell/backport-fixes
Back-port fixes to stabilization for RC 3
2 parents 7be4a33 + ff402a3 commit 139e715

7 files changed

Lines changed: 154 additions & 13 deletions

File tree

StyleCop.Analyzers/StyleCop.Analyzers.CodeFixes/ReadabilityRules/SA1127CodeFixProvider.cs

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ namespace StyleCop.Analyzers.ReadabilityRules
66
using System.Collections.Generic;
77
using System.Collections.Immutable;
88
using System.Composition;
9+
using System.Linq;
910
using System.Threading;
1011
using System.Threading.Tasks;
1112
using Helpers;
@@ -88,18 +89,11 @@ private static async Task<Document> GetTransformedDocumentAsync(Document documen
8889

8990
private static string GetParentIndentation(SyntaxToken token)
9091
{
91-
var parentLine = token.Parent.Parent;
92-
var parentIndentation = string.Empty;
93-
var parentTrivia = parentLine.GetLeadingTrivia();
94-
foreach (var trivia in parentTrivia)
95-
{
96-
if (trivia.IsKind(SyntaxKind.WhitespaceTrivia))
97-
{
98-
parentIndentation += trivia.ToString();
99-
}
100-
}
92+
var parentTrivia = token.Parent.Parent.GetLeadingTrivia();
10193

102-
return parentIndentation;
94+
return parentTrivia
95+
.LastOrDefault(SyntaxKind.WhitespaceTrivia)
96+
.ToString();
10397
}
10498

10599
// This function will remove any unnecessary whitespace or end-of-line trivia from a token.

StyleCop.Analyzers/StyleCop.Analyzers.CodeFixes/ReadabilityRules/SA1133CodeFixProvider.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,9 @@ private static List<AttributeListSyntax> GetNewAttributeList(AttributeListSyntax
7777

7878
for (var i = 0; i < attributeList.Attributes.Count; i++)
7979
{
80-
var newAttributes = SyntaxFactory.SingletonSeparatedList(attributeList.Attributes[i]);
80+
var newAttributes = SyntaxFactory.SingletonSeparatedList(
81+
attributeList.Attributes[i].WithLeadingTrivia(
82+
attributeList.Attributes[i].GetLeadingTrivia().WithoutLeadingWhitespace()));
8183
var newAttributeList = SyntaxFactory.AttributeList(attributeList.Target, newAttributes);
8284

8385
newAttributeList = (i == 0)

StyleCop.Analyzers/StyleCop.Analyzers.Test/NamingRules/SA1303UnitTests.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,24 @@ public async Task TestFieldWhichIsNotConstStartingWithLowerCaseAsync()
199199
await this.VerifyCSharpDiagnosticAsync(testCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
200200
}
201201

202+
/// <summary>
203+
/// Regression test for https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/1936.
204+
/// </summary>
205+
/// <remarks>SA1303 should not be reported on <c>enum</c> declarations. SA1300 will be reported in this case.</remarks>
206+
/// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
207+
[Fact]
208+
public async Task TestEnumDeclarationsDoNotReportAsync()
209+
{
210+
var testCode = @"
211+
public enum SpecialFile
212+
{
213+
iTunesMetadata
214+
}";
215+
216+
await this.VerifyCSharpDiagnosticAsync(testCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
217+
218+
}
219+
202220
protected override IEnumerable<DiagnosticAnalyzer> GetCSharpDiagnosticAnalyzers()
203221
{
204222
yield return new SA1303ConstFieldNamesMustBeginWithUpperCaseLetter();

StyleCop.Analyzers/StyleCop.Analyzers.Test/ReadabilityRules/SA1127UnitTests.cs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,66 @@ private void Method<T>(
128128
await this.VerifyCSharpFixAsync(testCode, fixedCode, cancellationToken: CancellationToken.None).ConfigureAwait(false);
129129
}
130130

131+
/// <summary>
132+
/// This is a regression test for DotNetAnalyzers/StyleCopAnalyzers#1652:
133+
/// https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/1652
134+
/// </summary>
135+
/// <returns>A <see cref="Task"/> representing the asynchronous unit test.</returns>
136+
[Fact]
137+
public async Task TestViolationWithMethodDeclarationAndXmlCommentsAsync()
138+
{
139+
var testCode = $@"
140+
class Foo
141+
{{
142+
/// <summary>Foo</summary>
143+
/// <typeparam name=""T"">The type.</typeparam>
144+
private void Method<T>() where T : class {{ }}
145+
}}";
146+
var fixedCode = $@"
147+
class Foo
148+
{{
149+
/// <summary>Foo</summary>
150+
/// <typeparam name=""T"">The type.</typeparam>
151+
private void Method<T>()
152+
where T : class
153+
{{ }}
154+
}}";
155+
var expected = this.CSharpDiagnostic().WithLocation(6, 30);
156+
await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false);
157+
await this.VerifyCSharpDiagnosticAsync(fixedCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
158+
await this.VerifyCSharpFixAsync(testCode, fixedCode, cancellationToken: CancellationToken.None).ConfigureAwait(false);
159+
}
160+
161+
/// <summary>
162+
/// This is a regression test for DotNetAnalyzers/StyleCopAnalyzers#1652:
163+
/// https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/1652
164+
/// </summary>
165+
/// <returns>A <see cref="Task"/> representing the asynchronous unit test.</returns>
166+
[Fact]
167+
public async Task TestViolationWithMethodDeclarationRegionDirectiveAsync()
168+
{
169+
var testCode = $@"
170+
class Foo
171+
{{
172+
#region Test
173+
private void Method<T>() where T : class {{ }}
174+
#endregion
175+
}}";
176+
var fixedCode = $@"
177+
class Foo
178+
{{
179+
#region Test
180+
private void Method<T>()
181+
where T : class
182+
{{ }}
183+
#endregion
184+
}}";
185+
var expected = this.CSharpDiagnostic().WithLocation(5, 30);
186+
await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false);
187+
await this.VerifyCSharpDiagnosticAsync(fixedCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
188+
await this.VerifyCSharpFixAsync(testCode, fixedCode, cancellationToken: CancellationToken.None).ConfigureAwait(false);
189+
}
190+
131191
[Fact]
132192
public async Task TestViolationWithExpressionBodiedMethodDeclarationAsync()
133193
{

StyleCop.Analyzers/StyleCop.Analyzers.Test/ReadabilityRules/SA1133UnitTests.cs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,51 @@ public enum ImplicitUseKindFlags { Assign }
421421
await this.VerifyCSharpFixAllFixAsync(testCode, fixedTestCode, maxNumberOfIterations: 1).ConfigureAwait(false);
422422
}
423423

424+
/// <summary>
425+
/// Regression test for issue 1883 (whitespace is preserved incorrectly): https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/1883
426+
/// </summary>
427+
/// <returns>A <see cref="Task"/> representing the asynchronous unit test.</returns>
428+
[Fact]
429+
public async Task TestWhitespaceIsHandledCorrectlyAsync()
430+
{
431+
var testCode = @"
432+
namespace SA1133CodeFix
433+
{
434+
using System.ComponentModel;
435+
using System.Diagnostics.CodeAnalysis;
436+
437+
[DefaultValue(true),
438+
SuppressMessage(null, null)]
439+
internal class Foo
440+
{
441+
}
442+
}
443+
";
444+
445+
var fixedTestCode = @"
446+
namespace SA1133CodeFix
447+
{
448+
using System.ComponentModel;
449+
using System.Diagnostics.CodeAnalysis;
450+
451+
[DefaultValue(true)]
452+
[SuppressMessage(null, null)]
453+
internal class Foo
454+
{
455+
}
456+
}
457+
";
458+
459+
DiagnosticResult[] expected =
460+
{
461+
this.CSharpDiagnostic().WithLocation(8, 5)
462+
};
463+
464+
await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false);
465+
await this.VerifyCSharpDiagnosticAsync(fixedTestCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
466+
await this.VerifyCSharpFixAsync(testCode, fixedTestCode).ConfigureAwait(false);
467+
}
468+
424469
/// <inheritdoc/>
425470
protected override CodeFixProvider GetCSharpCodeFixProvider()
426471
{

StyleCop.Analyzers/StyleCop.Analyzers/LinqHelpers/SyntaxTriviaListEnumerable.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ namespace System.Linq
55
{
66
using Collections.Generic;
77
using Microsoft.CodeAnalysis;
8+
using Microsoft.CodeAnalysis.CSharp;
89

910
/// <summary>
1011
/// This class supports a subset of LINQ operations on <see cref="SyntaxTriviaList"/> without requiring boxing of
@@ -93,5 +94,26 @@ internal static bool All(this SyntaxTriviaList list, Func<SyntaxTrivia, bool> pr
9394

9495
return true;
9596
}
97+
98+
/// <summary>
99+
/// Returns the last trivia of a specified kind in a trivia list.
100+
/// </summary>
101+
/// <param name="list">The trivia list.</param>
102+
/// <param name="kind">The syntax kind.</param>
103+
/// <returns>The last <see cref="SyntaxTrivia"/> in <paramref name="list"/> with the specified
104+
/// <paramref name="kind"/>; otherwise, a default <see cref="SyntaxTrivia"/> instance if no matching trivia was
105+
/// found.</returns>
106+
internal static SyntaxTrivia LastOrDefault(this SyntaxTriviaList list, SyntaxKind kind)
107+
{
108+
foreach (var trivia in list.Reverse())
109+
{
110+
if (trivia.IsKind(kind))
111+
{
112+
return trivia;
113+
}
114+
}
115+
116+
return default(SyntaxTrivia);
117+
}
96118
}
97119
}

StyleCop.Analyzers/StyleCop.Analyzers/NamingRules/SA1303ConstFieldNamesMustBeginWithUpperCaseLetter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ public void HandleFieldDeclaration(SymbolAnalysisContext context)
7171
{
7272
var symbol = context.Symbol as IFieldSymbol;
7373

74-
if (symbol == null || !symbol.IsConst)
74+
if (symbol == null || !symbol.IsConst || symbol.ContainingType?.TypeKind == TypeKind.Enum)
7575
{
7676
return;
7777
}

0 commit comments

Comments
 (0)