Skip to content

Commit 3d4e192

Browse files
committed
Merge pull request #1783 from bexxx/fix1764
Added checks of ArrowExpressionClausSyntax to ensure correct spacing
2 parents 3ed4b39 + a97f584 commit 3d4e192

2 files changed

Lines changed: 101 additions & 0 deletions

File tree

StyleCop.Analyzers/StyleCop.Analyzers.Test/SpacingRules/SA1003UnitTests.cs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -800,6 +800,59 @@ public void TestMethod()
800800
await this.VerifyCSharpDiagnosticAsync(testCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
801801
}
802802

803+
/// <summary>
804+
/// Verifies that unary plus expression will not trigger any diagnostics.
805+
/// </summary>
806+
/// <returns>A <see cref="Task"/> representing the asynchronous unit test.</returns>
807+
[Fact]
808+
public async Task TestExpressionBodiedMembersAsync()
809+
{
810+
var testCode = @"namespace N1
811+
{
812+
public class C1
813+
{
814+
public int Answer=>42; // Property
815+
public void DoStuff(int a)=>System.Console.WriteLine(a); // method
816+
public static C1 operator +(C1 a, C1 b)=>a; // operator
817+
public static explicit operator C1(int i)=>null; // conversion operator
818+
public int this[int index]=>23; // indexer
819+
}
820+
}
821+
";
822+
var fixedTestCode = @"namespace N1
823+
{
824+
public class C1
825+
{
826+
public int Answer => 42; // Property
827+
public void DoStuff(int a) => System.Console.WriteLine(a); // method
828+
public static C1 operator +(C1 a, C1 b) => a; // operator
829+
public static explicit operator C1(int i) => null; // conversion operator
830+
public int this[int index] => 23; // indexer
831+
}
832+
}
833+
";
834+
DiagnosticResult[] expected =
835+
{
836+
this.CSharpDiagnostic(DescriptorPrecededByWhitespace).WithLocation(5, 26).WithArguments("=>"),
837+
this.CSharpDiagnostic(DescriptorFollowedByWhitespace).WithLocation(5, 26).WithArguments("=>"),
838+
839+
this.CSharpDiagnostic(DescriptorPrecededByWhitespace).WithLocation(6, 35).WithArguments("=>"),
840+
this.CSharpDiagnostic(DescriptorFollowedByWhitespace).WithLocation(6, 35).WithArguments("=>"),
841+
842+
this.CSharpDiagnostic(DescriptorPrecededByWhitespace).WithLocation(7, 48).WithArguments("=>"),
843+
this.CSharpDiagnostic(DescriptorFollowedByWhitespace).WithLocation(7, 48).WithArguments("=>"),
844+
845+
this.CSharpDiagnostic(DescriptorPrecededByWhitespace).WithLocation(8, 50).WithArguments("=>"),
846+
this.CSharpDiagnostic(DescriptorFollowedByWhitespace).WithLocation(8, 50).WithArguments("=>"),
847+
848+
this.CSharpDiagnostic(DescriptorPrecededByWhitespace).WithLocation(9, 35).WithArguments("=>"),
849+
this.CSharpDiagnostic(DescriptorFollowedByWhitespace).WithLocation(9, 35).WithArguments("=>"),
850+
};
851+
852+
await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false);
853+
await this.VerifyCSharpFixAsync(testCode, fixedTestCode).ConfigureAwait(false);
854+
}
855+
803856
/// <inheritdoc/>
804857
protected override IEnumerable<DiagnosticAnalyzer> GetCSharpDiagnosticAnalyzers()
805858
{

StyleCop.Analyzers/StyleCop.Analyzers/SpacingRules/SA1003SymbolsMustBeSpacedCorrectly.cs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,11 @@ internal class SA1003SymbolsMustBeSpacedCorrectly : DiagnosticAnalyzer
133133
private static readonly Action<SyntaxNodeAnalysisContext> CastExpressionAction = HandleCastExpression;
134134
private static readonly Action<SyntaxNodeAnalysisContext> EqualsValueClauseAction = HandleEqualsValueClause;
135135
private static readonly Action<SyntaxNodeAnalysisContext> LambdaExpressionAction = HandleLambdaExpression;
136+
private static readonly Action<SyntaxNodeAnalysisContext> PropertyDeclarationAction = HandlePropertyDeclaration;
137+
private static readonly Action<SyntaxNodeAnalysisContext> MethodDeclarationAction = HandleMethodDeclaration;
138+
private static readonly Action<SyntaxNodeAnalysisContext> OperatorDeclarationAction = HandleOperatorDeclaration;
139+
private static readonly Action<SyntaxNodeAnalysisContext> ConversionOperatorDeclarationAction = HandleConversionOperatorDeclaration;
140+
private static readonly Action<SyntaxNodeAnalysisContext> IndexerDeclarationAction = HandleIndexerDeclaration;
136141

137142
/// <summary>
138143
/// Gets the descriptor for prefix unary expression that may not be followed by a comment.
@@ -210,6 +215,11 @@ private static void HandleCompilationStart(CompilationStartAnalysisContext conte
210215
context.RegisterSyntaxNodeActionHonorExclusions(CastExpressionAction, SyntaxKind.CastExpression);
211216
context.RegisterSyntaxNodeActionHonorExclusions(EqualsValueClauseAction, SyntaxKind.EqualsValueClause);
212217
context.RegisterSyntaxNodeActionHonorExclusions(LambdaExpressionAction, LambdaExpressionKinds);
218+
context.RegisterSyntaxNodeActionHonorExclusions(PropertyDeclarationAction, SyntaxKind.PropertyDeclaration);
219+
context.RegisterSyntaxNodeActionHonorExclusions(IndexerDeclarationAction, SyntaxKind.IndexerDeclaration);
220+
context.RegisterSyntaxNodeActionHonorExclusions(MethodDeclarationAction, SyntaxKind.MethodDeclaration);
221+
context.RegisterSyntaxNodeActionHonorExclusions(OperatorDeclarationAction, SyntaxKind.OperatorDeclaration);
222+
context.RegisterSyntaxNodeActionHonorExclusions(ConversionOperatorDeclarationAction, SyntaxKind.ConversionOperatorDeclaration);
213223
}
214224

215225
private static void HandleConstructorDeclaration(SyntaxNodeAnalysisContext context)
@@ -347,6 +357,44 @@ private static void HandleLambdaExpression(SyntaxNodeAnalysisContext context)
347357
CheckToken(context, lambdaExpression.ArrowToken, true, true, true);
348358
}
349359

