From 3162916c8545f9405f010c639ffe249c7c7e3d36 Mon Sep 17 00:00:00 2001 From: Martin Strecker Date: Thu, 13 Oct 2022 18:29:41 +0200 Subject: [PATCH] EncloseInNamespace for ConcurrentAnalysis --- .../Rules/AsyncVoidMethodTest.cs | 1 - ...erInformationParametersShouldBeLastTest.cs | 1 - .../Rules/ClassAndMethodNameTest.cs | 1 - .../Rules/CognitiveComplexityTest.cs | 1 - .../Rules/CommentedOutCodeTest.cs | 3 +- .../Rules/EmptyNamespaceTest.cs | 2 -- ...onMethodShouldBeInSeparateNamespaceTest.cs | 1 - .../RequestsWithExcessiveLengthTest.cs | 1 - .../Rules/SqlKeywordsDelimitedBySpaceTest.cs | 2 -- .../StringLiteralShouldNotBeDuplicatedTest.cs | 1 - .../LocksReleasedAllPathsTest.cs | 3 +- .../Rules/UnnecessaryUsingsTest.cs | 2 +- .../TestFramework/Tests/VerifierTest.cs | 11 +++--- .../TestFramework/Verifier.cs | 36 ++++++++++++++++++- 14 files changed, 45 insertions(+), 21 deletions(-) diff --git a/analyzers/tests/SonarAnalyzer.UnitTest/Rules/AsyncVoidMethodTest.cs b/analyzers/tests/SonarAnalyzer.UnitTest/Rules/AsyncVoidMethodTest.cs index 11fd4571cf9..5e7bc11b77f 100644 --- a/analyzers/tests/SonarAnalyzer.UnitTest/Rules/AsyncVoidMethodTest.cs +++ b/analyzers/tests/SonarAnalyzer.UnitTest/Rules/AsyncVoidMethodTest.cs @@ -60,7 +60,6 @@ public void AsyncVoidMethod_MsTestV2_CSharp11(string testFwkVersion) => // The first version of the framework is not compatible with Net 7 so we need to test only v2 with C#11 features .WithOptions(ParseOptionsHelper.FromCSharp11) .AddReferences(NuGetMetadataReference.MSTestTestFramework(testFwkVersion)) - .WithConcurrentAnalysis(false) .Verify(); #endif diff --git a/analyzers/tests/SonarAnalyzer.UnitTest/Rules/CallerInformationParametersShouldBeLastTest.cs b/analyzers/tests/SonarAnalyzer.UnitTest/Rules/CallerInformationParametersShouldBeLastTest.cs index e528fa18f4d..7fc6feb9870 100644 --- a/analyzers/tests/SonarAnalyzer.UnitTest/Rules/CallerInformationParametersShouldBeLastTest.cs +++ b/analyzers/tests/SonarAnalyzer.UnitTest/Rules/CallerInformationParametersShouldBeLastTest.cs @@ -51,7 +51,6 @@ public void CallerInformationParametersShouldBeLast_CSharp11() => public void CallerInformationParametersShouldBeLastInvalidSyntax() => builder.AddPaths("CallerInformationParametersShouldBeLastInvalidSyntax.cs") .WithErrorBehavior(CompilationErrorBehavior.Ignore) - .WithConcurrentAnalysis(false) .Verify(); } } diff --git a/analyzers/tests/SonarAnalyzer.UnitTest/Rules/ClassAndMethodNameTest.cs b/analyzers/tests/SonarAnalyzer.UnitTest/Rules/ClassAndMethodNameTest.cs index b735f933a2c..cef570e60ba 100644 --- a/analyzers/tests/SonarAnalyzer.UnitTest/Rules/ClassAndMethodNameTest.cs +++ b/analyzers/tests/SonarAnalyzer.UnitTest/Rules/ClassAndMethodNameTest.cs @@ -32,7 +32,6 @@ public class ClassAndMethodNameTest public void ClassAndMethodName_CS() => builderCS.AddPaths("ClassAndMethodName.cs", "ClassAndMethodName.Partial.cs") .AddReferences(MetadataReferenceFacade.NETStandard21) - .WithConcurrentAnalysis(false) .WithOptions(ParseOptionsHelper.FromCSharp8) .Verify(); diff --git a/analyzers/tests/SonarAnalyzer.UnitTest/Rules/CognitiveComplexityTest.cs b/analyzers/tests/SonarAnalyzer.UnitTest/Rules/CognitiveComplexityTest.cs index 4828221599e..913a07b7884 100644 --- a/analyzers/tests/SonarAnalyzer.UnitTest/Rules/CognitiveComplexityTest.cs +++ b/analyzers/tests/SonarAnalyzer.UnitTest/Rules/CognitiveComplexityTest.cs @@ -55,7 +55,6 @@ public void CognitiveComplexity_CS_CSharp9() => public void CognitiveComplexity_CS_CSharp10() => builderCS.AddPaths("CognitiveComplexity.CSharp10.cs") .WithOptions(ParseOptionsHelper.FromCSharp10) - .WithConcurrentAnalysis(false) .Verify(); [TestMethod] diff --git a/analyzers/tests/SonarAnalyzer.UnitTest/Rules/CommentedOutCodeTest.cs b/analyzers/tests/SonarAnalyzer.UnitTest/Rules/CommentedOutCodeTest.cs index cef7e4b27ae..fa8bc42ea32 100644 --- a/analyzers/tests/SonarAnalyzer.UnitTest/Rules/CommentedOutCodeTest.cs +++ b/analyzers/tests/SonarAnalyzer.UnitTest/Rules/CommentedOutCodeTest.cs @@ -30,7 +30,7 @@ public class CommentedOutCodeTest [TestMethod] public void CommentedOutCode_Nonconcurrent() => - builder.AddPaths("CommentedOutCode_Nonconcurrent.cs").WithConcurrentAnalysis(false).Verify(); + builder.AddPaths("CommentedOutCode_Nonconcurrent.cs").Verify(); [TestMethod] public void CommentedOutCode() => @@ -39,7 +39,6 @@ public void CommentedOutCode() => [TestMethod] public void CommentedOutCode_NoDocumentation() => builder.AddPaths("CommentedOutCode.cs") - .WithConcurrentAnalysis(false) .WithOptions(ImmutableArray.Create(new CSharpParseOptions(documentationMode: DocumentationMode.None))) .Verify(); } diff --git a/analyzers/tests/SonarAnalyzer.UnitTest/Rules/EmptyNamespaceTest.cs b/analyzers/tests/SonarAnalyzer.UnitTest/Rules/EmptyNamespaceTest.cs index cfd82cd2a83..107361a501d 100644 --- a/analyzers/tests/SonarAnalyzer.UnitTest/Rules/EmptyNamespaceTest.cs +++ b/analyzers/tests/SonarAnalyzer.UnitTest/Rules/EmptyNamespaceTest.cs @@ -37,7 +37,6 @@ public void EmptyNamespace() => public void EmptyNamespace_CSharp10() => builder.AddPaths("EmptyNamespace.CSharp10.Empty.cs", "EmptyNamespace.CSharp10.NotEmpty.cs") .WithOptions(ParseOptionsHelper.FromCSharp10) - .WithConcurrentAnalysis(false) .Verify(); [TestMethod] @@ -45,7 +44,6 @@ public void EmptyNamespace_CSharp10_CodeFix() => builder.AddPaths("EmptyNamespace.CSharp10.Empty.cs") .WithCodeFix() .WithOptions(ParseOptionsHelper.FromCSharp10) - .WithAutogenerateConcurrentFiles(false) .WithCodeFixedPaths("EmptyNamespace.CSharp10.Fixed.cs") .VerifyCodeFix(); diff --git a/analyzers/tests/SonarAnalyzer.UnitTest/Rules/ExtensionMethodShouldBeInSeparateNamespaceTest.cs b/analyzers/tests/SonarAnalyzer.UnitTest/Rules/ExtensionMethodShouldBeInSeparateNamespaceTest.cs index db0905ebe44..679e2cfed25 100644 --- a/analyzers/tests/SonarAnalyzer.UnitTest/Rules/ExtensionMethodShouldBeInSeparateNamespaceTest.cs +++ b/analyzers/tests/SonarAnalyzer.UnitTest/Rules/ExtensionMethodShouldBeInSeparateNamespaceTest.cs @@ -43,7 +43,6 @@ public void ExtensionMethodShouldBeInSeparateNamespace_CSharp9() => public void ExtensionMethodShouldBeInSeparateNamespace_CSharp10() => builder .AddPaths("ExtensionMethodShouldBeInSeparateNamespace.CSharp10.cs") - .WithConcurrentAnalysis(false) .WithOptions(ParseOptionsHelper.FromCSharp10) .Verify(); diff --git a/analyzers/tests/SonarAnalyzer.UnitTest/Rules/Hotspots/RequestsWithExcessiveLengthTest.cs b/analyzers/tests/SonarAnalyzer.UnitTest/Rules/Hotspots/RequestsWithExcessiveLengthTest.cs index 3ddefcd84d8..8330680033e 100644 --- a/analyzers/tests/SonarAnalyzer.UnitTest/Rules/Hotspots/RequestsWithExcessiveLengthTest.cs +++ b/analyzers/tests/SonarAnalyzer.UnitTest/Rules/Hotspots/RequestsWithExcessiveLengthTest.cs @@ -64,7 +64,6 @@ public void RequestsWithExcessiveLength_Csharp10() => public void RequestsWithExcessiveLength_Csharp11() => builderCS .AddPaths(@"RequestsWithExcessiveLength.CSharp11.cs") - .WithConcurrentAnalysis(false) .WithOptions(ParseOptionsHelper.FromCSharp11).Verify(); #endif diff --git a/analyzers/tests/SonarAnalyzer.UnitTest/Rules/SqlKeywordsDelimitedBySpaceTest.cs b/analyzers/tests/SonarAnalyzer.UnitTest/Rules/SqlKeywordsDelimitedBySpaceTest.cs index af068a9225b..38a210c7765 100644 --- a/analyzers/tests/SonarAnalyzer.UnitTest/Rules/SqlKeywordsDelimitedBySpaceTest.cs +++ b/analyzers/tests/SonarAnalyzer.UnitTest/Rules/SqlKeywordsDelimitedBySpaceTest.cs @@ -51,14 +51,12 @@ public void SqlKeywordsDelimitedBySpace_DefaultNamespace() => public void SqlKeywordsDelimitedBySpace_CSharp10_GlobalUsings() => builder.AddPaths("SqlKeywordsDelimitedBySpace.CSharp10.GlobalUsing.cs", "SqlKeywordsDelimitedBySpace.CSharp10.GlobalUsingConsumer.cs") .WithOptions(ParseOptionsHelper.FromCSharp10) - .WithConcurrentAnalysis(false) .Verify(); [TestMethod] public void SqlKeywordsDelimitedBySpace_CSharp10_FileScopesNamespace() => builder.AddPaths("SqlKeywordsDelimitedBySpace.CSharp10.FileScopedNamespaceDeclaration.cs") .WithOptions(ParseOptionsHelper.FromCSharp10) - .WithConcurrentAnalysis(false) .Verify(); [TestMethod] diff --git a/analyzers/tests/SonarAnalyzer.UnitTest/Rules/StringLiteralShouldNotBeDuplicatedTest.cs b/analyzers/tests/SonarAnalyzer.UnitTest/Rules/StringLiteralShouldNotBeDuplicatedTest.cs index 06745366bf0..a93c3e1fdc9 100644 --- a/analyzers/tests/SonarAnalyzer.UnitTest/Rules/StringLiteralShouldNotBeDuplicatedTest.cs +++ b/analyzers/tests/SonarAnalyzer.UnitTest/Rules/StringLiteralShouldNotBeDuplicatedTest.cs @@ -64,7 +64,6 @@ public void StringLiteralShouldNotBeDuplicated_CSharp11() => public void StringLiteralShouldNotBeDuplicated_Attributes_CS() => new VerifierBuilder().AddAnalyzer(() => new CS.StringLiteralShouldNotBeDuplicated { Threshold = 2 }) .AddPaths("StringLiteralShouldNotBeDuplicated_Attributes.cs") - .WithConcurrentAnalysis(false) .Verify(); [TestMethod] diff --git a/analyzers/tests/SonarAnalyzer.UnitTest/Rules/SymbolicExecution/LocksReleasedAllPathsTest.cs b/analyzers/tests/SonarAnalyzer.UnitTest/Rules/SymbolicExecution/LocksReleasedAllPathsTest.cs index d0bb2310668..bd6a3547bdd 100644 --- a/analyzers/tests/SonarAnalyzer.UnitTest/Rules/SymbolicExecution/LocksReleasedAllPathsTest.cs +++ b/analyzers/tests/SonarAnalyzer.UnitTest/Rules/SymbolicExecution/LocksReleasedAllPathsTest.cs @@ -87,7 +87,6 @@ private static VerifierBuilder CreateVerifier(Func createCon .AddAnalyzer(createConfiguredAnalyzer) .WithOnlyDiagnostics(onlyDiagnostics) .AddReferences(MetadataReferenceFacade.SystemThreading) - .WithBasePath(@"SymbolicExecution\Roslyn") - .WithConcurrentAnalysis(false); + .WithBasePath(@"SymbolicExecution\Roslyn"); } } diff --git a/analyzers/tests/SonarAnalyzer.UnitTest/Rules/UnnecessaryUsingsTest.cs b/analyzers/tests/SonarAnalyzer.UnitTest/Rules/UnnecessaryUsingsTest.cs index 358a7f15641..64e66859275 100644 --- a/analyzers/tests/SonarAnalyzer.UnitTest/Rules/UnnecessaryUsingsTest.cs +++ b/analyzers/tests/SonarAnalyzer.UnitTest/Rules/UnnecessaryUsingsTest.cs @@ -42,7 +42,7 @@ public void UnnecessaryUsings_CSharp10_GlobalUsings() => [TestMethod] public void UnnecessaryUsings_CSharp10_FileScopedNamespace() => - builder.AddPaths("UnnecessaryUsings.CSharp10.FileScopedNamespace.cs").WithOptions(ParseOptionsHelper.FromCSharp10).WithConcurrentAnalysis(false).Verify(); + builder.AddPaths("UnnecessaryUsings.CSharp10.FileScopedNamespace.cs").WithOptions(ParseOptionsHelper.FromCSharp10).Verify(); [TestMethod] public void UnnecessaryUsings_CodeFix_CSharp10_FileScopedNamespace() => diff --git a/analyzers/tests/SonarAnalyzer.UnitTest/TestFramework/Tests/VerifierTest.cs b/analyzers/tests/SonarAnalyzer.UnitTest/TestFramework/Tests/VerifierTest.cs index 2a271594e36..8e6e4b3db08 100644 --- a/analyzers/tests/SonarAnalyzer.UnitTest/TestFramework/Tests/VerifierTest.cs +++ b/analyzers/tests/SonarAnalyzer.UnitTest/TestFramework/Tests/VerifierTest.cs @@ -226,21 +226,24 @@ public void Verify_TwoPaths() => [TestMethod] public void Verify_AutogenerateConcurrentFiles() { - var builder = WithSnippetCS("// Noncompliant - FN"); + var builder = WithSnippetCS( +@"namespace N1 { + // Noncompliant - FN +}"); // Concurrent analysis by-default automatically generates concurrent files - File.Concurrent.cs builder.Invoking(x => x.Verify()).Should().Throw().WithMessage( @"CSharp7: Issue(s) expected but not raised in file(s): File: File.cs -Line: 1, Type: primary, Id: '' +Line: 2, Type: primary, Id: '' File: File.Concurrent.cs -Line: 1, Type: primary, Id: '' +Line: 2, Type: primary, Id: '' "); // When AutogenerateConcurrentFiles is turned off, only the provided snippet is analyzed builder.WithAutogenerateConcurrentFiles(false).Invoking(x => x.Verify()).Should().Throw().WithMessage( @"CSharp7: Issue(s) expected but not raised in file(s): File: File.cs -Line: 1, Type: primary, Id: '' +Line: 2, Type: primary, Id: '' "); } diff --git a/analyzers/tests/SonarAnalyzer.UnitTest/TestFramework/Verifier.cs b/analyzers/tests/SonarAnalyzer.UnitTest/TestFramework/Verifier.cs index 8154bba8d75..b5826463e0c 100644 --- a/analyzers/tests/SonarAnalyzer.UnitTest/TestFramework/Verifier.cs +++ b/analyzers/tests/SonarAnalyzer.UnitTest/TestFramework/Verifier.cs @@ -23,7 +23,10 @@ using System.Text; using System.Text.RegularExpressions; using Google.Protobuf; +using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CodeFixes; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; using SonarAnalyzer.Common; using SonarAnalyzer.Rules; using SonarAnalyzer.UnitTest.Helpers; @@ -181,7 +184,7 @@ private string InsertConcurrentNamespace(string content) { return language.LanguageName switch { - LanguageNames.CSharp => $"namespace AppendedNamespaceForConcurrencyTest {{ {content} {Environment.NewLine}}}", // Last line can be a comment + LanguageNames.CSharp => EncloseInNamespace(content), LanguageNames.VisualBasic => content.Insert(ImportsIndexVB(), "Namespace AppendedNamespaceForConcurrencyTest : ") + Environment.NewLine + " : End Namespace", _ => throw new UnexpectedLanguageException(language) }; @@ -190,6 +193,37 @@ int ImportsIndexVB() => ImportsRegexVB.Match(content) is { Success: true } match ? match.Index + match.Length + 1 : 0; } + private static string EncloseInNamespace(string content) + { + var tree = CSharpSyntaxTree.ParseText(content); + if (tree.TryGetRoot(out var root) && root is CompilationUnitSyntax { Members: { } members } compilationUnit) + { + if (members.OfType().FirstOrDefault() is { } fileScoped) + { + root = root.ReplaceNode(fileScoped, fileScoped.WithName(SyntaxFactory.ParseName($"ConcurrencyTest.{CSharpSyntaxHelper.GetName(fileScoped.Name)}"))); + } + else + { + var newNamespace = SyntaxFactory.NamespaceDeclaration(SyntaxFactory.ParseName(" AppendedNamespaceForConcurrencyTest")) + .WithMembers(compilationUnit.Members) + .WithCloseBraceToken(SyntaxFactory.Token(SyntaxKind.CloseBraceToken).WithLeadingTrivia(SyntaxFactory.Whitespace("\n"))); + if (newNamespace.Members.Any() && newNamespace.Members[0] is NamespaceDeclarationSyntax) + { + // Move the leading trivia of the first member to newNamespace + newNamespace = newNamespace.WithLeadingTrivia(newNamespace.Members[0].GetLeadingTrivia()); + newNamespace = newNamespace.WithMembers(newNamespace.Members.Replace(newNamespace.Members[0], newNamespace.Members[0].WithoutLeadingTrivia())); + } + root = compilationUnit.WithMembers(SyntaxFactory.List(new[] { newNamespace })); + } + + return root.ToFullString(); + } + else + { + return $"namespace AppendedNamespaceForConcurrencyTest {{ {content} {Environment.NewLine}}}"; + } + } + private string TestCasePath(string fileName) => Path.GetFullPath(builder.BasePath == null ? Path.Combine(TestCases, fileName) : Path.Combine(TestCases, builder.BasePath, fileName));