diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/NamingRules/SA1313CSharp10UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/NamingRules/SA1313CSharp10UnitTests.cs index d099245cb..9d2127a9a 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/NamingRules/SA1313CSharp10UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/NamingRules/SA1313CSharp10UnitTests.cs @@ -1,14 +1,12 @@ // Copyright (c) Tunnel Vision Laboratories, LLC. All Rights Reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. -#nullable disable - namespace StyleCop.Analyzers.Test.CSharp10.NamingRules { using System.Threading; using System.Threading.Tasks; + using Microsoft.CodeAnalysis.Testing; using StyleCop.Analyzers.Test.CSharp9.NamingRules; - using StyleCop.Analyzers.Test.Verifiers; using Xunit; using static StyleCop.Analyzers.Test.Verifiers.StyleCopCodeFixVerifier< StyleCop.Analyzers.NamingRules.SA1313ParameterNamesMustBeginWithLowerCaseLetter, @@ -42,12 +40,7 @@ public R(int a, int b) }} "; - await new CSharpTest() - { - ReferenceAssemblies = GenericAnalyzerTest.ReferenceAssembliesNet60, - TestCode = testCode, - FixedCode = fixedCode, - }.RunAsync(CancellationToken.None).ConfigureAwait(false); + await VerifyCSharpFixAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, fixedCode, CancellationToken.None).ConfigureAwait(false); } } } diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/ReadabilityRules/SA1101CSharp10UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/ReadabilityRules/SA1101CSharp10UnitTests.cs index 33b092d9e..cc17c7e56 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/ReadabilityRules/SA1101CSharp10UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp10/ReadabilityRules/SA1101CSharp10UnitTests.cs @@ -5,8 +5,8 @@ namespace StyleCop.Analyzers.Test.CSharp10.ReadabilityRules { using System.Threading; using System.Threading.Tasks; + using Microsoft.CodeAnalysis.Testing; using StyleCop.Analyzers.Test.CSharp9.ReadabilityRules; - using StyleCop.Analyzers.Test.Verifiers; using Xunit; using static StyleCop.Analyzers.Test.Verifiers.StyleCopCodeFixVerifier< StyleCop.Analyzers.ReadabilityRules.SA1101PrefixLocalCallsWithThis, @@ -29,11 +29,7 @@ public bool Method(Test arg) } }"; - await new CSharpTest() - { - ReferenceAssemblies = GenericAnalyzerTest.ReferenceAssembliesNet60, - TestCode = testCode, - }.RunAsync(CancellationToken.None).ConfigureAwait(false); + await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false); } } } diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp11/OrderingRules/SA1206CSharp11CodeFixProviderUnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp11/OrderingRules/SA1206CSharp11CodeFixProviderUnitTests.cs index 53cefd548..4371e2887 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp11/OrderingRules/SA1206CSharp11CodeFixProviderUnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp11/OrderingRules/SA1206CSharp11CodeFixProviderUnitTests.cs @@ -5,8 +5,8 @@ namespace StyleCop.Analyzers.Test.CSharp11.OrderingRules { using System.Threading; using System.Threading.Tasks; + using Microsoft.CodeAnalysis.Testing; using StyleCop.Analyzers.Test.CSharp10.OrderingRules; - using StyleCop.Analyzers.Test.Verifiers; using Xunit; using static StyleCop.Analyzers.Test.Verifiers.StyleCopCodeFixVerifier< StyleCop.Analyzers.OrderingRules.SA1206DeclarationKeywordsMustFollowOrder, @@ -43,17 +43,13 @@ internal struct SomeStruct public required int Field; }"; - await new CSharpTest() + DiagnosticResult[] expected = { - ReferenceAssemblies = GenericAnalyzerTest.ReferenceAssembliesNet70, - TestCode = testCode, - FixedCode = fixedCode, - ExpectedDiagnostics = - { - Diagnostic().WithLocation(0).WithArguments("public", "required"), - Diagnostic().WithLocation(1).WithArguments("public", "required"), - }, - }.RunAsync(CancellationToken.None).ConfigureAwait(false); + Diagnostic().WithLocation(0).WithArguments("public", "required"), + Diagnostic().WithLocation(1).WithArguments("public", "required"), + }; + + await VerifyCSharpFixAsync(testCode, expected, fixedCode, CancellationToken.None).ConfigureAwait(false); } } } diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp11/SpacingRules/SA1010CSharp11UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp11/SpacingRules/SA1010CSharp11UnitTests.cs index 58fb98289..017d102dc 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp11/SpacingRules/SA1010CSharp11UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp11/SpacingRules/SA1010CSharp11UnitTests.cs @@ -5,8 +5,8 @@ namespace StyleCop.Analyzers.Test.CSharp11.SpacingRules { using System.Threading; using System.Threading.Tasks; + using Microsoft.CodeAnalysis.Testing; using StyleCop.Analyzers.Test.CSharp10.SpacingRules; - using StyleCop.Analyzers.Test.Verifiers; using Xunit; using static StyleCop.Analyzers.Test.Verifiers.StyleCopCodeFixVerifier< @@ -40,11 +40,7 @@ public void TestMethod(List x) }} "; - await new CSharpTest() - { - ReferenceAssemblies = GenericAnalyzerTest.ReferenceAssembliesNet50, - TestCode = testCode, - }.RunAsync(CancellationToken.None).ConfigureAwait(false); + await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false); } } } diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp11/SpacingRules/SA1012CSharp11UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp11/SpacingRules/SA1012CSharp11UnitTests.cs index 7d9c7dd52..1c33a19f2 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp11/SpacingRules/SA1012CSharp11UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp11/SpacingRules/SA1012CSharp11UnitTests.cs @@ -5,8 +5,8 @@ namespace StyleCop.Analyzers.Test.CSharp11.SpacingRules { using System.Threading; using System.Threading.Tasks; + using Microsoft.CodeAnalysis.Testing; using StyleCop.Analyzers.Test.CSharp10.SpacingRules; - using StyleCop.Analyzers.Test.Verifiers; using Xunit; using static StyleCop.Analyzers.Test.Verifiers.StyleCopCodeFixVerifier< StyleCop.Analyzers.SpacingRules.SA1012OpeningBracesMustBeSpacedCorrectly, @@ -40,20 +40,16 @@ void M(string[] a) } "; - await new CSharpTest() + DiagnosticResult[] expected = { - ReferenceAssemblies = GenericAnalyzerTest.ReferenceAssembliesNet50, - TestCode = testCode, - ExpectedDiagnostics = - { - // Opening brace should not be preceded by a space - Diagnostic().WithLocation(0).WithArguments(" not", "preceded"), + // Opening brace should not be preceded by a space + Diagnostic().WithLocation(0).WithArguments(" not", "preceded"), - // Opening brace should be preceded by a space - Diagnostic().WithLocation(1).WithArguments(string.Empty, "preceded"), - }, - FixedCode = fixedCode, - }.RunAsync(CancellationToken.None).ConfigureAwait(false); + // Opening brace should be preceded by a space + Diagnostic().WithLocation(1).WithArguments(string.Empty, "preceded"), + }; + + await VerifyCSharpFixAsync(testCode, expected, fixedCode, CancellationToken.None).ConfigureAwait(false); } } } diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp8/OrderingRules/SA1202CSharp8UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp8/OrderingRules/SA1202CSharp8UnitTests.cs index 3607bac01..be723ed43 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp8/OrderingRules/SA1202CSharp8UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp8/OrderingRules/SA1202CSharp8UnitTests.cs @@ -3,9 +3,59 @@ namespace StyleCop.Analyzers.Test.CSharp8.OrderingRules { + using System.Threading; + using System.Threading.Tasks; using StyleCop.Analyzers.Test.CSharp7.OrderingRules; + using Xunit; + using static StyleCop.Analyzers.Test.Verifiers.StyleCopCodeFixVerifier< + StyleCop.Analyzers.OrderingRules.SA1202ElementsMustBeOrderedByAccess, + StyleCop.Analyzers.OrderingRules.ElementOrderCodeFixProvider>; public class SA1202CSharp8UnitTests : SA1202CSharp7UnitTests { + /// + /// Verifies that the analyzer will properly handle property access levels. + /// + /// A representing the asynchronous unit test. + [Fact] + public async Task TestPropertiesOfInterfaceAsync() + { + var testCode = @"public interface TestClass +{ + private string TestProperty1 { get { return """"; } set { } } + protected string {|#0:TestProperty2|} { get; set; } + protected internal string {|#1:TestProperty3|} { get; set; } + internal string {|#2:TestProperty4|} { get; set; } + public string {|#3:TestProperty5|} { get; set; } + string TestProperty0 { get; set; } +} +"; + + var fixedCode = @"public interface TestClass +{ + public string TestProperty5 { get; set; } + string TestProperty0 { get; set; } + internal string TestProperty4 { get; set; } + protected internal string TestProperty3 { get; set; } + protected string TestProperty2 { get; set; } + private string TestProperty1 { get { return """"; } set { } } +} +"; + + await new CSharpTest + { + TestCode = testCode, + ExpectedDiagnostics = + { + Diagnostic().WithLocation(0).WithArguments("protected", "private"), + Diagnostic().WithLocation(1).WithArguments("protected internal", "protected"), + Diagnostic().WithLocation(2).WithArguments("internal", "protected internal"), + Diagnostic().WithLocation(3).WithArguments("public", "internal"), + }, + FixedCode = fixedCode, + NumberOfIncrementalIterations = 5, + NumberOfFixAllIterations = 2, + }.RunAsync(CancellationToken.None).ConfigureAwait(false); + } } } diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp9/NamingRules/SA1300CSharp9UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp9/NamingRules/SA1300CSharp9UnitTests.cs index be42e3823..c0af19fad 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp9/NamingRules/SA1300CSharp9UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp9/NamingRules/SA1300CSharp9UnitTests.cs @@ -1,15 +1,12 @@ // Copyright (c) Tunnel Vision Laboratories, LLC. All Rights Reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. -#nullable disable - namespace StyleCop.Analyzers.Test.CSharp9.NamingRules { using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.Testing; using StyleCop.Analyzers.Test.CSharp8.NamingRules; - using StyleCop.Analyzers.Test.Verifiers; using Xunit; using static StyleCop.Analyzers.Test.Verifiers.StyleCopCodeFixVerifier< StyleCop.Analyzers.NamingRules.SA1300ElementMustBeginWithUpperCaseLetter, @@ -40,15 +37,7 @@ public R(int a, int b) } "; - var test = new CSharpTest() - { - ReferenceAssemblies = GenericAnalyzerTest.ReferenceAssembliesNet50, - TestCode = testCode, - FixedCode = fixedCode, - }; - var expectedDiagnostics = this.GetExpectedResultTestPositionalRecord1(); - test.TestState.ExpectedDiagnostics.AddRange(expectedDiagnostics); - await test.RunAsync(CancellationToken.None).ConfigureAwait(false); + await VerifyCSharpFixAsync(testCode, this.GetExpectedResultTestPositionalRecord1(), fixedCode, CancellationToken.None).ConfigureAwait(false); } [Fact] @@ -74,12 +63,7 @@ public R(int a, int b) } "; - await new CSharpTest() - { - ReferenceAssemblies = GenericAnalyzerTest.ReferenceAssembliesNet50, - TestCode = testCode, - FixedCode = fixedCode, - }.RunAsync(CancellationToken.None).ConfigureAwait(false); + await VerifyCSharpFixAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, fixedCode, CancellationToken.None).ConfigureAwait(false); } protected virtual DiagnosticResult[] GetExpectedResultTestPositionalRecord1() diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp9/NamingRules/SA1313CSharp9UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp9/NamingRules/SA1313CSharp9UnitTests.cs index 96a628d23..1ee1ef5ef 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp9/NamingRules/SA1313CSharp9UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp9/NamingRules/SA1313CSharp9UnitTests.cs @@ -1,14 +1,12 @@ // Copyright (c) Tunnel Vision Laboratories, LLC. All Rights Reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. -#nullable disable - namespace StyleCop.Analyzers.Test.CSharp9.NamingRules { using System.Threading; using System.Threading.Tasks; + using Microsoft.CodeAnalysis.Testing; using StyleCop.Analyzers.Test.CSharp8.NamingRules; - using StyleCop.Analyzers.Test.Verifiers; using Xunit; using static StyleCop.Analyzers.Test.Verifiers.StyleCopCodeFixVerifier< StyleCop.Analyzers.NamingRules.SA1313ParameterNamesMustBeginWithLowerCaseLetter, @@ -41,12 +39,7 @@ public R(int a, int b) } "; - await new CSharpTest() - { - ReferenceAssemblies = GenericAnalyzerTest.ReferenceAssembliesNet50, - TestCode = testCode, - FixedCode = fixedCode, - }.RunAsync(CancellationToken.None).ConfigureAwait(false); + await VerifyCSharpFixAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, fixedCode, CancellationToken.None).ConfigureAwait(false); } } } diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp9/ReadabilityRules/SA1101CSharp9UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp9/ReadabilityRules/SA1101CSharp9UnitTests.cs index 8e29d86dd..b9ac5d103 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp9/ReadabilityRules/SA1101CSharp9UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp9/ReadabilityRules/SA1101CSharp9UnitTests.cs @@ -5,8 +5,8 @@ namespace StyleCop.Analyzers.Test.CSharp9.ReadabilityRules { using System.Threading; using System.Threading.Tasks; + using Microsoft.CodeAnalysis.Testing; using StyleCop.Analyzers.Test.CSharp8.ReadabilityRules; - using StyleCop.Analyzers.Test.Verifiers; using Xunit; using static StyleCop.Analyzers.Test.Verifiers.StyleCopCodeFixVerifier< StyleCop.Analyzers.ReadabilityRules.SA1101PrefixLocalCallsWithThis, @@ -31,11 +31,7 @@ public A UpdateA(A value) } }"; - await new CSharpTest() - { - ReferenceAssemblies = GenericAnalyzerTest.ReferenceAssembliesNet50, - TestCode = testCode, - }.RunAsync(CancellationToken.None).ConfigureAwait(false); + await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false); } } } diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp9/SpacingRules/SA1023CSharp9UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp9/SpacingRules/SA1023CSharp9UnitTests.cs index 3acea4d49..2ca8514ae 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp9/SpacingRules/SA1023CSharp9UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp9/SpacingRules/SA1023CSharp9UnitTests.cs @@ -1,14 +1,12 @@ // Copyright (c) Tunnel Vision Laboratories, LLC. All Rights Reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. -#nullable disable - namespace StyleCop.Analyzers.Test.CSharp9.SpacingRules { using System.Threading; using System.Threading.Tasks; + using Microsoft.CodeAnalysis.Testing; using StyleCop.Analyzers.Test.CSharp8.SpacingRules; - using StyleCop.Analyzers.Test.Verifiers; using Xunit; using static StyleCop.Analyzers.SpacingRules.SA1023DereferenceAndAccessOfSymbolsMustBeSpacedCorrectly; using static StyleCop.Analyzers.Test.Verifiers.StyleCopCodeFixVerifier< @@ -68,21 +66,17 @@ public async Task TestFunctionPointerTypeInvalidSpacingAsync() } "; - await new CSharpTest() + DiagnosticResult[] expected = { - ReferenceAssemblies = GenericAnalyzerTest.ReferenceAssembliesNet50, - TestCode = testCode, - FixedCode = fixedCode, - ExpectedDiagnostics = - { - Diagnostic(DescriptorNotPreceded).WithLocation(0), - Diagnostic(DescriptorNotFollowed).WithLocation(1), - Diagnostic(DescriptorNotPreceded).WithLocation(2), - Diagnostic(DescriptorFollowed).WithLocation(3), - Diagnostic(DescriptorNotPreceded).WithLocation(4), - Diagnostic(DescriptorFollowed).WithLocation(5), - }, - }.RunAsync().ConfigureAwait(false); + Diagnostic(DescriptorNotPreceded).WithLocation(0), + Diagnostic(DescriptorNotFollowed).WithLocation(1), + Diagnostic(DescriptorNotPreceded).WithLocation(2), + Diagnostic(DescriptorFollowed).WithLocation(3), + Diagnostic(DescriptorNotPreceded).WithLocation(4), + Diagnostic(DescriptorFollowed).WithLocation(5), + }; + + await VerifyCSharpFixAsync(testCode, expected, fixedCode, CancellationToken.None).ConfigureAwait(false); } } } diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test/Helpers/CommonMemberData.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test/Helpers/CommonMemberData.cs index 660ac0be6..3920ac2f4 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test/Helpers/CommonMemberData.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test/Helpers/CommonMemberData.cs @@ -31,6 +31,37 @@ public static IEnumerable DataTypeDeclarationKeywords } } + public static IEnumerable ReferenceTypeDeclarationKeywords + { + get + { + yield return new[] { "class" }; + + if (LightupHelpers.SupportsCSharp9) + { + yield return new[] { "record" }; + } + + if (LightupHelpers.SupportsCSharp10) + { + yield return new[] { "record class" }; + } + } + } + + public static IEnumerable ValueTypeDeclarationKeywords + { + get + { + yield return new[] { "struct" }; + + if (LightupHelpers.SupportsCSharp10) + { + yield return new[] { "record struct" }; + } + } + } + public static IEnumerable RecordTypeDeclarationKeywords { get diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test/MaintainabilityRules/DebugMessagesUnitTestsBase.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test/MaintainabilityRules/DebugMessagesUnitTestsBase.cs index 0c96f5712..49e91a050 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test/MaintainabilityRules/DebugMessagesUnitTestsBase.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test/MaintainabilityRules/DebugMessagesUnitTestsBase.cs @@ -6,6 +6,7 @@ namespace StyleCop.Analyzers.Test.MaintainabilityRules { using System.Collections.Generic; + using System.Diagnostics; using System.Linq; using System.Text; using System.Threading; @@ -14,6 +15,7 @@ namespace StyleCop.Analyzers.Test.MaintainabilityRules using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Testing; using Microsoft.CodeAnalysis.Text; + using StyleCop.Analyzers.Lightup; using StyleCop.Analyzers.Test.Verifiers; using Xunit; @@ -98,10 +100,23 @@ public async Task TestConstantMessage_Inline_PassWrongTypeAsync() { var startLinePosition = new LinePosition(5, 15 + this.MethodName.Length + this.InitialArguments.Sum(i => i.Length + ", ".Length)); var endLinePosition = new LinePosition(startLinePosition.Line, startLinePosition.Character + 1); - DiagnosticResult[] expected = + DiagnosticResult[] expected; + if (LightupHelpers.SupportsCSharp11 && this.MethodName == nameof(Debug.Assert)) { - DiagnosticResult.CompilerError("CS1503").WithSpan(new FileLinePositionSpan("/0/Test0.cs", startLinePosition, endLinePosition)).WithMessage($"Argument {1 + this.InitialArguments.Count()}: cannot convert from 'int' to 'string'"), - }; + // For some reason this case wants to bind to Debug.Assert(bool, ref Debug.AssertInterpolatedStringHandler) + expected = new[] + { + DiagnosticResult.CompilerError("CS1620").WithSpan(new FileLinePositionSpan("/0/Test0.cs", startLinePosition, endLinePosition)).WithMessage($"Argument {1 + this.InitialArguments.Count()} must be passed with the 'ref' keyword"), + }; + } + else + { + var expectedType = LightupHelpers.SupportsCSharp8 ? "string?" : "string"; + expected = new[] + { + DiagnosticResult.CompilerError("CS1503").WithSpan(new FileLinePositionSpan("/0/Test0.cs", startLinePosition, endLinePosition)).WithMessage($"Argument {1 + this.InitialArguments.Count()}: cannot convert from 'int' to '{expectedType}'"), + }; + } await this.TestConstantMessage_Inline_PassExecuterAsync("3", expected).ConfigureAwait(false); } diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1201UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1201UnitTests.cs index f39577e06..745de4f8b 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1201UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1201UnitTests.cs @@ -1,13 +1,14 @@ // Copyright (c) Tunnel Vision Laboratories, LLC. All Rights Reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. -#nullable disable - namespace StyleCop.Analyzers.Test.OrderingRules { + using System.Collections.Generic; + using System.Linq; using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.Testing; + using StyleCop.Analyzers.Test.Helpers; using Xunit; using static StyleCop.Analyzers.Test.Verifiers.StyleCopCodeFixVerifier< @@ -16,6 +17,20 @@ namespace StyleCop.Analyzers.Test.OrderingRules public class SA1201UnitTests { + public static IEnumerable ValueTypesAndReferenceTypes + { + get + { + foreach (var valueTypeKeyword in CommonMemberData.ValueTypeDeclarationKeywords) + { + foreach (var referenceTypeKeyword in CommonMemberData.ReferenceTypeDeclarationKeywords) + { + yield return new object[] { valueTypeKeyword.Single(), referenceTypeKeyword.Single() }; + } + } + } + } + [Fact] public async Task TestOuterOrderCorrectOrderAsync() { @@ -52,6 +67,35 @@ public struct FooStruct { } await VerifyCSharpDiagnosticAsync("namespace OuterNamespace { " + testCode + " }", expected, CancellationToken.None).ConfigureAwait(false); } + [Theory] + [MemberData(nameof(ValueTypesAndReferenceTypes))] + public async Task TestClassBeforeStructAsync( + string structKeyword, + string classKeyword) + { + string testCode = $@" +public {classKeyword} FooClass {{ }} +public {structKeyword} {{|#0:FooStruct|}} {{ }} +"; + string fixedCode = $@"public {structKeyword} FooStruct {{ }} + +public {classKeyword} FooClass {{ }} +"; + + var reportedClassKind = classKeyword switch + { + "record class" => "record", + _ => classKeyword, + }; + + var expected = new[] + { + Diagnostic().WithLocation(0).WithArguments(structKeyword, reportedClassKind), + }; + + await VerifyCSharpFixAsync(testCode, expected, fixedCode, CancellationToken.None).ConfigureAwait(false); + } + [Fact] public async Task TestTypeMemberOrderCorrectOrderClassAsync() { diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1202UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1202UnitTests.cs index 9c453b20f..8d27bfcd2 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1202UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test/OrderingRules/SA1202UnitTests.cs @@ -9,6 +9,7 @@ namespace StyleCop.Analyzers.Test.OrderingRules using System.Threading.Tasks; using Microsoft.CodeAnalysis.Testing; using StyleCop.Analyzers.OrderingRules; + using StyleCop.Analyzers.Test.Helpers; using Xunit; using static StyleCop.Analyzers.Test.Verifiers.StyleCopCodeFixVerifier< StyleCop.Analyzers.OrderingRules.SA1202ElementsMustBeOrderedByAccess, @@ -103,20 +104,22 @@ private class TestClass10 { } } /// - /// Verifies that the analyzer will properly handle class access levels. + /// Verifies that the analyzer will properly handle type access levels. /// + /// The keyword used to declare the type. /// A representing the asynchronous unit test. - [Fact] - public async Task TestClassOrderingAsync() + [Theory] + [MemberData(nameof(CommonMemberData.TypeDeclarationKeywords), MemberType = typeof(CommonMemberData))] + public async Task TestTypeOrderingAsync(string keyword) { - var testCode = @"internal class TestClass1 { } -public class TestClass2 { } + var testCode = $@"internal {keyword} TestClass1 {{ }} +public {keyword} {{|#0:TestClass2|}} {{ }} "; - var expected = Diagnostic().WithLocation(2, 14).WithArguments("public", "internal"); + var expected = Diagnostic().WithLocation(0).WithArguments("public", "internal"); - var fixedCode = @"public class TestClass2 { } -internal class TestClass1 { } + var fixedCode = $@"public {keyword} TestClass2 {{ }} +internal {keyword} TestClass1 {{ }} "; await VerifyCSharpFixAsync(testCode, expected, fixedCode, CancellationToken.None).ConfigureAwait(false); @@ -125,12 +128,14 @@ internal class TestClass1 { } /// /// Verifies that the analyzer will properly handle interfaces before classes. /// + /// The keyword used to declare the type. /// A representing the asynchronous unit test. - [Fact] - public async Task TestInternalInterfaceBeforePublicClassAsync() + [Theory] + [MemberData(nameof(CommonMemberData.DataTypeDeclarationKeywords), MemberType = typeof(CommonMemberData))] + public async Task TestInternalInterfaceBeforePublicClassAsync(string keyword) { - var testCode = @"internal interface ITestInterface { } -public class TestClass2 { } + var testCode = $@"internal interface ITestInterface {{ }} +public {keyword} TestClass2 {{ }} "; await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false); @@ -139,18 +144,20 @@ public class TestClass2 { } /// /// Verifies that the analyzer will properly handle property access levels. /// + /// The keyword used to declare the type. /// A representing the asynchronous unit test. - [Fact] - public async Task TestPropertiesAsync() + [Theory] + [MemberData(nameof(CommonMemberData.ReferenceTypeDeclarationKeywords), MemberType = typeof(CommonMemberData))] + public async Task TestPropertiesOfClassAsync(string keyword) { - var testCode = @"public class TestClass -{ - private string TestProperty1 { get; set; } - protected string TestProperty2 { get; set; } - protected internal string TestProperty3 { get; set; } - internal string TestProperty4 { get; set; } - public string TestProperty5 { get; set; } -} + var testCode = $@"public {keyword} TestClass +{{ + private string TestProperty1 {{ get; set; }} + protected string TestProperty2 {{ get; set; }} + protected internal string TestProperty3 {{ get; set; }} + internal string TestProperty4 {{ get; set; }} + public string TestProperty5 {{ get; set; }} +}} "; DiagnosticResult[] expected = @@ -161,14 +168,48 @@ public async Task TestPropertiesAsync() Diagnostic().WithLocation(7, 19).WithArguments("public", "internal"), }; - var fixedCode = @"public class TestClass -{ - public string TestProperty5 { get; set; } - internal string TestProperty4 { get; set; } - protected internal string TestProperty3 { get; set; } - protected string TestProperty2 { get; set; } - private string TestProperty1 { get; set; } -} + var fixedCode = $@"public {keyword} TestClass +{{ + public string TestProperty5 {{ get; set; }} + internal string TestProperty4 {{ get; set; }} + protected internal string TestProperty3 {{ get; set; }} + protected string TestProperty2 {{ get; set; }} + private string TestProperty1 {{ get; set; }} +}} +"; + + await VerifyCSharpFixAsync(testCode, expected, fixedCode, CancellationToken.None).ConfigureAwait(false); + } + + /// + /// Verifies that the analyzer will properly handle property access levels. + /// + /// The keyword used to declare the type. + /// A representing the asynchronous unit test. + [Theory] + [MemberData(nameof(CommonMemberData.ValueTypeDeclarationKeywords), MemberType = typeof(CommonMemberData))] + public async Task TestPropertiesOfStructAsync(string keyword) + { + var testCode = $@"public {keyword} TestClass +{{ + private string TestProperty1 {{ get; set; }} + internal string {{|#0:TestProperty4|}} {{ get; set; }} + public string {{|#1:TestProperty5|}} {{ get; set; }} +}} +"; + + DiagnosticResult[] expected = + { + Diagnostic().WithLocation(0).WithArguments("internal", "private"), + Diagnostic().WithLocation(1).WithArguments("public", "internal"), + }; + + var fixedCode = $@"public {keyword} TestClass +{{ + public string TestProperty5 {{ get; set; }} + internal string TestProperty4 {{ get; set; }} + private string TestProperty1 {{ get; set; }} +}} "; await VerifyCSharpFixAsync(testCode, expected, fixedCode, CancellationToken.None).ConfigureAwait(false); diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test/SpacingRules/SA1009UnitTests.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test/SpacingRules/SA1009UnitTests.cs index 6331f77ed..52871b857 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test/SpacingRules/SA1009UnitTests.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test/SpacingRules/SA1009UnitTests.cs @@ -153,29 +153,13 @@ public void Method(int param1, int param2) await VerifyCSharpFixAsync(testCode, expected, fixedCode, CancellationToken.None).ConfigureAwait(false); } - [Fact] - public async Task TestAttributeWithParametersAndNoSpaceAfterClosingParenthesisAsync() - { - const string testCode = @"using System; -using System.Security.Permissions; - -[PermissionSet(SecurityAction.LinkDemand, Name = ""FullTrust"")] -public class Foo -{ - public void Method(int param1, int param2) - { - } -}"; - await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false); - } - [Fact] public async Task TestAttributeWithParametersAndSpaceAfterClosingParenthesisAsync() { const string testCode = @"using System; -using System.Security.Permissions; +using System.Runtime.InteropServices; -[PermissionSet(SecurityAction.LinkDemand, Name = ""FullTrust"") ] +[StructLayout(LayoutKind.Auto, CharSet = CharSet.Auto{|#0:)|} ] public class Foo { public void Method(int param1, int param2) @@ -184,9 +168,9 @@ public void Method(int param1, int param2) }"; const string fixedCode = @"using System; -using System.Security.Permissions; +using System.Runtime.InteropServices; -[PermissionSet(SecurityAction.LinkDemand, Name = ""FullTrust"")] +[StructLayout(LayoutKind.Auto, CharSet = CharSet.Auto)] public class Foo { public void Method(int param1, int param2) @@ -194,7 +178,7 @@ public void Method(int param1, int param2) } }"; - DiagnosticResult expected = Diagnostic(DescriptorNotFollowed).WithLocation(4, 61); + DiagnosticResult expected = Diagnostic(DescriptorNotFollowed).WithLocation(0); await VerifyCSharpFixAsync(testCode, expected, fixedCode, CancellationToken.None).ConfigureAwait(false); } diff --git a/StyleCop.Analyzers/StyleCop.Analyzers.Test/Verifiers/GenericAnalyzerTest.cs b/StyleCop.Analyzers/StyleCop.Analyzers.Test/Verifiers/GenericAnalyzerTest.cs index d3cd7a567..dabf87fbc 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers.Test/Verifiers/GenericAnalyzerTest.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers.Test/Verifiers/GenericAnalyzerTest.cs @@ -1,8 +1,6 @@ // Copyright (c) Tunnel Vision Laboratories, LLC. All Rights Reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. -#nullable disable - namespace StyleCop.Analyzers.Test.Verifiers { using System; @@ -13,17 +11,12 @@ namespace StyleCop.Analyzers.Test.Verifiers using Microsoft.CodeAnalysis.Host.Mef; using Microsoft.CodeAnalysis.Testing; using Microsoft.VisualStudio.Composition; + using StyleCop.Analyzers.Lightup; internal static class GenericAnalyzerTest { internal static readonly ReferenceAssemblies ReferenceAssemblies; - internal static readonly ReferenceAssemblies ReferenceAssembliesNet50; - - internal static readonly ReferenceAssemblies ReferenceAssembliesNet60; - - internal static readonly ReferenceAssemblies ReferenceAssembliesNet70; - private static readonly Lazy ExportProviderFactory; static GenericAnalyzerTest() @@ -38,19 +31,34 @@ static GenericAnalyzerTest() _ => throw new InvalidOperationException("Unknown version."), }; - ReferenceAssemblies = ReferenceAssemblies.Default.AddPackages(ImmutableArray.Create( + // Use appropriate default reference assemblies per the support matrix: + // https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/configure-language-version + ReferenceAssemblies defaultReferenceAssemblies; + if (LightupHelpers.SupportsCSharp11) + { + defaultReferenceAssemblies = ReferenceAssemblies.Net.Net70; + } + else if (LightupHelpers.SupportsCSharp10) + { + defaultReferenceAssemblies = ReferenceAssemblies.Net.Net60; + } + else if (LightupHelpers.SupportsCSharp9) + { + defaultReferenceAssemblies = ReferenceAssemblies.Net.Net50; + } + else if (LightupHelpers.SupportsCSharp8) + { + defaultReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp30; + } + else + { + defaultReferenceAssemblies = ReferenceAssemblies.Default; + } + + ReferenceAssemblies = defaultReferenceAssemblies.AddPackages(ImmutableArray.Create( new PackageIdentity("Microsoft.CodeAnalysis.CSharp", codeAnalysisTestVersion), new PackageIdentity("System.ValueTuple", "4.5.0"))); - ReferenceAssembliesNet50 = ReferenceAssemblies.Net.Net50.AddPackages(ImmutableArray.Create( - new PackageIdentity("Microsoft.CodeAnalysis.CSharp", codeAnalysisTestVersion))); - - ReferenceAssembliesNet60 = ReferenceAssemblies.Net.Net60.AddPackages(ImmutableArray.Create( - new PackageIdentity("Microsoft.CodeAnalysis.CSharp", codeAnalysisTestVersion))); - - ReferenceAssembliesNet70 = ReferenceAssemblies.Net.Net70.AddPackages(ImmutableArray.Create( - new PackageIdentity("Microsoft.CodeAnalysis.CSharp", codeAnalysisTestVersion))); - ExportProviderFactory = new Lazy( () => { diff --git a/StyleCop.Analyzers/StyleCop.Analyzers/Helpers/MemberOrderHelper.cs b/StyleCop.Analyzers/StyleCop.Analyzers/Helpers/MemberOrderHelper.cs index 12a1a3f4f..049c1ca10 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers/Helpers/MemberOrderHelper.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers/Helpers/MemberOrderHelper.cs @@ -1,8 +1,6 @@ // Copyright (c) Tunnel Vision Laboratories, LLC. All Rights Reserved. // Licensed under the MIT License. See LICENSE in the project root for license information. -#nullable disable - namespace StyleCop.Analyzers.Helpers { using System; @@ -16,7 +14,7 @@ namespace StyleCop.Analyzers.Helpers /// /// Helper for dealing with member priority. /// - internal struct MemberOrderHelper + internal readonly struct MemberOrderHelper { private static readonly ImmutableArray TypeMemberOrder = ImmutableArray.Create( SyntaxKind.ClassDeclaration, @@ -44,8 +42,13 @@ internal MemberOrderHelper(MemberDeclarationSyntax member, ImmutableArray SyntaxKind.EventDeclaration, + SyntaxKindEx.RecordDeclaration => SyntaxKind.ClassDeclaration, + SyntaxKindEx.RecordStructDeclaration => SyntaxKind.StructDeclaration, + var kind => kind, + }; this.Priority = 0; foreach (OrderingTrait trait in elementOrder) @@ -158,6 +161,10 @@ internal static AccessLevel GetAccessLevelForOrdering(SyntaxNode member, SyntaxT { accessibility = AccessLevel.Internal; } + else if (member.Parent.IsKind(SyntaxKind.InterfaceDeclaration)) + { + accessibility = AccessLevel.Public; + } else { accessibility = AccessLevel.Private; diff --git a/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1202ElementsMustBeOrderedByAccess.cs b/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1202ElementsMustBeOrderedByAccess.cs index a7a3b211d..2a94c3572 100644 --- a/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1202ElementsMustBeOrderedByAccess.cs +++ b/StyleCop.Analyzers/StyleCop.Analyzers/OrderingRules/SA1202ElementsMustBeOrderedByAccess.cs @@ -53,9 +53,6 @@ internal class SA1202ElementsMustBeOrderedByAccess : DiagnosticAnalyzer private static readonly DiagnosticDescriptor Descriptor = new DiagnosticDescriptor(DiagnosticId, Title, MessageFormat, AnalyzerCategory.OrderingRules, DiagnosticSeverity.Warning, AnalyzerConstants.EnabledByDefault, Description, HelpLink); - private static readonly ImmutableArray TypeDeclarationKinds = - ImmutableArray.Create(SyntaxKind.ClassDeclaration, SyntaxKind.StructDeclaration); - private static readonly ImmutableHashSet MemberKinds = ImmutableHashSet.Create( SyntaxKind.DelegateDeclaration, SyntaxKind.EnumDeclaration, @@ -69,7 +66,9 @@ internal class SA1202ElementsMustBeOrderedByAccess : DiagnosticAnalyzer SyntaxKind.IndexerDeclaration, SyntaxKind.MethodDeclaration, SyntaxKind.ConversionOperatorDeclaration, - SyntaxKind.OperatorDeclaration); + SyntaxKind.OperatorDeclaration, + SyntaxKindEx.RecordDeclaration, + SyntaxKindEx.RecordStructDeclaration); private static readonly Action CompilationUnitAction = HandleCompilationUnit; private static readonly Action BaseNamespaceDeclarationAction = HandleBaseNamespaceDeclaration; @@ -89,7 +88,7 @@ public override void Initialize(AnalysisContext context) { context.RegisterSyntaxNodeAction(CompilationUnitAction, SyntaxKind.CompilationUnit); context.RegisterSyntaxNodeAction(BaseNamespaceDeclarationAction, SyntaxKinds.BaseNamespaceDeclaration); - context.RegisterSyntaxNodeAction(TypeDeclarationAction, TypeDeclarationKinds); + context.RegisterSyntaxNodeAction(TypeDeclarationAction, SyntaxKinds.TypeDeclaration); }); }