360+
private static void HandlePropertyDeclaration(SyntaxNodeAnalysisContext context)
361+
{
362+
var propertyDeclaration = (PropertyDeclarationSyntax)context.Node;
363+
HandleArrowExpressionClause(context, propertyDeclaration.ExpressionBody);
364+
}
365+
366+
private static void HandleIndexerDeclaration(SyntaxNodeAnalysisContext context)
367+
{
368+
var indexerDeclaration = (IndexerDeclarationSyntax)context.Node;
369+
HandleArrowExpressionClause(context, indexerDeclaration.ExpressionBody);
370+
}
371+
372+
private static void HandleMethodDeclaration(SyntaxNodeAnalysisContext context)
373+
{
374+
var methodDeclaration = (MethodDeclarationSyntax)context.Node;
375+
HandleArrowExpressionClause(context, methodDeclaration.ExpressionBody);
376+
}
377+
378+
private static void HandleOperatorDeclaration(SyntaxNodeAnalysisContext context)
379+
{
380+
var operatorDeclaration = (OperatorDeclarationSyntax)context.Node;
381+
HandleArrowExpressionClause(context, operatorDeclaration.ExpressionBody);
382+
}
383+
384+
private static void HandleConversionOperatorDeclaration(SyntaxNodeAnalysisContext context)
385+
{
386+
var conversionOperatorDeclaration = (ConversionOperatorDeclarationSyntax)context.Node;
387+
HandleArrowExpressionClause(context, conversionOperatorDeclaration.ExpressionBody);
388+
}
389+
390+
private static void HandleArrowExpressionClause(SyntaxNodeAnalysisContext context, ArrowExpressionClauseSyntax arrowExpressionClause)
391+
{
392+
if (arrowExpressionClause != null)
393+
{
394+
CheckToken(context, arrowExpressionClause.ArrowToken, true, true, true);
395+
}
396+
}
397+
350398
private static void CheckToken(SyntaxNodeAnalysisContext context, SyntaxToken token, bool withLeadingWhitespace, bool allowAtEndOfLine, bool withTrailingWhitespace, string tokenText = null)
351399
{
352400
tokenText = tokenText ?? token.Text;

0 commit comments

Comments
 (0)