Skip to content

Commit 029ba95

Browse files
committed
Added enum member, operator, and conversion operator declaration checks (and tests)
1 parent 67f2527 commit 029ba95

2 files changed

Lines changed: 151 additions & 19 deletions

File tree

StyleCop.Analyzers/StyleCop.Analyzers.Test/LayoutRules/SA1506UnitTests.cs

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -617,6 +617,135 @@ public void TestMethod3() { }
617617
await this.VerifyCSharpFixAsync(testCode, fixedCode).ConfigureAwait(false);
618618
}
619619

620+
/// <summary>
621+
/// Verifies that enum member declarations with invalid documentation will produce the expected diagnostics.
622+
/// </summary>
623+
/// <returns>A <see cref="Task"/> representing the asynchronous unit test.</returns>
624+
[Fact]
625+
public async Task TestInvalidEnumMemberDeclarationsAsync()
626+
{
627+
var testCode = @"namespace TestNamespace
628+
{
629+
public enum TestEnum
630+
{
631+
/// <summary>
632+
/// This is an enum member.
633+
/// </summary>
634+
635+
Foo = 0
636+
}
637+
}
638+
";
639+
640+
var fixedTestCode = @"namespace TestNamespace
641+
{
642+
public enum TestEnum
643+
{
644+
/// <summary>
645+
/// This is an enum member.
646+
/// </summary>
647+
Foo = 0
648+
}
649+
}
650+
";
651+
652+
var expectedDiagnostic = this.CSharpDiagnostic().WithLocation(8, 1);
653+
654+
await this.VerifyCSharpDiagnosticAsync(testCode, expectedDiagnostic, CancellationToken.None).ConfigureAwait(false);
655+
await this.VerifyCSharpDiagnosticAsync(fixedTestCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
656+
await this.VerifyCSharpFixAsync(testCode, fixedTestCode).ConfigureAwait(false);
657+
}
658+
659+
/// <summary>
660+
/// Verifies that operator declarations with invalid documentation will produce the expected diagnostics.
661+
/// </summary>
662+
/// <returns>A <see cref="Task"/> representing the asynchronous unit test.</returns>
663+
[Fact]
664+
public async Task TestInvalidOperatorDeclarationsAsync()
665+
{
666+
var testCode = @"namespace TestNamespace
667+
{
668+
public struct Foo
669+
{
670+
/// <summary>
671+
/// This is an operator declaration.
672+
/// </summary>
673+
674+
public static Foo operator +(Foo x, Foo y)
675+
{
676+
return new Foo();
677+
}
678+
}
679+
}
680+
";
681+
682+
var fixedTestCode = @"namespace TestNamespace
683+
{
684+
public struct Foo
685+
{
686+
/// <summary>
687+
/// This is an operator declaration.
688+
/// </summary>
689+
public static Foo operator +(Foo x, Foo y)
690+
{
691+
return new Foo();
692+
}
693+
}
694+
}
695+
";
696+
697+
var expectedDiagnostic = this.CSharpDiagnostic().WithLocation(8, 1);
698+
699+
await this.VerifyCSharpDiagnosticAsync(testCode, expectedDiagnostic, CancellationToken.None).ConfigureAwait(false);
700+
await this.VerifyCSharpDiagnosticAsync(fixedTestCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
701+
await this.VerifyCSharpFixAsync(testCode, fixedTestCode).ConfigureAwait(false);
702+
}
703+
704+
/// <summary>
705+
/// Verifies that conversion operator declarations with invalid documentation will produce the expected diagnostics.
706+
/// </summary>
707+
/// <returns>A <see cref="Task"/> representing the asynchronous unit test.</returns>
708+
[Fact]
709+
public async Task TestInvalidConversionOperatorDeclarationsAsync()
710+
{
711+
var testCode = @"namespace TestNamespace
712+
{
713+
public struct Foo
714+
{
715+
/// <summary>
716+
/// This is a conversion operator declaration.
717+
/// </summary>
718+
719+
public static explicit operator Foo(string s)
720+
{
721+
return new Foo();
722+
}
723+
}
724+
}
725+
";
726+
727+
var fixedTestCode = @"namespace TestNamespace
728+
{
729+
public struct Foo
730+
{
731+
/// <summary>
732+
/// This is a conversion operator declaration.
733+
/// </summary>
734+
public static explicit operator Foo(string s)
735+
{
736+
return new Foo();
737+
}
738+
}
739+
}
740+
";
741+
742+
var expectedDiagnostic = this.CSharpDiagnostic().WithLocation(8, 1);
743+
744+
await this.VerifyCSharpDiagnosticAsync(testCode, expectedDiagnostic, CancellationToken.None).ConfigureAwait(false);
745+
await this.VerifyCSharpDiagnosticAsync(fixedTestCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
746+
await this.VerifyCSharpFixAsync(testCode, fixedTestCode).ConfigureAwait(false);
747+
}
748+
620749
protected override IEnumerable<DiagnosticAnalyzer> GetCSharpDiagnosticAnalyzers()
621750
{
622751
yield return new SA1506ElementDocumentationHeadersMustNotBeFollowedByBlankLine();

StyleCop.Analyzers/StyleCop.Analyzers/LayoutRules/SA1506ElementDocumentationHeadersMustNotBeFollowedByBlankLine.cs

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ internal class SA1506ElementDocumentationHeadersMustNotBeFollowedByBlankLine : D
5656
SyntaxKind.StructDeclaration,
5757
SyntaxKind.InterfaceDeclaration,
5858
SyntaxKind.EnumDeclaration,
59+
SyntaxKind.EnumMemberDeclaration,
5960
SyntaxKind.MethodDeclaration,
6061
SyntaxKind.ConstructorDeclaration,
6162
SyntaxKind.DestructorDeclaration,
@@ -64,7 +65,9 @@ internal class SA1506ElementDocumentationHeadersMustNotBeFollowedByBlankLine : D
6465
SyntaxKind.FieldDeclaration,
6566
SyntaxKind.DelegateDeclaration,
6667
SyntaxKind.EventDeclaration,
67-
SyntaxKind.EventFieldDeclaration);
68+
SyntaxKind.EventFieldDeclaration,
69+
SyntaxKind.OperatorDeclaration,
70+
SyntaxKind.ConversionOperatorDeclaration);
6871

6972
private static readonly Action<CompilationStartAnalysisContext> CompilationStartAction = HandleCompilationStart;
7073
private static readonly Action<SyntaxNodeAnalysisContext> DeclarationAction = HandleDeclaration;
@@ -93,25 +96,25 @@ private static void HandleDeclaration(SyntaxNodeAnalysisContext context)
9396
{
9497
switch (triviaList[i].Kind())
9598
{
96-
case SyntaxKind.WhitespaceTrivia:
97-
break;
98-
case SyntaxKind.EndOfLineTrivia:
99-
eolCount++;
100-
break;
101-
case SyntaxKind.SingleLineCommentTrivia:
102-
case SyntaxKind.MultiLineCommentTrivia:
103-
eolCount--;
104-
break;
105-
case SyntaxKind.SingleLineDocumentationCommentTrivia:
106-
if (eolCount > 0)
107-
{
108-
context.ReportDiagnostic(Diagnostic.Create(Descriptor, triviaList[i + 1].GetLocation()));
109-
}
99+
case SyntaxKind.WhitespaceTrivia:
100+
break;
101+
case SyntaxKind.EndOfLineTrivia:
102+
eolCount++;
103+
break;
104+
case SyntaxKind.SingleLineCommentTrivia:
105+
case SyntaxKind.MultiLineCommentTrivia:
106+
eolCount--;
107+
break;
108+
case SyntaxKind.SingleLineDocumentationCommentTrivia:
109+
if (eolCount > 0)
110+
{
111+
context.ReportDiagnostic(Diagnostic.Create(Descriptor, triviaList[i + 1].GetLocation()));
112+
}
110113

111-
return;
112-
default:
113-
// no documentation found
114-
return;
114+
return;
115+
default:
116+
// no documentation found
117+
return;
115118
}
116119
}
117120
}

0 commit comments

Comments
 (0)