From 677a111b6282316c4de234c65c8bb20c67516b28 Mon Sep 17 00:00:00 2001 From: John Venable Date: Wed, 5 Aug 2015 22:59:39 -0400 Subject: [PATCH 1/3] update ordering diagnostics to proper StyleCop order --- .../OrderingRules/SA1202UnitTests.cs | 120 +++++++++++------- .../OrderingRules/SA1203UnitTests.cs | 67 +++++++++- .../OrderingRules/SA1204UnitTests.cs | 64 +++++++++- .../OrderingRules/SA1214UnitTests.cs | 83 +++++++++++- .../OrderingRules/SA1215UnitTests.cs | 59 ++++++++- .../OrderingRules/AccessLevel.cs | 26 ++++ .../OrderingRules/AccessLevelHelper.cs | 63 +++++++++ .../SA1202ElementsMustBeOrderedByAccess.cs | 94 +------------- .../SA1203ConstantsMustAppearBeforeFields.cs | 21 +-- ...lementsMustAppearBeforeInstanceElements.cs | 4 + ...stAppearBeforeStaticNonReadonlyElements.cs | 50 +++----- ...AppearBeforeInstanceNonReadonlyElements.cs | 10 +- .../StyleCop.Analyzers.csproj | 2 + 13 files changed, 461 insertions(+), 202 deletions(-) create mode 100644 StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/AccessLevel.cs create mode 100644 StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/AccessLevelHelper.cs diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1202UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1202UnitTests.cs index 24e736828..58fad8ff2 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1202UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1202UnitTests.cs @@ -23,13 +23,31 @@ public async Task TestValidOrderAsync() { var testCode = @"public class TestClass { - private const int TestField1 = 1; - protected static readonly int TestField2 = 2; - protected internal static int TestField3; - internal readonly int TestField4; - public int TestField5; - - public string TestString; + public const int TestField1 = 1; + public static readonly int TestField2 = 1; + public static int TestField3 = 1; + public readonly int TestField4 = 1; + public int TestField5 = 1; + internal const int TestField6 = 1; + internal static readonly int TestField7 = 1; + internal static int TestField8 = 1; + internal readonly int TestField9 = 1; + internal int TestField10 = 1; + protected internal const int TestField11 = 1; + protected internal static readonly int TestField12 = 1; + protected internal static int TestField13 = 1; + protected internal readonly int TestField14 = 1; + protected internal int TestField15 = 1; + protected const int TestField16 = 1; + protected static readonly int TestField17 = 1; + protected static int TestField18 = 1; + protected readonly int TestField19 = 1; + protected int TestField20 = 1; + private const int TestField21 = 1; + private static readonly int TestField22 = 1; + private static int TestField23 = 1; + private readonly int TestField24 = 1; + private int TestField25 = 1; public TestClass() { @@ -41,23 +59,27 @@ private TestClass(string a) ~TestClass() { } - public string TestProperty1 { get; set; } - - internal string TestProperty2 { get; set; } - - protected internal string TestProperty3 { get; set; } - - protected string TestProperty4 { get; set; } - - private string TestProperty5 { get; set; } - - public void TestMethod1() - { - } + public static int TestProperty1 { get; set; } + public int TestProperty2 { get; set; } + internal static int TestProperty3 { get; set; } + internal int TestProperty4 { get; set; } + protected internal static int TestProperty5 { get; set; } + protected internal int TestProperty6 { get; set; } + protected static int TestProperty7 { get; set; } + protected int TestProperty8 { get; set; } + private static int TestProperty9 { get; set; } + private int TestProperty10 { get; set; } - private void TestMethod2() - { - } + public static void TestMethod1() { } + public void TestMethod2() { } + internal static void TestMethod3() { } + internal void TestMethod4() { } + protected internal static void TestMethod5() { } + protected internal void TestMethod6() { } + protected static void TestMethod7() { } + protected void TestMethod8() { } + private static void TestMethod9() { } + private void TestMethod10() { } } "; @@ -75,7 +97,7 @@ public async Task TestClassOrderingAsync() public class TestClass2 { } "; - var expected = this.CSharpDiagnostic().WithLocation(2, 14).WithArguments("Public", string.Empty, "classes", "internal"); + var expected = this.CSharpDiagnostic().WithLocation(2, 14).WithArguments("Public", "classes", "internal"); await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false); } @@ -113,10 +135,10 @@ public async Task TestPropertiesAsync() DiagnosticResult[] expected = { - this.CSharpDiagnostic().WithLocation(4, 22).WithArguments("Protected", string.Empty, "properties", "private"), - this.CSharpDiagnostic().WithLocation(5, 31).WithArguments("Protected internal", string.Empty, "properties", "protected"), - this.CSharpDiagnostic().WithLocation(6, 21).WithArguments("Internal", string.Empty, "properties", "protected internal"), - this.CSharpDiagnostic().WithLocation(7, 19).WithArguments("Public", string.Empty, "properties", "internal") + this.CSharpDiagnostic().WithLocation(4, 22).WithArguments("Protected", "properties", "private"), + this.CSharpDiagnostic().WithLocation(5, 31).WithArguments("Protected internal", "properties", "protected"), + this.CSharpDiagnostic().WithLocation(6, 21).WithArguments("Internal", "properties", "protected internal"), + this.CSharpDiagnostic().WithLocation(7, 19).WithArguments("Public", "properties", "internal") }; await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false); @@ -141,10 +163,10 @@ public void TestMethod5() { } DiagnosticResult[] expected = { - this.CSharpDiagnostic().WithLocation(4, 20).WithArguments("Protected", string.Empty, "methods", "private"), - this.CSharpDiagnostic().WithLocation(5, 29).WithArguments("Protected internal", string.Empty, "methods", "protected"), - this.CSharpDiagnostic().WithLocation(6, 19).WithArguments("Internal", string.Empty, "methods", "protected internal"), - this.CSharpDiagnostic().WithLocation(7, 17).WithArguments("Public", string.Empty, "methods", "internal") + this.CSharpDiagnostic().WithLocation(4, 20).WithArguments("Protected", "methods", "private"), + this.CSharpDiagnostic().WithLocation(5, 29).WithArguments("Protected internal", "methods", "protected"), + this.CSharpDiagnostic().WithLocation(6, 19).WithArguments("Internal", "methods", "protected internal"), + this.CSharpDiagnostic().WithLocation(7, 17).WithArguments("Public", "methods", "internal") }; await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false); @@ -164,7 +186,7 @@ public async Task TestProtectedInternalBeforePublicAsync() } "; - var expected = this.CSharpDiagnostic().WithLocation(4, 5).WithArguments("Public", string.Empty, "events", "protected internal"); + var expected = this.CSharpDiagnostic().WithLocation(4, 5).WithArguments("Public", "events", "protected internal"); await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false); } @@ -183,7 +205,7 @@ public async Task TestProtectedBeforePublicAsync() } "; - var expected = this.CSharpDiagnostic().WithLocation(4, 19).WithArguments("Public", string.Empty, "fields", "protected"); + var expected = this.CSharpDiagnostic().WithLocation(4, 19).WithArguments("Public", "fields", "protected"); await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false); } @@ -202,7 +224,7 @@ public event System.Action TestEvent2 { add { } remove { } } } "; - var expected = this.CSharpDiagnostic().WithLocation(4, 32).WithArguments("Public", string.Empty, "events", "private"); + var expected = this.CSharpDiagnostic().WithLocation(4, 32).WithArguments("Public", "events", "private"); await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false); } @@ -221,7 +243,7 @@ internal event System.Action TestEvent2 { add { } remove { } } } "; - var expected = this.CSharpDiagnostic().WithLocation(4, 34).WithArguments("Internal", string.Empty, "events", "protected"); + var expected = this.CSharpDiagnostic().WithLocation(4, 34).WithArguments("Internal", "events", "protected"); await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false); } @@ -240,7 +262,7 @@ public async Task TestPrivateBeforeInternalAsync() } "; - var expected = this.CSharpDiagnostic().WithLocation(4, 28).WithArguments("Internal", string.Empty, "delegates", "private"); + var expected = this.CSharpDiagnostic().WithLocation(4, 28).WithArguments("Internal", "delegates", "private"); await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false); } @@ -259,7 +281,7 @@ protected internal void TestMethod2() { } } "; - var expected = this.CSharpDiagnostic().WithLocation(4, 29).WithArguments("Protected internal", string.Empty, "methods", "private"); + var expected = this.CSharpDiagnostic().WithLocation(4, 29).WithArguments("Protected internal", "methods", "private"); await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false); } @@ -278,7 +300,7 @@ internal protected void TestMethod2() { } } "; - var expected = this.CSharpDiagnostic().WithLocation(4, 29).WithArguments("Protected internal", string.Empty, "methods", "private"); + var expected = this.CSharpDiagnostic().WithLocation(4, 29).WithArguments("Protected internal", "methods", "private"); await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false); } @@ -316,7 +338,7 @@ public async Task TestOnlyFirstViolationReportedAsync() } "; - var expected = this.CSharpDiagnostic().WithLocation(4, 19).WithArguments("Public", string.Empty, "fields", "private"); + var expected = this.CSharpDiagnostic().WithLocation(4, 19).WithArguments("Public", "fields", "private"); await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false); } @@ -340,7 +362,9 @@ public void B() } "; - await this.VerifyCSharpDiagnosticAsync(testCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false); + var expected = this.CSharpDiagnostic().WithLocation(7, 17).WithArguments("Public", "methods", "private"); + + await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false); } /// @@ -362,10 +386,10 @@ public static void TestMethod5() { } DiagnosticResult[] expected = { - this.CSharpDiagnostic().WithLocation(4, 27).WithArguments("Protected", " static", "methods", "private"), - this.CSharpDiagnostic().WithLocation(5, 36).WithArguments("Protected internal", " static", "methods", "protected"), - this.CSharpDiagnostic().WithLocation(6, 26).WithArguments("Internal", " static", "methods", "protected internal"), - this.CSharpDiagnostic().WithLocation(7, 24).WithArguments("Public", " static", "methods", "internal") + this.CSharpDiagnostic().WithLocation(4, 27).WithArguments("Protected", "methods", "private"), + this.CSharpDiagnostic().WithLocation(5, 36).WithArguments("Protected internal", "methods", "protected"), + this.CSharpDiagnostic().WithLocation(6, 26).WithArguments("Internal", "methods", "protected internal"), + this.CSharpDiagnostic().WithLocation(7, 24).WithArguments("Public", "methods", "internal") }; await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false); @@ -386,7 +410,11 @@ public async Task TestConstOrderingAsync() } "; - var expected = this.CSharpDiagnostic().WithLocation(4, 25).WithArguments("Protected", " const", "fields", "private"); + DiagnosticResult[] expected = + { + this.CSharpDiagnostic().WithLocation(4, 25).WithArguments("Protected", "fields", "private"), + this.CSharpDiagnostic().WithLocation(5, 16).WithArguments("Public", "fields", "protected") + }; await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false); } diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1203UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1203UnitTests.cs index 5b0c11851..3f6da3861 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1203UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1203UnitTests.cs @@ -13,12 +13,69 @@ public class SA1203UnitTests : DiagnosticVerifier [Fact] public async Task TestNoDiagnosticAsync() { - var testCode = @" -public class Foo + var testCode = @"public static class TestClass1 { } + +public class TestClass2 { - private const int Bar = 2; - private int Baz = 1; -}"; + public const int TestField1 = 1; + public static readonly int TestField2 = 1; + public static int TestField3 = 1; + public readonly int TestField4 = 1; + public int TestField5 = 1; + internal const int TestField6 = 1; + internal static readonly int TestField7 = 1; + internal static int TestField8 = 1; + internal readonly int TestField9 = 1; + internal int TestField10 = 1; + protected internal const int TestField11 = 1; + protected internal static readonly int TestField12 = 1; + protected internal static int TestField13 = 1; + protected internal readonly int TestField14 = 1; + protected internal int TestField15 = 1; + protected const int TestField16 = 1; + protected static readonly int TestField17 = 1; + protected static int TestField18 = 1; + protected readonly int TestField19 = 1; + protected int TestField20 = 1; + private const int TestField21 = 1; + private static readonly int TestField22 = 1; + private static int TestField23 = 1; + private readonly int TestField24 = 1; + private int TestField25 = 1; + + public TestClass2() + { + } + + private TestClass2(string a) + { + } + + ~TestClass2() { } + + public static int TestProperty1 { get; set; } + public int TestProperty2 { get; set; } + internal static int TestProperty3 { get; set; } + internal int TestProperty4 { get; set; } + protected internal static int TestProperty5 { get; set; } + protected internal int TestProperty6 { get; set; } + protected static int TestProperty7 { get; set; } + protected int TestProperty8 { get; set; } + private static int TestProperty9 { get; set; } + private int TestProperty10 { get; set; } + + public static void TestMethod1() { } + public void TestMethod2() { } + internal static void TestMethod3() { } + internal void TestMethod4() { } + protected internal static void TestMethod5() { } + protected internal void TestMethod6() { } + protected static void TestMethod7() { } + protected void TestMethod8() { } + private static void TestMethod9() { } + private void TestMethod10() { } +} +"; await this.VerifyCSharpDiagnosticAsync(testCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false); } diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1204UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1204UnitTests.cs index 46ed770e0..275a42c43 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1204UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1204UnitTests.cs @@ -22,16 +22,66 @@ public class SA1204UnitTests : DiagnosticVerifier public async Task TestValidOrderingAsync() { var testCode = @"public static class TestClass1 { } -public class TestClass2 { + +public class TestClass2 +{ public const int TestField1 = 1; - public static readonly int TestField2 = 2; - public static int TestField3; - public readonly int TestField4; - public int TestField5; + public static readonly int TestField2 = 1; + public static int TestField3 = 1; + public readonly int TestField4 = 1; + public int TestField5 = 1; + internal const int TestField6 = 1; + internal static readonly int TestField7 = 1; + internal static int TestField8 = 1; + internal readonly int TestField9 = 1; + internal int TestField10 = 1; + protected internal const int TestField11 = 1; + protected internal static readonly int TestField12 = 1; + protected internal static int TestField13 = 1; + protected internal readonly int TestField14 = 1; + protected internal int TestField15 = 1; + protected const int TestField16 = 1; + protected static readonly int TestField17 = 1; + protected static int TestField18 = 1; + protected readonly int TestField19 = 1; + protected int TestField20 = 1; + private const int TestField21 = 1; + private static readonly int TestField22 = 1; + private static int TestField23 = 1; + private readonly int TestField24 = 1; + private int TestField25 = 1; + + public TestClass2() + { + } + + private TestClass2(string a) + { + } + + ~TestClass2() { } + public static int TestProperty1 { get; set; } public int TestProperty2 { get; set; } + internal static int TestProperty3 { get; set; } + internal int TestProperty4 { get; set; } + protected internal static int TestProperty5 { get; set; } + protected internal int TestProperty6 { get; set; } + protected static int TestProperty7 { get; set; } + protected int TestProperty8 { get; set; } + private static int TestProperty9 { get; set; } + private int TestProperty10 { get; set; } + public static void TestMethod1() { } public void TestMethod2() { } + internal static void TestMethod3() { } + internal void TestMethod4() { } + protected internal static void TestMethod5() { } + protected internal void TestMethod6() { } + protected static void TestMethod7() { } + protected void TestMethod8() { } + private static void TestMethod9() { } + private void TestMethod10() { } } "; @@ -124,9 +174,9 @@ public async Task TestEventOrderingAsync() { var testCode = @"public class TestClass { - event System.Action TestEvent; + public event System.Action TestEvent; public event System.Action TestEvent2 { add { } remove { } } - static event System.Action TestEvent3; + public static event System.Action TestEvent3; public static event System.Action TestEvent4 { add { } remove { } } } "; diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1214UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1214UnitTests.cs index b597ea328..d3b44d7f1 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1214UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1214UnitTests.cs @@ -10,6 +10,76 @@ public class SA1214UnitTests : CodeFixVerifier { + [Fact] + public async Task TestValidOrderingAsync() + { + var testCode = @"public static class TestClass1 { } + +public class TestClass2 +{ + public const int TestField1 = 1; + public static readonly int TestField2 = 1; + public static int TestField3 = 1; + public readonly int TestField4 = 1; + public int TestField5 = 1; + internal const int TestField6 = 1; + internal static readonly int TestField7 = 1; + internal static int TestField8 = 1; + internal readonly int TestField9 = 1; + internal int TestField10 = 1; + protected internal const int TestField11 = 1; + protected internal static readonly int TestField12 = 1; + protected internal static int TestField13 = 1; + protected internal readonly int TestField14 = 1; + protected internal int TestField15 = 1; + protected const int TestField16 = 1; + protected static readonly int TestField17 = 1; + protected static int TestField18 = 1; + protected readonly int TestField19 = 1; + protected int TestField20 = 1; + private const int TestField21 = 1; + private static readonly int TestField22 = 1; + private static int TestField23 = 1; + private readonly int TestField24 = 1; + private int TestField25 = 1; + + public TestClass2() + { + } + + private TestClass2(string a) + { + } + + ~TestClass2() { } + + public static int TestProperty1 { get; set; } + public int TestProperty2 { get; set; } + internal static int TestProperty3 { get; set; } + internal int TestProperty4 { get; set; } + protected internal static int TestProperty5 { get; set; } + protected internal int TestProperty6 { get; set; } + protected static int TestProperty7 { get; set; } + protected int TestProperty8 { get; set; } + private static int TestProperty9 { get; set; } + private int TestProperty10 { get; set; } + + public static void TestMethod1() { } + public void TestMethod2() { } + internal static void TestMethod3() { } + internal void TestMethod4() { } + protected internal static void TestMethod5() { } + protected internal void TestMethod6() { } + protected static void TestMethod7() { } + protected void TestMethod8() { } + private static void TestMethod9() { } + private void TestMethod10() { } +} +"; + + await this.VerifyCSharpDiagnosticAsync(testCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false); + } + [Fact] public async Task TestTwoFieldsInClassStaticReadonlyFieldPlacedAfterStaticNonReadonlyAsync() { @@ -22,7 +92,7 @@ public class Foo var expected = new[] { - this.CSharpDiagnostic().WithLocation(5, 5) + this.CSharpDiagnostic().WithLocation(5, 33) }; await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false); @@ -52,7 +122,7 @@ public class Foo var expected = new[] { - this.CSharpDiagnostic().WithLocation(4, 30) + this.CSharpDiagnostic().WithLocation(4, 58) }; await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false); @@ -96,7 +166,7 @@ public struct Foo var expected = new[] { - this.CSharpDiagnostic().WithLocation(5, 5) + this.CSharpDiagnostic().WithLocation(5, 33) }; await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false); @@ -130,9 +200,10 @@ public class FooInner var expected = new[] { - this.CSharpDiagnostic().WithLocation(11, 5), - this.CSharpDiagnostic().WithLocation(18, 9), - this.CSharpDiagnostic().WithLocation(21, 5), + this.CSharpDiagnostic().WithLocation(11, 33), + this.CSharpDiagnostic().WithLocation(18, 37) + + // line 21 should be reported by SA1201 }; await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false); diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1215UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1215UnitTests.cs index b6d3f6ef6..3b44c7876 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1215UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1215UnitTests.cs @@ -22,8 +22,63 @@ public async Task TestValidOrderingAsync() { var testCode = @"public class TestClass { - public readonly int TestField1 = 1; - public int TestField2; + public const int TestField1 = 1; + public static readonly int TestField2 = 1; + public static int TestField3 = 1; + public readonly int TestField4 = 1; + public int TestField5 = 1; + internal const int TestField6 = 1; + internal static readonly int TestField7 = 1; + internal static int TestField8 = 1; + internal readonly int TestField9 = 1; + internal int TestField10 = 1; + protected internal const int TestField11 = 1; + protected internal static readonly int TestField12 = 1; + protected internal static int TestField13 = 1; + protected internal readonly int TestField14 = 1; + protected internal int TestField15 = 1; + protected const int TestField16 = 1; + protected static readonly int TestField17 = 1; + protected static int TestField18 = 1; + protected readonly int TestField19 = 1; + protected int TestField20 = 1; + private const int TestField21 = 1; + private static readonly int TestField22 = 1; + private static int TestField23 = 1; + private readonly int TestField24 = 1; + private int TestField25 = 1; + + public TestClass() + { + } + + private TestClass(string a) + { + } + + ~TestClass() { } + + public static int TestProperty1 { get; set; } + public int TestProperty2 { get; set; } + internal static int TestProperty3 { get; set; } + internal int TestProperty4 { get; set; } + protected internal static int TestProperty5 { get; set; } + protected internal int TestProperty6 { get; set; } + protected static int TestProperty7 { get; set; } + protected int TestProperty8 { get; set; } + private static int TestProperty9 { get; set; } + private int TestProperty10 { get; set; } + + public static void TestMethod1() { } + public void TestMethod2() { } + internal static void TestMethod3() { } + internal void TestMethod4() { } + protected internal static void TestMethod5() { } + protected internal void TestMethod6() { } + protected static void TestMethod7() { } + protected void TestMethod8() { } + private static void TestMethod9() { } + private void TestMethod10() { } } "; diff --git a/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/AccessLevel.cs b/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/AccessLevel.cs new file mode 100644 index 000000000..9b28f3d60 --- /dev/null +++ b/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/AccessLevel.cs @@ -0,0 +1,26 @@ +namespace StyleCop.Analyzers.OrderingRules +{ + /// + /// Describes an element's access level + /// + internal enum AccessLevel + { + /// No access level specified. + NotSpecified, + + /// Public access. + Public, + + /// Internal access. + Internal, + + /// Protected internal access. + ProtectedInternal, + + /// Protected access. + Protected, + + /// Private access. + Private + } +} diff --git a/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/AccessLevelHelper.cs b/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/AccessLevelHelper.cs new file mode 100644 index 000000000..264653276 --- /dev/null +++ b/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/AccessLevelHelper.cs @@ -0,0 +1,63 @@ +namespace StyleCop.Analyzers.OrderingRules +{ + using Microsoft.CodeAnalysis; + using Microsoft.CodeAnalysis.CSharp; + + /// + /// Contains helper methods for determining an element's access level. + /// + internal static class AccessLevelHelper + { + /// Determines the access level for the given . + /// The modifiers. + /// A value representing the access level. + internal static AccessLevel GetAccessLevel(SyntaxTokenList modifiers) + { + bool isProtected = false; + bool isInternal = false; + foreach (var modifier in modifiers) + { + switch (modifier.Kind()) + { + case SyntaxKind.PublicKeyword: + return AccessLevel.Public; + case SyntaxKind.PrivateKeyword: + return AccessLevel.Private; + case SyntaxKind.InternalKeyword: + if (isProtected) + { + return AccessLevel.ProtectedInternal; + } + else + { + isInternal = true; + } + + break; + case SyntaxKind.ProtectedKeyword: + if (isInternal) + { + return AccessLevel.ProtectedInternal; + } + else + { + isProtected = true; + } + + break; + } + } + + if (isProtected) + { + return AccessLevel.Protected; + } + else if (isInternal) + { + return AccessLevel.Internal; + } + + return AccessLevel.NotSpecified; + } + } +} diff --git a/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1202ElementsMustBeOrderedByAccess.cs b/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1202ElementsMustBeOrderedByAccess.cs index 2a652df75..2474af09d 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1202ElementsMustBeOrderedByAccess.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1202ElementsMustBeOrderedByAccess.cs @@ -40,7 +40,7 @@ public class SA1202ElementsMustBeOrderedByAccess : DiagnosticAnalyzer /// public const string DiagnosticId = "SA1202"; private const string Title = "Elements must be ordered by access"; - private const string MessageFormat = "{0}{1} {2} must come before {3}."; + private const string MessageFormat = "{0} {1} must come before {2}."; private const string Description = "An element within a C# code file is out of order within regard to access level, in relation to other elements in the code."; private const string HelpLink = "http://www.stylecop.com/docs/SA1202.html"; @@ -85,27 +85,6 @@ public class SA1202ElementsMustBeOrderedByAccess : DiagnosticAnalyzer [SyntaxKind.OperatorDeclaration] = "operators" }; - private enum AccessLevel - { - /// No access level specified. - NotSpecified, - - /// Public access. - Public, - - /// Internal access. - Internal, - - /// Protected internal access. - ProtectedInternal, - - /// Protected access. - Protected, - - /// Private access. - Private - } - /// public override ImmutableArray SupportedDiagnostics { @@ -138,34 +117,18 @@ private static void HandleTypeDeclaration(SyntaxNodeAnalysisContext context) private static void HandleMemberList(SyntaxNodeAnalysisContext context, SyntaxList members) { - var previousMemberStatic = true; - var previousMemberReadonly = true; - var previousMemberConst = true; var previousSyntaxKind = SyntaxKind.None; var previousAccessLevel = AccessLevel.NotSpecified; foreach (var member in members) { - var currentModifiers = member.GetModifiers(); - var currentMemberStatic = currentModifiers.Any(SyntaxKind.StaticKeyword); - var currentMemberReadonly = false; - var currentMemberConst = false; var currentSyntaxKind = member.Kind(); currentSyntaxKind = currentSyntaxKind == SyntaxKind.EventFieldDeclaration ? SyntaxKind.EventDeclaration : currentSyntaxKind; - if (currentSyntaxKind == SyntaxKind.FieldDeclaration) - { - currentMemberReadonly = currentModifiers.Any(SyntaxKind.ReadOnlyKeyword); - currentMemberConst = currentModifiers.Any(SyntaxKind.ConstKeyword); - } - - var currentAccessLevel = GetAccessLevel(currentModifiers); + var currentAccessLevel = AccessLevelHelper.GetAccessLevel(member.GetModifiers()); if (previousAccessLevel != AccessLevel.NotSpecified && currentAccessLevel != AccessLevel.NotSpecified && currentSyntaxKind == previousSyntaxKind - && currentMemberStatic == previousMemberStatic - && currentMemberReadonly == previousMemberReadonly - && currentMemberConst == previousMemberConst && currentAccessLevel < previousAccessLevel) { context.ReportDiagnostic( @@ -173,66 +136,13 @@ private static void HandleMemberList(SyntaxNodeAnalysisContext context, SyntaxLi Descriptor, NamedTypeHelpers.GetNameOrIdentifierLocation(member), UpperAccessLevelNames[currentAccessLevel], - currentMemberStatic ? " static" : currentMemberConst ? " const" : string.Empty, MemberNames[currentSyntaxKind], LowerAccessLevelNames[previousAccessLevel])); } - previousMemberStatic = currentMemberStatic; - previousMemberReadonly = currentMemberReadonly; - previousMemberConst = currentMemberConst; previousSyntaxKind = currentSyntaxKind; previousAccessLevel = currentAccessLevel; } } - - private static AccessLevel GetAccessLevel(SyntaxTokenList modifiers) - { - bool isProtected = false; - bool isInternal = false; - foreach (var modifier in modifiers) - { - switch (modifier.Kind()) - { - case SyntaxKind.PublicKeyword: - return AccessLevel.Public; - case SyntaxKind.PrivateKeyword: - return AccessLevel.Private; - case SyntaxKind.InternalKeyword: - if (isProtected) - { - return AccessLevel.ProtectedInternal; - } - else - { - isInternal = true; - } - - break; - case SyntaxKind.ProtectedKeyword: - if (isInternal) - { - return AccessLevel.ProtectedInternal; - } - else - { - isProtected = true; - } - - break; - } - } - - if (isProtected) - { - return AccessLevel.Protected; - } - else if (isInternal) - { - return AccessLevel.Internal; - } - - return AccessLevel.NotSpecified; - } } } diff --git a/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1203ConstantsMustAppearBeforeFields.cs b/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1203ConstantsMustAppearBeforeFields.cs index db7f368a8..911e45992 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1203ConstantsMustAppearBeforeFields.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1203ConstantsMustAppearBeforeFields.cs @@ -54,26 +54,27 @@ private static void HandleTypeDeclaration(SyntaxNodeAnalysisContext context) var typeDeclaration = (TypeDeclarationSyntax)context.Node; var members = typeDeclaration.Members; - bool nonConstFieldFound = false; + var previousFieldConstant = true; + var previousAcccessLevel = AccessLevel.NotSpecified; - for (int i = 0; i < members.Count; i++) + foreach (var member in members) { - var field = members[i] as FieldDeclarationSyntax; + var field = member as FieldDeclarationSyntax; if (field == null) { continue; } - bool thisFieldIsConstant = field.Modifiers.Any(SyntaxKind.ConstKeyword); - if (!thisFieldIsConstant) - { - nonConstFieldFound = true; - } + bool currentFieldConstant = field.Modifiers.Any(SyntaxKind.ConstKeyword); + var currentAccessLevel = AccessLevelHelper.GetAccessLevel(field.Modifiers); - if (thisFieldIsConstant && nonConstFieldFound) + if (currentAccessLevel == previousAcccessLevel && !previousFieldConstant && currentFieldConstant) { - context.ReportDiagnostic(Diagnostic.Create(Descriptor, NamedTypeHelpers.GetNameOrIdentifierLocation(members[i]))); + context.ReportDiagnostic(Diagnostic.Create(Descriptor, NamedTypeHelpers.GetNameOrIdentifierLocation(member))); } + + previousFieldConstant = currentFieldConstant; + previousAcccessLevel = currentAccessLevel; } } } diff --git a/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1204StaticElementsMustAppearBeforeInstanceElements.cs b/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1204StaticElementsMustAppearBeforeInstanceElements.cs index afe66d203..7027b1c98 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1204StaticElementsMustAppearBeforeInstanceElements.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1204StaticElementsMustAppearBeforeInstanceElements.cs @@ -85,16 +85,19 @@ private static void HandleTypeDelcaration(SyntaxNodeAnalysisContext context) private static void HandleMemberList(SyntaxNodeAnalysisContext context, SyntaxList members) { var previousSyntaxKind = SyntaxKind.None; + var previousAccessLevel = AccessLevel.NotSpecified; var previousMemberStatic = true; foreach (var member in members) { var currentSyntaxKind = member.Kind(); currentSyntaxKind = currentSyntaxKind == SyntaxKind.EventFieldDeclaration ? SyntaxKind.EventDeclaration : currentSyntaxKind; var modifiers = member.GetModifiers(); + var currentAccessLevel = AccessLevelHelper.GetAccessLevel(modifiers); var currentMemberStatic = modifiers.Any(SyntaxKind.StaticKeyword); var currentMemberConst = modifiers.Any(SyntaxKind.ConstKeyword); if (currentSyntaxKind == previousSyntaxKind + && currentAccessLevel == previousAccessLevel && !previousMemberStatic && currentMemberStatic && !currentMemberConst) @@ -103,6 +106,7 @@ private static void HandleMemberList(SyntaxNodeAnalysisContext context, SyntaxLi } previousSyntaxKind = currentSyntaxKind; + previousAccessLevel = currentAccessLevel; previousMemberStatic = currentMemberStatic || currentMemberConst; } } diff --git a/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1214StaticReadonlyElementsMustAppearBeforeStaticNonReadonlyElements.cs b/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1214StaticReadonlyElementsMustAppearBeforeStaticNonReadonlyElements.cs index d607ee943..808f85bbc 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1214StaticReadonlyElementsMustAppearBeforeStaticNonReadonlyElements.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1214StaticReadonlyElementsMustAppearBeforeStaticNonReadonlyElements.cs @@ -58,42 +58,28 @@ private void AnalyzeTypeDeclaration(SyntaxNodeAnalysisContext context) private static void AnalyzeType(SyntaxNodeAnalysisContext context, TypeDeclarationSyntax typeDeclaration) { - var staticFields = typeDeclaration.Members - .OfType() - .Where(f => f.Modifiers.Any(SyntaxKind.StaticKeyword)) - .ToList(); - - var firstNonReadonlyField = - staticFields.FirstOrDefault(f => !f.Modifiers.Any(SyntaxKind.ReadOnlyKeyword)); - - if (firstNonReadonlyField == null) - { - return; - } - - var firstNonReadonlyFieldLocation = firstNonReadonlyField.GetLineSpan(); - if (!firstNonReadonlyFieldLocation.IsValid) + var previousFieldReadonly = true; + var previousAccessLevel = AccessLevel.NotSpecified; + var previousMemberStatic = true; + foreach (var member in typeDeclaration.Members) { - return; - } - - var readonlyFieldLocations = - staticFields.Where(f => f.Modifiers.Any(SyntaxKind.ReadOnlyKeyword)) - .Where(f => f.GetLineSpan().IsValid) - .Where(f => f.Declaration != null && f.Declaration.Variables.Any()) - .Select(f => new - { - FieldDeclaration = f, - FieldEndLinePosition = f.GetLineSpan().EndLinePosition - }) - .ToList(); + var field = member as FieldDeclarationSyntax; + if (field == null) + { + continue; + } - foreach (var location in readonlyFieldLocations) - { - if (firstNonReadonlyFieldLocation.EndLinePosition < location.FieldEndLinePosition) + var currentFieldReadonly = field.Modifiers.Any(SyntaxKind.ReadOnlyKeyword); + var currentAccessLevel = AccessLevelHelper.GetAccessLevel(field.Modifiers); + var currentMemberStatic = field.Modifiers.Any(SyntaxKind.StaticKeyword); + if (currentMemberStatic && previousMemberStatic && currentFieldReadonly && !previousFieldReadonly) { - context.ReportDiagnostic(Diagnostic.Create(Descriptor, location.FieldDeclaration.GetLocation())); + context.ReportDiagnostic(Diagnostic.Create(Descriptor, NamedTypeHelpers.GetNameOrIdentifierLocation(field))); } + + previousFieldReadonly = currentFieldReadonly; + previousAccessLevel = currentAccessLevel; + previousMemberStatic = currentMemberStatic; } } } diff --git a/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1215InstanceReadonlyElementsMustAppearBeforeInstanceNonReadonlyElements.cs b/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1215InstanceReadonlyElementsMustAppearBeforeInstanceNonReadonlyElements.cs index 89d91a6d1..f8c292f75 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1215InstanceReadonlyElementsMustAppearBeforeInstanceNonReadonlyElements.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1215InstanceReadonlyElementsMustAppearBeforeInstanceNonReadonlyElements.cs @@ -53,21 +53,27 @@ private static void HandleTypeDeclaration(SyntaxNodeAnalysisContext context) var typeDeclaration = (TypeDeclarationSyntax)context.Node; var previousFieldReadonly = true; + var previousAccessLevel = AccessLevel.NotSpecified; + var previousMemberStatic = true; foreach (var member in typeDeclaration.Members) { var field = member as FieldDeclarationSyntax; - if (field == null || field.Modifiers.Any(SyntaxKind.StaticKeyword)) + if (field == null) { continue; } var currentFieldReadonly = field.Modifiers.Any(SyntaxKind.ReadOnlyKeyword); - if (currentFieldReadonly && !previousFieldReadonly) + var currentAccessLevel = AccessLevelHelper.GetAccessLevel(field.Modifiers); + var currentMemberStatic = field.Modifiers.Any(SyntaxKind.StaticKeyword); + if (!currentMemberStatic && !previousMemberStatic && currentFieldReadonly && !previousFieldReadonly) { context.ReportDiagnostic(Diagnostic.Create(Descriptor, NamedTypeHelpers.GetNameOrIdentifierLocation(field))); } previousFieldReadonly = currentFieldReadonly; + previousAccessLevel = currentAccessLevel; + previousMemberStatic = currentMemberStatic; } } } diff --git a/StyleCop.Analyzers/StyleCop.Analyzers/StyleCop.Analyzers.csproj b/StyleCop.Analyzers/StyleCop.Analyzers/StyleCop.Analyzers.csproj index da3d6a775..6c6120c75 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers/StyleCop.Analyzers.csproj +++ b/StyleCop.Analyzers/StyleCop.Analyzers/StyleCop.Analyzers.csproj @@ -232,6 +232,8 @@ + + True True From f2173b82c27681371526a49618b0126fc7367912 Mon Sep 17 00:00:00 2001 From: John Venable Date: Thu, 6 Aug 2015 18:29:19 -0400 Subject: [PATCH 2/3] Add tests for nested classes and improve diagnostic messages --- .../OrderingRules/SA1202UnitTests.cs | 79 +++++++++++++------ .../OrderingRules/SA1203UnitTests.cs | 17 +++- .../OrderingRules/SA1204UnitTests.cs | 69 ++++++++++++++-- .../OrderingRules/SA1214UnitTests.cs | 10 +-- .../OrderingRules/SA1215UnitTests.cs | 4 +- .../OrderingRules/AccessLevelHelper.cs | 18 +++++ .../SA1202ElementsMustBeOrderedByAccess.cs | 24 +----- .../SA1203ConstantsMustAppearBeforeFields.cs | 4 +- ...lementsMustAppearBeforeInstanceElements.cs | 9 ++- ...stAppearBeforeStaticNonReadonlyElements.cs | 4 +- ...AppearBeforeInstanceNonReadonlyElements.cs | 4 +- 11 files changed, 171 insertions(+), 71 deletions(-) diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1202UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1202UnitTests.cs index 58fad8ff2..918d0e6ff 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1202UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1202UnitTests.cs @@ -80,6 +80,17 @@ protected static void TestMethod7() { } protected void TestMethod8() { } private static void TestMethod9() { } private void TestMethod10() { } + + public static class TestClass1 { } + public class TestClass2 { } + internal static class TestClass3 { } + internal class TestClass4 { } + protected internal static class TestClass5 { } + protected internal class TestClass6 { } + protected static class TestClass7 { } + protected class TestClass8 { } + private static class TestClass9 { } + private class TestClass10 { } } "; @@ -97,7 +108,7 @@ public async Task TestClassOrderingAsync() public class TestClass2 { } "; - var expected = this.CSharpDiagnostic().WithLocation(2, 14).WithArguments("Public", "classes", "internal"); + var expected = this.CSharpDiagnostic().WithLocation(2, 14).WithArguments("public", "classes", "internal"); await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false); } @@ -135,10 +146,10 @@ public async Task TestPropertiesAsync() DiagnosticResult[] expected = { - this.CSharpDiagnostic().WithLocation(4, 22).WithArguments("Protected", "properties", "private"), - this.CSharpDiagnostic().WithLocation(5, 31).WithArguments("Protected internal", "properties", "protected"), - this.CSharpDiagnostic().WithLocation(6, 21).WithArguments("Internal", "properties", "protected internal"), - this.CSharpDiagnostic().WithLocation(7, 19).WithArguments("Public", "properties", "internal") + this.CSharpDiagnostic().WithLocation(4, 22).WithArguments("protected", "properties", "private"), + this.CSharpDiagnostic().WithLocation(5, 31).WithArguments("protected internal", "properties", "protected"), + this.CSharpDiagnostic().WithLocation(6, 21).WithArguments("internal", "properties", "protected internal"), + this.CSharpDiagnostic().WithLocation(7, 19).WithArguments("public", "properties", "internal") }; await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false); @@ -163,10 +174,10 @@ public void TestMethod5() { } DiagnosticResult[] expected = { - this.CSharpDiagnostic().WithLocation(4, 20).WithArguments("Protected", "methods", "private"), - this.CSharpDiagnostic().WithLocation(5, 29).WithArguments("Protected internal", "methods", "protected"), - this.CSharpDiagnostic().WithLocation(6, 19).WithArguments("Internal", "methods", "protected internal"), - this.CSharpDiagnostic().WithLocation(7, 17).WithArguments("Public", "methods", "internal") + this.CSharpDiagnostic().WithLocation(4, 20).WithArguments("protected", "methods", "private"), + this.CSharpDiagnostic().WithLocation(5, 29).WithArguments("protected internal", "methods", "protected"), + this.CSharpDiagnostic().WithLocation(6, 19).WithArguments("internal", "methods", "protected internal"), + this.CSharpDiagnostic().WithLocation(7, 17).WithArguments("public", "methods", "internal") }; await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false); @@ -186,7 +197,7 @@ public async Task TestProtectedInternalBeforePublicAsync() } "; - var expected = this.CSharpDiagnostic().WithLocation(4, 5).WithArguments("Public", "events", "protected internal"); + var expected = this.CSharpDiagnostic().WithLocation(4, 5).WithArguments("public", "events", "protected internal"); await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false); } @@ -205,7 +216,7 @@ public async Task TestProtectedBeforePublicAsync() } "; - var expected = this.CSharpDiagnostic().WithLocation(4, 19).WithArguments("Public", "fields", "protected"); + var expected = this.CSharpDiagnostic().WithLocation(4, 19).WithArguments("public", "fields", "protected"); await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false); } @@ -224,7 +235,7 @@ public event System.Action TestEvent2 { add { } remove { } } } "; - var expected = this.CSharpDiagnostic().WithLocation(4, 32).WithArguments("Public", "events", "private"); + var expected = this.CSharpDiagnostic().WithLocation(4, 32).WithArguments("public", "events", "private"); await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false); } @@ -243,7 +254,7 @@ internal event System.Action TestEvent2 { add { } remove { } } } "; - var expected = this.CSharpDiagnostic().WithLocation(4, 34).WithArguments("Internal", "events", "protected"); + var expected = this.CSharpDiagnostic().WithLocation(4, 34).WithArguments("internal", "events", "protected"); await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false); } @@ -262,7 +273,7 @@ public async Task TestPrivateBeforeInternalAsync() } "; - var expected = this.CSharpDiagnostic().WithLocation(4, 28).WithArguments("Internal", "delegates", "private"); + var expected = this.CSharpDiagnostic().WithLocation(4, 28).WithArguments("internal", "delegates", "private"); await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false); } @@ -281,7 +292,7 @@ protected internal void TestMethod2() { } } "; - var expected = this.CSharpDiagnostic().WithLocation(4, 29).WithArguments("Protected internal", "methods", "private"); + var expected = this.CSharpDiagnostic().WithLocation(4, 29).WithArguments("protected internal", "methods", "private"); await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false); } @@ -300,7 +311,7 @@ internal protected void TestMethod2() { } } "; - var expected = this.CSharpDiagnostic().WithLocation(4, 29).WithArguments("Protected internal", "methods", "private"); + var expected = this.CSharpDiagnostic().WithLocation(4, 29).WithArguments("protected internal", "methods", "private"); await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false); } @@ -338,7 +349,7 @@ public async Task TestOnlyFirstViolationReportedAsync() } "; - var expected = this.CSharpDiagnostic().WithLocation(4, 19).WithArguments("Public", "fields", "private"); + var expected = this.CSharpDiagnostic().WithLocation(4, 19).WithArguments("public", "fields", "private"); await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false); } @@ -362,7 +373,7 @@ public void B() } "; - var expected = this.CSharpDiagnostic().WithLocation(7, 17).WithArguments("Public", "methods", "private"); + var expected = this.CSharpDiagnostic().WithLocation(7, 17).WithArguments("public", "methods", "private"); await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false); } @@ -386,10 +397,10 @@ public static void TestMethod5() { } DiagnosticResult[] expected = { - this.CSharpDiagnostic().WithLocation(4, 27).WithArguments("Protected", "methods", "private"), - this.CSharpDiagnostic().WithLocation(5, 36).WithArguments("Protected internal", "methods", "protected"), - this.CSharpDiagnostic().WithLocation(6, 26).WithArguments("Internal", "methods", "protected internal"), - this.CSharpDiagnostic().WithLocation(7, 24).WithArguments("Public", "methods", "internal") + this.CSharpDiagnostic().WithLocation(4, 27).WithArguments("protected", "methods", "private"), + this.CSharpDiagnostic().WithLocation(5, 36).WithArguments("protected internal", "methods", "protected"), + this.CSharpDiagnostic().WithLocation(6, 26).WithArguments("internal", "methods", "protected internal"), + this.CSharpDiagnostic().WithLocation(7, 24).WithArguments("public", "methods", "internal") }; await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false); @@ -412,13 +423,33 @@ public async Task TestConstOrderingAsync() DiagnosticResult[] expected = { - this.CSharpDiagnostic().WithLocation(4, 25).WithArguments("Protected", "fields", "private"), - this.CSharpDiagnostic().WithLocation(5, 16).WithArguments("Public", "fields", "protected") + this.CSharpDiagnostic().WithLocation(4, 25).WithArguments("protected", "fields", "private"), + this.CSharpDiagnostic().WithLocation(5, 16).WithArguments("public", "fields", "protected") }; await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false); } + /// + /// Verifies that the analyzer will properly handle nested class ordering. + /// + /// A representing the asynchronous unit test. + [Fact] + public async Task TestNestedClassesAsync() + { + var testCode = @"public class TestClass +{ + public class TestClass1 { } + private class TestClass2 { } + internal class TestClass3 { } +} +"; + + var expected = this.CSharpDiagnostic().WithLocation(5, 20).WithArguments("internal", "classes", "private"); + + await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false); + } + /// /// Verifies that the analyzer will properly handle incomplete members. /// diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1203UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1203UnitTests.cs index 3f6da3861..c16fad2d1 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1203UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1203UnitTests.cs @@ -74,6 +74,17 @@ protected static void TestMethod7() { } protected void TestMethod8() { } private static void TestMethod9() { } private void TestMethod10() { } + + public static class TestClass1 { } + public class TestClass2a { } + internal static class TestClass3 { } + internal class TestClass4 { } + protected internal static class TestClass5 { } + protected internal class TestClass6 { } + protected static class TestClass7 { } + protected class TestClass8 { } + private static class TestClass9 { } + private class TestClass10 { } } "; @@ -89,7 +100,7 @@ public class Foo private int Baz = 1; private const int Bar = 2; }"; - var firstDiagnostic = this.CSharpDiagnostic().WithLocation(5, 23); + var firstDiagnostic = this.CSharpDiagnostic().WithLocation(5, 23).WithArguments("private"); await this.VerifyCSharpDiagnosticAsync(testCode, firstDiagnostic, CancellationToken.None).ConfigureAwait(false); } @@ -102,7 +113,7 @@ public struct Foo private int baz; private const int Bar = 2; }"; - var firstDiagnostic = this.CSharpDiagnostic().WithLocation(5, 23); + var firstDiagnostic = this.CSharpDiagnostic().WithLocation(5, 23).WithArguments("private"); await this.VerifyCSharpDiagnosticAsync(testCode, firstDiagnostic, CancellationToken.None).ConfigureAwait(false); } @@ -116,7 +127,7 @@ public class Foo private int Baz = 1; private const int FooBar = 2; }"; - var firstDiagnostic = this.CSharpDiagnostic().WithLocation(6, 23); + var firstDiagnostic = this.CSharpDiagnostic().WithLocation(6, 23).WithArguments("private"); await this.VerifyCSharpDiagnosticAsync(testCode, firstDiagnostic, CancellationToken.None).ConfigureAwait(false); } diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1204UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1204UnitTests.cs index 275a42c43..4d7c513c9 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1204UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1204UnitTests.cs @@ -82,6 +82,17 @@ protected static void TestMethod7() { } protected void TestMethod8() { } private static void TestMethod9() { } private void TestMethod10() { } + + public static class TestClass1 { } + public class TestClass2a { } + internal static class TestClass3 { } + internal class TestClass4 { } + protected internal static class TestClass5 { } + protected internal class TestClass6 { } + protected static class TestClass7 { } + protected class TestClass8 { } + private static class TestClass9 { } + private class TestClass10 { } } "; @@ -101,7 +112,7 @@ public static class TestClass2 { } DiagnosticResult[] expected = { - this.CSharpDiagnostic().WithLocation(2, 21).WithArguments("classes") + this.CSharpDiagnostic().WithLocation(2, 21).WithArguments("public", "classes") }; await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false); @@ -128,9 +139,9 @@ public static void TestMethod2() { } DiagnosticResult[] expected = { - this.CSharpDiagnostic().WithLocation(4, 23).WithArguments("fields"), - this.CSharpDiagnostic().WithLocation(6, 23).WithArguments("properties"), - this.CSharpDiagnostic().WithLocation(8, 24).WithArguments("methods") + this.CSharpDiagnostic().WithLocation(4, 23).WithArguments("public", "fields"), + this.CSharpDiagnostic().WithLocation(6, 23).WithArguments("public", "properties"), + this.CSharpDiagnostic().WithLocation(8, 24).WithArguments("public", "methods") }; await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false); @@ -157,9 +168,9 @@ public static void TestMethod2() { } DiagnosticResult[] expected = { - this.CSharpDiagnostic().WithLocation(4, 23).WithArguments("fields"), - this.CSharpDiagnostic().WithLocation(6, 23).WithArguments("properties"), - this.CSharpDiagnostic().WithLocation(8, 24).WithArguments("methods") + this.CSharpDiagnostic().WithLocation(4, 23).WithArguments("public", "fields"), + this.CSharpDiagnostic().WithLocation(6, 23).WithArguments("public", "properties"), + this.CSharpDiagnostic().WithLocation(8, 24).WithArguments("public", "methods") }; await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false); @@ -183,7 +194,7 @@ public static event System.Action TestEvent4 { add { } remove { } } DiagnosticResult[] expected = { - this.CSharpDiagnostic().WithLocation(5, 5).WithArguments("events") + this.CSharpDiagnostic().WithLocation(5, 5).WithArguments("public", "events") }; await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false); @@ -206,6 +217,48 @@ public async Task TestConstNotReportedBeforeInstanceMembersAsync() await this.VerifyCSharpDiagnosticAsync(testCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false); } + /// + /// Verifies that the analyzer will properly handle nested class ordering. + /// + /// A representing the asynchronous unit test. + [Fact] + public async Task TestNestedClassesAsync() + { + var testCode = @"public class TestClass +{ + public class TestClass1 { } + internal class TestClass2 { } + internal static class TestClass3 { } +} +"; + + var expected = this.CSharpDiagnostic().WithLocation(5, 27).WithArguments("internal", "classes"); + + await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false); + } + + /// + /// Verifies that the analyzer will properly handle class ordering. + /// + /// A representing the asynchronous unit test. + [Fact] + public async Task TestClassesAsync() + { + var testCode = @"public class TestClass1 { } +public static class TestClass2 { } +internal class TestClass3 { } +internal static class TestClass4 { } +"; + + DiagnosticResult[] expected = + { + this.CSharpDiagnostic().WithLocation(2, 21).WithArguments("public", "classes"), + this.CSharpDiagnostic().WithLocation(4, 23).WithArguments("internal", "classes"), + }; + + await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false); + } + /// /// Verifies that the analyzer will properly incomplete members. /// diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1214UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1214UnitTests.cs index d3b44d7f1..0fbfc529a 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1214UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1214UnitTests.cs @@ -92,7 +92,7 @@ public class Foo var expected = new[] { - this.CSharpDiagnostic().WithLocation(5, 33) + this.CSharpDiagnostic().WithLocation(5, 33).WithArguments("private") }; await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false); @@ -122,7 +122,7 @@ public class Foo var expected = new[] { - this.CSharpDiagnostic().WithLocation(4, 58) + this.CSharpDiagnostic().WithLocation(4, 58).WithArguments("private") }; await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false); @@ -166,7 +166,7 @@ public struct Foo var expected = new[] { - this.CSharpDiagnostic().WithLocation(5, 33) + this.CSharpDiagnostic().WithLocation(5, 33).WithArguments("private") }; await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false); @@ -200,8 +200,8 @@ public class FooInner var expected = new[] { - this.CSharpDiagnostic().WithLocation(11, 33), - this.CSharpDiagnostic().WithLocation(18, 37) + this.CSharpDiagnostic().WithLocation(11, 33).WithArguments("public"), + this.CSharpDiagnostic().WithLocation(18, 37).WithArguments("private") // line 21 should be reported by SA1201 }; diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1215UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1215UnitTests.cs index 3b44c7876..b8bdb3391 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1215UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1215UnitTests.cs @@ -116,7 +116,7 @@ public async Task TestReadonlyOrderingInClassAsync() } "; - DiagnosticResult expected = this.CSharpDiagnostic().WithLocation(4, 25); + DiagnosticResult expected = this.CSharpDiagnostic().WithLocation(4, 25).WithArguments("public"); await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false); } @@ -135,7 +135,7 @@ public async Task TestReadonlyOrderingInStructAsync() } "; - DiagnosticResult expected = this.CSharpDiagnostic().WithLocation(4, 25); + DiagnosticResult expected = this.CSharpDiagnostic().WithLocation(4, 25).WithArguments("public"); await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false); } diff --git a/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/AccessLevelHelper.cs b/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/AccessLevelHelper.cs index 264653276..301397ce1 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/AccessLevelHelper.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/AccessLevelHelper.cs @@ -1,5 +1,6 @@ namespace StyleCop.Analyzers.OrderingRules { + using System.Collections.Generic; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; @@ -8,6 +9,15 @@ /// internal static class AccessLevelHelper { + private static readonly Dictionary AccessLevelNames = new Dictionary + { + [AccessLevel.Public] = "public", + [AccessLevel.Internal] = "internal", + [AccessLevel.ProtectedInternal] = "protected internal", + [AccessLevel.Protected] = "protected", + [AccessLevel.Private] = "private" + }; + /// Determines the access level for the given . /// The modifiers. /// A value representing the access level. @@ -59,5 +69,13 @@ internal static AccessLevel GetAccessLevel(SyntaxTokenList modifiers) return AccessLevel.NotSpecified; } + + /// Gets the name for a given access level. + /// The access level. + /// The name for a given access level. + internal static string GetName(AccessLevel accessLevel) + { + return AccessLevelNames[accessLevel]; + } } } diff --git a/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1202ElementsMustBeOrderedByAccess.cs b/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1202ElementsMustBeOrderedByAccess.cs index 2474af09d..802e46833 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1202ElementsMustBeOrderedByAccess.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1202ElementsMustBeOrderedByAccess.cs @@ -40,7 +40,7 @@ public class SA1202ElementsMustBeOrderedByAccess : DiagnosticAnalyzer /// public const string DiagnosticId = "SA1202"; private const string Title = "Elements must be ordered by access"; - private const string MessageFormat = "{0} {1} must come before {2}."; + private const string MessageFormat = "All {0} {1} must come before {2} {1}."; private const string Description = "An element within a C# code file is out of order within regard to access level, in relation to other elements in the code."; private const string HelpLink = "http://www.stylecop.com/docs/SA1202.html"; @@ -50,24 +50,6 @@ public class SA1202ElementsMustBeOrderedByAccess : DiagnosticAnalyzer private static readonly ImmutableArray SupportedDiagnosticsValue = ImmutableArray.Create(Descriptor); - private static readonly Dictionary UpperAccessLevelNames = new Dictionary - { - [AccessLevel.Public] = "Public", - [AccessLevel.Internal] = "Internal", - [AccessLevel.ProtectedInternal] = "Protected internal", - [AccessLevel.Protected] = "Protected", - [AccessLevel.Private] = "Private" - }; - - private static readonly Dictionary LowerAccessLevelNames = new Dictionary - { - [AccessLevel.Public] = "public", - [AccessLevel.Internal] = "internal", - [AccessLevel.ProtectedInternal] = "protected internal", - [AccessLevel.Protected] = "protected", - [AccessLevel.Private] = "private" - }; - private static readonly Dictionary MemberNames = new Dictionary { [SyntaxKind.DelegateDeclaration] = "delegates", @@ -135,9 +117,9 @@ private static void HandleMemberList(SyntaxNodeAnalysisContext context, SyntaxLi Diagnostic.Create( Descriptor, NamedTypeHelpers.GetNameOrIdentifierLocation(member), - UpperAccessLevelNames[currentAccessLevel], + AccessLevelHelper.GetName(currentAccessLevel), MemberNames[currentSyntaxKind], - LowerAccessLevelNames[previousAccessLevel])); + AccessLevelHelper.GetName(previousAccessLevel))); } previousSyntaxKind = currentSyntaxKind; diff --git a/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1203ConstantsMustAppearBeforeFields.cs b/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1203ConstantsMustAppearBeforeFields.cs index 911e45992..4d250d8da 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1203ConstantsMustAppearBeforeFields.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1203ConstantsMustAppearBeforeFields.cs @@ -23,7 +23,7 @@ public class SA1203ConstantsMustAppearBeforeFields : DiagnosticAnalyzer /// public const string DiagnosticId = "SA1203"; private const string Title = "Constants must appear before fields"; - private const string MessageFormat = "Constants must appear before fields"; + private const string MessageFormat = "All {0} constants must appear before {0} fields"; private const string Description = "A constant field is placed beneath a non-constant field."; private const string HelpLink = "http://www.stylecop.com/docs/SA1203.html"; @@ -70,7 +70,7 @@ private static void HandleTypeDeclaration(SyntaxNodeAnalysisContext context) if (currentAccessLevel == previousAcccessLevel && !previousFieldConstant && currentFieldConstant) { - context.ReportDiagnostic(Diagnostic.Create(Descriptor, NamedTypeHelpers.GetNameOrIdentifierLocation(member))); + context.ReportDiagnostic(Diagnostic.Create(Descriptor, NamedTypeHelpers.GetNameOrIdentifierLocation(member), AccessLevelHelper.GetName(currentAccessLevel))); } previousFieldConstant = currentFieldConstant; diff --git a/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1204StaticElementsMustAppearBeforeInstanceElements.cs b/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1204StaticElementsMustAppearBeforeInstanceElements.cs index 7027b1c98..19c338622 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1204StaticElementsMustAppearBeforeInstanceElements.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1204StaticElementsMustAppearBeforeInstanceElements.cs @@ -26,7 +26,7 @@ public class SA1204StaticElementsMustAppearBeforeInstanceElements : DiagnosticAn /// public const string DiagnosticId = "SA1204"; private const string Title = "Static elements must appear before instance elements"; - private const string MessageFormat = "Static {0} must appear before instance {0}."; + private const string MessageFormat = "All {0} static {1} must appear before {0} non-static {1}."; private const string Description = "A static element is positioned beneath an instance element of the same type."; private const string HelpLink = "http://www.stylecop.com/docs/SA1204.html"; @@ -102,7 +102,12 @@ private static void HandleMemberList(SyntaxNodeAnalysisContext context, SyntaxLi && currentMemberStatic && !currentMemberConst) { - context.ReportDiagnostic(Diagnostic.Create(Descriptor, NamedTypeHelpers.GetNameOrIdentifierLocation(member), MemberNames[currentSyntaxKind])); + context.ReportDiagnostic( + Diagnostic.Create( + Descriptor, + NamedTypeHelpers.GetNameOrIdentifierLocation(member), + AccessLevelHelper.GetName(currentAccessLevel), + MemberNames[currentSyntaxKind])); } previousSyntaxKind = currentSyntaxKind; diff --git a/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1214StaticReadonlyElementsMustAppearBeforeStaticNonReadonlyElements.cs b/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1214StaticReadonlyElementsMustAppearBeforeStaticNonReadonlyElements.cs index 808f85bbc..3b98feee3 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1214StaticReadonlyElementsMustAppearBeforeStaticNonReadonlyElements.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1214StaticReadonlyElementsMustAppearBeforeStaticNonReadonlyElements.cs @@ -24,7 +24,7 @@ public class SA1214StaticReadonlyElementsMustAppearBeforeStaticNonReadonlyElemen /// public const string DiagnosticId = "SA1214"; private const string Title = "Static readonly elements must appear before static non-readonly elements"; - private const string MessageFormat = "Static readonly elements must appear before static non-readonly elements."; + private const string MessageFormat = "All {0} static readonly fields must appear before {0} static non-readonly fields."; private const string Description = "A static readonly element is positioned beneath a static non-readonly element of the same type."; private const string HelpLink = "http://www.stylecop.com/docs/SA1214.html"; @@ -74,7 +74,7 @@ private static void AnalyzeType(SyntaxNodeAnalysisContext context, TypeDeclarati var currentMemberStatic = field.Modifiers.Any(SyntaxKind.StaticKeyword); if (currentMemberStatic && previousMemberStatic && currentFieldReadonly && !previousFieldReadonly) { - context.ReportDiagnostic(Diagnostic.Create(Descriptor, NamedTypeHelpers.GetNameOrIdentifierLocation(field))); + context.ReportDiagnostic(Diagnostic.Create(Descriptor, NamedTypeHelpers.GetNameOrIdentifierLocation(field), AccessLevelHelper.GetName(currentAccessLevel))); } previousFieldReadonly = currentFieldReadonly; diff --git a/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1215InstanceReadonlyElementsMustAppearBeforeInstanceNonReadonlyElements.cs b/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1215InstanceReadonlyElementsMustAppearBeforeInstanceNonReadonlyElements.cs index f8c292f75..bc0c03e3e 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1215InstanceReadonlyElementsMustAppearBeforeInstanceNonReadonlyElements.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1215InstanceReadonlyElementsMustAppearBeforeInstanceNonReadonlyElements.cs @@ -23,7 +23,7 @@ public class SA1215InstanceReadonlyElementsMustAppearBeforeInstanceNonReadonlyEl /// public const string DiagnosticId = "SA1215"; private const string Title = "Instance readonly elements must appear before instance non-readonly elements"; - private const string MessageFormat = "Instance readonly elements must appear before instance non-readonly elements."; + private const string MessageFormat = "All {0} readonly fields must appear before {0} non-readonly fields."; private const string Description = "An instance readonly element is positioned beneath an instance non-readonly element of the same type."; private const string HelpLink = "http://www.stylecop.com/docs/SA1215.html"; @@ -68,7 +68,7 @@ private static void HandleTypeDeclaration(SyntaxNodeAnalysisContext context) var currentMemberStatic = field.Modifiers.Any(SyntaxKind.StaticKeyword); if (!currentMemberStatic && !previousMemberStatic && currentFieldReadonly && !previousFieldReadonly) { - context.ReportDiagnostic(Diagnostic.Create(Descriptor, NamedTypeHelpers.GetNameOrIdentifierLocation(field))); + context.ReportDiagnostic(Diagnostic.Create(Descriptor, NamedTypeHelpers.GetNameOrIdentifierLocation(field), AccessLevelHelper.GetName(currentAccessLevel))); } previousFieldReadonly = currentFieldReadonly; From df6f548e4fb2b0e4eadf3fb750773fefa2dbe432 Mon Sep 17 00:00:00 2001 From: John Venable Date: Thu, 6 Aug 2015 19:46:10 -0400 Subject: [PATCH 3/3] move AccessLevelHelper to Helpers --- .../{OrderingRules => Helpers}/AccessLevel.cs | 2 +- .../{OrderingRules => Helpers}/AccessLevelHelper.cs | 2 +- .../StyleCop.Analyzers/StyleCop.Analyzers.csproj | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) rename StyleCop.Analyzers/StyleCop.Analyzers/{OrderingRules => Helpers}/AccessLevel.cs (92%) rename StyleCop.Analyzers/StyleCop.Analyzers/{OrderingRules => Helpers}/AccessLevelHelper.cs (98%) diff --git a/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/AccessLevel.cs b/StyleCop.Analyzers/StyleCop.Analyzers/Helpers/AccessLevel.cs similarity index 92% rename from StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/AccessLevel.cs rename to StyleCop.Analyzers/StyleCop.Analyzers/Helpers/AccessLevel.cs index 9b28f3d60..6b5c551bc 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/AccessLevel.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers/Helpers/AccessLevel.cs @@ -1,4 +1,4 @@ -namespace StyleCop.Analyzers.OrderingRules +namespace StyleCop.Analyzers.Helpers { /// /// Describes an element's access level diff --git a/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/AccessLevelHelper.cs b/StyleCop.Analyzers/StyleCop.Analyzers/Helpers/AccessLevelHelper.cs similarity index 98% rename from StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/AccessLevelHelper.cs rename to StyleCop.Analyzers/StyleCop.Analyzers/Helpers/AccessLevelHelper.cs index 301397ce1..f940180fe 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/AccessLevelHelper.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers/Helpers/AccessLevelHelper.cs @@ -1,4 +1,4 @@ -namespace StyleCop.Analyzers.OrderingRules +namespace StyleCop.Analyzers.Helpers { using System.Collections.Generic; using Microsoft.CodeAnalysis; diff --git a/StyleCop.Analyzers/StyleCop.Analyzers/StyleCop.Analyzers.csproj b/StyleCop.Analyzers/StyleCop.Analyzers/StyleCop.Analyzers.csproj index 6c6120c75..c33646751 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers/StyleCop.Analyzers.csproj +++ b/StyleCop.Analyzers/StyleCop.Analyzers/StyleCop.Analyzers.csproj @@ -232,8 +232,8 @@ - - + + True True