Skip to content

Commit ad09cf8

Browse files
authored
Merge pull request #3083 from pantosha/fix-2941
Fix SA1008 on line end
2 parents c930ef3 + f273830 commit ad09cf8

4 files changed

Lines changed: 126 additions & 9 deletions

File tree

StyleCop.Analyzers/StyleCop.Analyzers.CodeFixes/SpacingRules/TokenSpacingCodeFixProvider.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,9 +239,10 @@ private static void UpdateReplaceMap(Dictionary<SyntaxToken, SyntaxToken> replac
239239

240240
case TokenSpacingProperties.ActionRemove:
241241
triviaList = token.TrailingTrivia.AddRange(nextToken.LeadingTrivia);
242+
bool preserveLayout = layout == TokenSpacingProperties.LayoutPreserve;
242243

243244
UpdateReplaceMap(replaceMap, token, t => t.WithTrailingTrivia());
244-
UpdateReplaceMap(replaceMap, nextToken, t => t.WithLeadingTrivia(triviaList.WithoutLeadingWhitespace(true)));
245+
UpdateReplaceMap(replaceMap, nextToken, t => t.WithLeadingTrivia(triviaList.WithoutLeadingWhitespace(endOfLineIsWhitespace: !preserveLayout)));
245246
break;
246247
}
247248

StyleCop.Analyzers/StyleCop.Analyzers.Test/SpacingRules/SA1008UnitTests.cs

Lines changed: 117 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,11 +137,61 @@ public void TestMethod1(
137137
int z)
138138
{
139139
}
140+
141+
public void TestMethod2 (
142+
int x,
143+
int y,
144+
int z)
145+
{
146+
}
147+
148+
// Opening parenthesis followed by space
149+
public void TestMethod3(
150+
int x,
151+
int y,
152+
int z)
153+
{
154+
}
140155
}
141156
}
142157
";
143158

144-
await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
159+
var fixedTestCode = @"namespace TestNamespace
160+
{
161+
public class TestClass
162+
{
163+
public void TestMethod1(
164+
int x,
165+
int y,
166+
int z)
167+
{
168+
}
169+
170+
public void TestMethod2(
171+
int x,
172+
int y,
173+
int z)
174+
{
175+
}
176+
177+
// Opening parenthesis followed by space
178+
public void TestMethod3(
179+
int x,
180+
int y,
181+
int z)
182+
{
183+
}
184+
}
185+
}
186+
";
187+
188+
DiagnosticResult[] expectedDiagnostics =
189+
{
190+
Diagnostic(DescriptorNotPreceded).WithLocation(12, 33),
191+
Diagnostic(DescriptorNotFollowed).WithLocation(20, 32),
192+
};
193+
194+
await VerifyCSharpFixAsync(testCode, expectedDiagnostics, fixedTestCode, CancellationToken.None).ConfigureAwait(false);
145195
}
146196

147197
/// <summary>
@@ -781,6 +831,72 @@ public TestClass()
781831
await VerifyCSharpFixAsync(testCode, expectedDiagnostics, fixedTestCode, CancellationToken.None).ConfigureAwait(false);
782832
}
783833

834+
/// <summary>
835+
/// Verifies that spacing for multiline argument lists is handled properly.
836+
/// </summary>
837+
/// <returns>A <see cref="Task"/> representing the asynchronous unit test.</returns>
838+
[Fact]
839+
public async Task TestMultiLineArgumentListAsync()
840+
{
841+
var testCode = @"using System;
842+
843+
namespace TestNamespace
844+
{
845+
public class TestClass
846+
{
847+
public TestClass(int x, int y)
848+
{
849+
var s1 = new String(
850+
'a',
851+
x);
852+
853+
var s2 = new String (
854+
'a',
855+
y);
856+
857+
// Opening parenthesis followed by space
858+
var s3 = new String(
859+
'a',
860+
x);
861+
}
862+
}
863+
}
864+
";
865+
866+
var fixedTestCode = @"using System;
867+
868+
namespace TestNamespace
869+
{
870+
public class TestClass
871+
{
872+
public TestClass(int x, int y)
873+
{
874+
var s1 = new String(
875+
'a',
876+
x);
877+
878+
var s2 = new String(
879+
'a',
880+
y);
881+
882+
// Opening parenthesis followed by space
883+
var s3 = new String(
884+
'a',
885+
x);
886+
}
887+
}
888+
}
889+
";
890+
891+
DiagnosticResult[] expectedDiagnostics =
892+
{
893+
Diagnostic(DescriptorNotPreceded).WithLocation(13, 33),
894+
Diagnostic(DescriptorNotFollowed).WithLocation(18, 32),
895+
};
896+
897+
await VerifyCSharpFixAsync(testCode, expectedDiagnostics, fixedTestCode, CancellationToken.None).ConfigureAwait(false);
898+
}
899+
784900
/// <summary>
785901
/// Verifies that spacing for while statements is handled properly.
786902
/// </summary>

StyleCop.Analyzers/StyleCop.Analyzers/SpacingRules/SA1008OpeningParenthesisMustBeSpacedCorrectly.cs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -92,12 +92,6 @@ private static void HandleOpenParenToken(SyntaxTreeAnalysisContext context, Synt
9292
return;
9393
}
9494

95-
if (token.IsLastInLine())
96-
{
97-
// ignore open parenthesis when last on line.
98-
return;
99-
}
100-
10195
var prevToken = token.GetPreviousToken();
10296

10397
// Don't check leading spaces when preceded by a keyword that is already handled by SA1000
@@ -268,7 +262,7 @@ private static void HandleOpenParenToken(SyntaxTreeAnalysisContext context, Synt
268262

269263
if (token.IsFollowedByWhitespace())
270264
{
271-
context.ReportDiagnostic(Diagnostic.Create(DescriptorNotFollowed, token.GetLocation(), TokenSpacingProperties.RemoveFollowing));
265+
context.ReportDiagnostic(Diagnostic.Create(DescriptorNotFollowed, token.GetLocation(), TokenSpacingProperties.RemoveFollowingPreserveLayout));
272266
}
273267
}
274268
}

StyleCop.Analyzers/StyleCop.Analyzers/SpacingRules/TokenSpacingProperties.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,5 +61,11 @@ internal static class TokenSpacingProperties
6161
ImmutableDictionary<string, string>.Empty
6262
.SetItem(LocationKey, LocationFollowing)
6363
.SetItem(ActionKey, ActionRemove);
64+
65+
internal static ImmutableDictionary<string, string> RemoveFollowingPreserveLayout { get; } =
66+
ImmutableDictionary<string, string>.Empty
67+
.SetItem(LocationKey, LocationFollowing)
68+
.SetItem(ActionKey, ActionRemove)
69+
.SetItem(LayoutKey, LayoutPreserve);
6470
}
6571
}

0 commit comments

Comments
 (0)