From 62a63bc6276aad5ca43017f58a1471b20d6e2b0f Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Sat, 29 Jun 2024 09:42:16 -0700 Subject: [PATCH 1/5] Do not offer 'convert' namespace when the ns has sibling types --- .../ConvertNamespaceAnalysis.cs | 15 +- ...nvertToFileScopedNamespaceAnalyzerTests.cs | 42 + ...ConvertNamespaceCodeRefactoringProvider.cs | 10 +- .../ConvertNamespaceRefactoringTests.cs | 886 +++++++++--------- 4 files changed, 493 insertions(+), 460 deletions(-) diff --git a/src/Analyzers/CSharp/Analyzers/ConvertNamespace/ConvertNamespaceAnalysis.cs b/src/Analyzers/CSharp/Analyzers/ConvertNamespace/ConvertNamespaceAnalysis.cs index 9f4356c16c022..e824d4854e728 100644 --- a/src/Analyzers/CSharp/Analyzers/ConvertNamespace/ConvertNamespaceAnalysis.cs +++ b/src/Analyzers/CSharp/Analyzers/ConvertNamespace/ConvertNamespaceAnalysis.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using System.Collections.Immutable; using System.Diagnostics.CodeAnalysis; using System.Linq; using Microsoft.CodeAnalysis.CodeStyle; @@ -68,16 +67,14 @@ internal static bool CanOfferUseFileScoped( if (!canOffer) return false; - // even if we could offer this here, we have to make sure it would be legal. A file scoped namespace is - // only legal if it's the only namespace in the file and there are no top level statements. - var tooManyNamespaces = root.DescendantNodesAndSelf(n => n is CompilationUnitSyntax or BaseNamespaceDeclarationSyntax) - .OfType() - .Take(2) - .Count() != 1; - if (tooManyNamespaces) + // even if we could offer this here, we have to make sure it would be legal. + + // A file scoped namespace is only legal if it's the only top level member in the file. + if (root.Members is not [var singleMember] || singleMember != namespaceDeclaration) return false; - if (root.Members.Any(m => m is GlobalStatementSyntax)) + // A file scoped namespace is only legal if it's the only namespace in the file. + if (namespaceDeclaration.Members.Any(static m => m is BaseNamespaceDeclarationSyntax)) return false; return true; diff --git a/src/Analyzers/CSharp/Tests/ConvertNamespace/ConvertToFileScopedNamespaceAnalyzerTests.cs b/src/Analyzers/CSharp/Tests/ConvertNamespace/ConvertToFileScopedNamespaceAnalyzerTests.cs index 1dd2c0d898974..dcb3bff374a04 100644 --- a/src/Analyzers/CSharp/Tests/ConvertNamespace/ConvertToFileScopedNamespaceAnalyzerTests.cs +++ b/src/Analyzers/CSharp/Tests/ConvertNamespace/ConvertToFileScopedNamespaceAnalyzerTests.cs @@ -1544,4 +1544,46 @@ limit 1 } }.RunAsync(); } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/74214")] + public async Task TestNotWithClassAfter() + { + await new VerifyCS.Test + { + TestCode = """ + namespace N + { + class Inner { } + } + + class Outer { } + """, + LanguageVersion = LanguageVersion.CSharp10, + Options = + { + { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } + } + }.RunAsync(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/74214")] + public async Task TestNotWithClassBefore() + { + await new VerifyCS.Test + { + TestCode = """ + class Outer { } + + namespace N + { + class Inner { } + } + """, + LanguageVersion = LanguageVersion.CSharp10, + Options = + { + { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.FileScoped } + } + }.RunAsync(); + } } diff --git a/src/Features/CSharp/Portable/ConvertNamespace/ConvertNamespaceCodeRefactoringProvider.cs b/src/Features/CSharp/Portable/ConvertNamespace/ConvertNamespaceCodeRefactoringProvider.cs index 347a1cd7ca079..839cd36843729 100644 --- a/src/Features/CSharp/Portable/ConvertNamespace/ConvertNamespaceCodeRefactoringProvider.cs +++ b/src/Features/CSharp/Portable/ConvertNamespace/ConvertNamespaceCodeRefactoringProvider.cs @@ -24,14 +24,10 @@ namespace Microsoft.CodeAnalysis.CSharp.ConvertNamespace; using static ConvertNamespaceTransform; [ExportCodeRefactoringProvider(LanguageNames.CSharp, Name = PredefinedCodeRefactoringProviderNames.ConvertNamespace), Shared] -internal class ConvertNamespaceCodeRefactoringProvider : SyntaxEditorBasedCodeRefactoringProvider +[method: ImportingConstructor] +[method: SuppressMessage("RoslynDiagnosticsReliability", "RS0033:Importing constructor should be [Obsolete]", Justification = "Used in test code: https://github.com/dotnet/roslyn/issues/42814")] +internal class ConvertNamespaceCodeRefactoringProvider() : SyntaxEditorBasedCodeRefactoringProvider { - [ImportingConstructor] - [SuppressMessage("RoslynDiagnosticsReliability", "RS0033:Importing constructor should be [Obsolete]", Justification = "Used in test code: https://github.com/dotnet/roslyn/issues/42814")] - public ConvertNamespaceCodeRefactoringProvider() - { - } - protected override ImmutableArray SupportedFixAllScopes => [FixAllScope.Project, FixAllScope.Solution]; diff --git a/src/Features/CSharpTest/ConvertNamespace/ConvertNamespaceRefactoringTests.cs b/src/Features/CSharpTest/ConvertNamespace/ConvertNamespaceRefactoringTests.cs index fd8ec397c36c2..18b81030fd799 100644 --- a/src/Features/CSharpTest/ConvertNamespace/ConvertNamespaceRefactoringTests.cs +++ b/src/Features/CSharpTest/ConvertNamespace/ConvertNamespaceRefactoringTests.cs @@ -19,14 +19,16 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ConvertNamespace; using VerifyCS = CSharpCodeRefactoringVerifier; [UseExportProvider] -public class ConvertNamespaceRefactoringTests +public sealed class ConvertNamespaceRefactoringTests { public static IEnumerable EndOfDocumentSequences { get { yield return new object[] { "" }; - yield return new object[] { "\r\n" }; + yield return new object[] { """ + + """ }; } } @@ -35,11 +37,11 @@ public static IEnumerable EndOfDocumentSequences [Fact] public async Task TestNoConvertToFileScopedInCSharp9() { - var code = @" -namespace $$N -{ -} -"; + var code = """ + namespace $$N + { + } + """; await new VerifyCS.Test { TestCode = code, @@ -55,11 +57,11 @@ namespace $$N [Fact] public async Task TestNoConvertToFileScopedInCSharp10WithFileScopedPreference() { - var code = @" -namespace $$N -{ -} -"; + var code = """ + namespace $$N + { + } + """; await new VerifyCS.Test { TestCode = code, @@ -77,14 +79,14 @@ public async Task TestConvertToFileScopedInCSharp10WithBlockScopedPreference() { await new VerifyCS.Test { - TestCode = @" -namespace $$N -{ -} -", - FixedCode = @" -namespace $$N; -", + TestCode = """ + namespace $$N + { + } + """, + FixedCode = """ + namespace $$N; + """, LanguageVersion = LanguageVersion.CSharp10, Options = { @@ -98,14 +100,14 @@ public async Task TestOnNamespaceToken() { await new VerifyCS.Test { - TestCode = @" -$$namespace N -{ -} -", - FixedCode = @" -namespace N; -", + TestCode = """ + $$namespace N + { + } + """, + FixedCode = """ + namespace N; + """, LanguageVersion = LanguageVersion.CSharp10, Options = { @@ -117,12 +119,12 @@ namespace N; [Fact] public async Task TestNotBeforeNamespaceToken() { - var code = @" -$$ -namespace N -{ -} -"; + var code = """ + $$ + namespace N + { + } + """; await new VerifyCS.Test { TestCode = code, @@ -138,11 +140,11 @@ namespace N [Fact] public async Task TestNotOnOpenBrace() { - var code = @" -namespace N -$${ -} -"; + var code = """ + namespace N + $${ + } + """; await new VerifyCS.Test { TestCode = code, @@ -158,15 +160,15 @@ namespace N [Fact] public async Task TestNoConvertWithMultipleNamespaces() { - var code = @" -namespace $$N -{ -} + var code = """ + namespace $$N + { + } -namespace N2 -{ -} -"; + namespace N2 + { + } + """; await new VerifyCS.Test { TestCode = code, @@ -182,14 +184,14 @@ namespace N2 [Fact] public async Task TestNoConvertWithNestedNamespaces1() { - var code = @" -namespace $$N -{ - namespace N2 - { - } -} -"; + var code = """ + namespace $$N + { + namespace N2 + { + } + } + """; await new VerifyCS.Test { TestCode = code, @@ -205,14 +207,14 @@ namespace N2 [Fact] public async Task TestNoConvertWithNestedNamespaces2() { - var code = @" -namespace N -{ - namespace $$N2 - { - } -} -"; + var code = """ + namespace N + { + namespace $$N2 + { + } + } + """; await new VerifyCS.Test { TestCode = code, @@ -228,23 +230,18 @@ namespace $$N2 [Fact] public async Task TestNoConvertWithTopLevelStatement1() { - var code = @" -int i = 0; + var code = """ + {|CS8805:int i = 0;|} -namespace $$N -{ -} -"; + namespace $$N + { + } + """; await new VerifyCS.Test { TestCode = code, FixedCode = code, LanguageVersion = LanguageVersion.CSharp10, - ExpectedDiagnostics = - { - // /0/Test0.cs(2,1): error CS8805: Program using top-level statements must be an executable. - DiagnosticResult.CompilerError("CS8805").WithSpan(2, 1, 2, 11), - }, Options = { { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped } @@ -255,25 +252,18 @@ namespace $$N [Fact] public async Task TestNoConvertWithTopLevelStatement2() { - var code = @" -namespace $$N -{ -} + var code = """ + namespace $$N + { + } -int i = 0; -"; + {|CS8805:{|CS8803:int i = 0;|}|} + """; await new VerifyCS.Test { TestCode = code, FixedCode = code, LanguageVersion = LanguageVersion.CSharp10, - ExpectedDiagnostics = - { - // /0/Test0.cs(6,1): error CS8803: Top-level statements must precede namespace and type declarations. - DiagnosticResult.CompilerError("CS8803").WithSpan(6, 1, 6, 11), - // /0/Test0.cs(6,1): error CS8805: Program using top-level statements must be an executable. - DiagnosticResult.CompilerError("CS8805").WithSpan(6, 1, 6, 11), - }, Options = { { CSharpCodeStyleOptions.NamespaceDeclarations, NamespaceDeclarationPreference.BlockScoped } @@ -286,18 +276,18 @@ public async Task TestConvertToFileScopedWithUsing1() { await new VerifyCS.Test { - TestCode = @" -using System; + TestCode = """ + using System; -namespace $$N -{ -} -", - FixedCode = @" -using System; + namespace $$N + { + } + """, + FixedCode = """ + using System; -namespace $$N; -", + namespace $$N; + """, LanguageVersion = LanguageVersion.CSharp10, Options = { @@ -311,17 +301,17 @@ public async Task TestConvertToFileScopedWithUsing2() { await new VerifyCS.Test { - TestCode = @" -namespace $$N -{ - using System; -} -", - FixedCode = @" -namespace $$N; + TestCode = """ + namespace $$N + { + using System; + } + """, + FixedCode = """ + namespace $$N; -using System; -", + using System; + """, LanguageVersion = LanguageVersion.CSharp10, Options = { @@ -335,21 +325,21 @@ public async Task TestConvertToFileScopedWithClass() { await new VerifyCS.Test { - TestCode = @" -namespace $$N -{ - class C - { - } -} -", - FixedCode = @" -namespace $$N; + TestCode = """ + namespace $$N + { + class C + { + } + } + """, + FixedCode = """ + namespace $$N; -class C -{ -} -", + class C + { + } + """, LanguageVersion = LanguageVersion.CSharp10, Options = { @@ -363,23 +353,23 @@ public async Task TestConvertToFileScopedWithClassWithDocComment() { await new VerifyCS.Test { - TestCode = @" -namespace $$N -{ - /// - class C - { - } -} -", - FixedCode = @" -namespace $$N; + TestCode = """ + namespace $$N + { + /// + class C + { + } + } + """, + FixedCode = """ + namespace $$N; -/// -class C -{ -} -", + /// + class C + { + } + """, LanguageVersion = LanguageVersion.CSharp10, Options = { @@ -393,20 +383,22 @@ public async Task TestConvertToFileScopedWithMissingCloseBrace() { await new VerifyCS.Test { - TestCode = @" -namespace $$N -{ - /// - class C - { - }{|CS1513:|}", - FixedCode = @" -namespace N; - -/// -class C -{ -}", + TestCode = """ + namespace $$N + { + /// + class C + { + }{|CS1513:|} + """, + FixedCode = """ + namespace N; + + /// + class C + { + } + """, LanguageVersion = LanguageVersion.CSharp10, Options = { @@ -420,21 +412,21 @@ public async Task TestConvertToFileScopedWithCommentOnOpenCurly() { await new VerifyCS.Test { - TestCode = @" -namespace $$N -{ // comment - class C - { - } -} -", - FixedCode = @" -namespace $$N; -// comment -class C -{ -} -", + TestCode = """ + namespace $$N + { // comment + class C + { + } + } + """, + FixedCode = """ + namespace $$N; + // comment + class C + { + } + """, LanguageVersion = LanguageVersion.CSharp10, Options = { @@ -448,23 +440,23 @@ public async Task TestConvertToFileScopedWithLeadingComment() { await new VerifyCS.Test { - TestCode = @" -// copyright -namespace $$N -{ - class C - { - } -} -", - FixedCode = @" -// copyright -namespace $$N; + TestCode = """ + // copyright + namespace $$N + { + class C + { + } + } + """, + FixedCode = """ + // copyright + namespace $$N; -class C -{ -} -", + class C + { + } + """, LanguageVersion = LanguageVersion.CSharp10, Options = { @@ -478,21 +470,21 @@ public async Task TextConvertToFileScopedWithCommentedOutContents() { await new VerifyCS.Test { - TestCode = @" -$$namespace N -{ - // public class C - // { - // } -} -", - FixedCode = @" -namespace N; - -// public class C -// { -// } -", + TestCode = """ + $$namespace N + { + // public class C + // { + // } + } + """, + FixedCode = """ + namespace N; + + // public class C + // { + // } + """, LanguageVersion = LanguageVersion.CSharp10, Options = { @@ -506,25 +498,25 @@ public async Task TextConvertToFileScopedWithCommentedAfterContents() { await new VerifyCS.Test { - TestCode = @" -$$namespace N -{ - public class C - { - } + TestCode = """ + $$namespace N + { + public class C + { + } - // I'll probably write some more code here later -} -", - FixedCode = @" -namespace N; + // I'll probably write some more code here later + } + """, + FixedCode = """ + namespace N; -public class C -{ -} + public class C + { + } -// I'll probably write some more code here later -", + // I'll probably write some more code here later + """, LanguageVersion = LanguageVersion.CSharp10, Options = { @@ -538,29 +530,29 @@ public async Task TextConvertToFileScopedWithTriviaAroundNamespace1() { await new VerifyCS.Test { - TestCode = @" -#if !NONEXISTENT -$$namespace NDebug -#else -namespace NRelease -#endif -{ - public class C - { - } -} -", - FixedCode = @" -#if !NONEXISTENT -namespace NDebug; -#else -namespace NRelease -#endif - -public class C -{ -} -", + TestCode = """ + #if !NONEXISTENT + $$namespace NDebug + #else + namespace NRelease + #endif + { + public class C + { + } + } + """, + FixedCode = """ + #if !NONEXISTENT + namespace NDebug; + #else + namespace NRelease + #endif + + public class C + { + } + """, LanguageVersion = LanguageVersion.CSharp10, Options = { @@ -574,29 +566,29 @@ public async Task TextConvertToFileScopedWithTriviaAroundNamespace2() { await new VerifyCS.Test { - TestCode = @" -#if NONEXISTENT -namespace NDebug -#else -$$namespace NRelease -#endif -{ - public class C - { - } -} -", - FixedCode = @" -#if NONEXISTENT -namespace NDebug -#else -namespace NRelease; -#endif - -public class C -{ -} -", + TestCode = """ + #if NONEXISTENT + namespace NDebug + #else + $$namespace NRelease + #endif + { + public class C + { + } + } + """, + FixedCode = """ + #if NONEXISTENT + namespace NDebug + #else + namespace NRelease; + #endif + + public class C + { + } + """, LanguageVersion = LanguageVersion.CSharp10, Options = { @@ -615,12 +607,14 @@ public async Task TestConvertToBlockScopedInCSharp9(string endOfDocumentSequence { await new VerifyCS.Test { - TestCode = $@" -{{|CS8773:namespace|}} $$N;{endOfDocumentSequence}", - FixedCode = $@" -namespace $$N -{{ -}}{endOfDocumentSequence}", + TestCode = $$""" + {|CS8773:namespace|} $$N;{{endOfDocumentSequence}} + """, + FixedCode = $$""" + namespace $$N + { + }{{endOfDocumentSequence}} + """, LanguageVersion = LanguageVersion.CSharp9, Options = { @@ -632,9 +626,9 @@ namespace $$N [Fact] public async Task TestNoConvertToBlockScopedInCSharp10WithBlockScopedPreference() { - var code = @" -namespace $$N; -"; + var code = """ + namespace $$N; + """; await new VerifyCS.Test { TestCode = code, @@ -652,14 +646,14 @@ public async Task TestConvertToBlockScopedInCSharp10WithFileScopedPreference() { await new VerifyCS.Test { - TestCode = @" -namespace $$N; -", - FixedCode = @" -namespace $$N -{ -} -", + TestCode = """ + namespace $$N; + """, + FixedCode = """ + namespace $$N + { + } + """, LanguageVersion = LanguageVersion.CSharp10, Options = { @@ -673,14 +667,14 @@ public async Task TestConvertToBlockOnNamespaceToken2() { await new VerifyCS.Test { - TestCode = @" -$$namespace N; -", - FixedCode = @" -namespace N -{ -} -", + TestCode = """ + $$namespace N; + """, + FixedCode = """ + namespace N + { + } + """, LanguageVersion = LanguageVersion.CSharp10, Options = { @@ -692,10 +686,10 @@ namespace N [Fact] public async Task TestConvertToBlockNotBeforeNamespaceToken2() { - var code = @" -$$ -namespace N; -"; + var code = """ + $$ + namespace N; + """; await new VerifyCS.Test { TestCode = code, @@ -711,10 +705,10 @@ namespace N; [Fact] public async Task TestConvertToBlockNotAfterSemicolon() { - var code = @" -namespace N; -$$ -"; + var code = """ + namespace N; + $$ + """; await new VerifyCS.Test { TestCode = code, @@ -730,9 +724,9 @@ namespace N; [Fact] public async Task TestConvertToBlockAfterSemicolon() { - var code = @" -namespace N; $$ -"; + var code = """ + namespace N; $$ + """; await new VerifyCS.Test { TestCode = code, @@ -750,21 +744,21 @@ public async Task TestConvertToBlockWithMultipleNamespaces() { await new VerifyCS.Test { - TestCode = @" -namespace $$N; + TestCode = """ + namespace $$N; -namespace {|CS8955:N2|} -{ -} -", - FixedCode = @" -namespace $$N -{ - namespace N2 - { - } -} -", + namespace {|CS8955:N2|} + { + } + """, + FixedCode = """ + namespace $$N + { + namespace N2 + { + } + } + """, LanguageVersion = LanguageVersion.CSharp10, Options = { @@ -778,15 +772,17 @@ public async Task TestConvertToBlockWithNestedNamespaces1() { await new VerifyCS.Test { - TestCode = @" -namespace $$N; + TestCode = """ + namespace $$N; -namespace {|CS8954:N2|};", - FixedCode = @" -namespace $$N -{ - namespace {|CS8955:N2|}; -}", + namespace {|CS8954:N2|}; + """, + FixedCode = """ + namespace $$N + { + namespace {|CS8955:N2|}; + } + """, LanguageVersion = LanguageVersion.CSharp10, Options = { @@ -800,20 +796,20 @@ public async Task TestConvertToBlockWithNestedNamespaces2() { await new VerifyCS.Test { - TestCode = @" -namespace N -{ - namespace $${|CS8955:N2|}; -} -", - FixedCode = @" -namespace N -{ - namespace $$N2 - { - } -} -", + TestCode = """ + namespace N + { + namespace $${|CS8955:N2|}; + } + """, + FixedCode = """ + namespace N + { + namespace $$N2 + { + } + } + """, LanguageVersion = LanguageVersion.CSharp10, Options = { @@ -827,18 +823,18 @@ public async Task TestConvertToBlockWithTopLevelStatement1() { await new VerifyCS.Test { - TestCode = @" -{|CS8805:int i = 0;|} + TestCode = """ + {|CS8805:int i = 0;|} -namespace $${|CS8956:N|}; -", - FixedCode = @" -{|CS8805:int i = 0;|} + namespace $${|CS8956:N|}; + """, + FixedCode = """ + {|CS8805:int i = 0;|} -namespace $$N -{ -} -", + namespace $$N + { + } + """, LanguageVersion = LanguageVersion.CSharp10, Options = { @@ -852,17 +848,17 @@ public async Task TestConvertToBlockWithTopLevelStatement2() { await new VerifyCS.Test { - TestCode = @" -namespace $$N; + TestCode = """ + namespace $$N; -int {|CS0116:i|} = 0; -", - FixedCode = @" -namespace $$N -{ - int {|CS0116:i|} = 0; -} -", + int {|CS0116:i|} = 0; + """, + FixedCode = """ + namespace $$N + { + int {|CS0116:i|} = 0; + } + """, LanguageVersion = LanguageVersion.CSharp10, Options = { @@ -876,18 +872,18 @@ public async Task TestConvertToBlockScopedWithUsing1() { await new VerifyCS.Test { - TestCode = @" -using System; + TestCode = """ + using System; -namespace $$N; -", - FixedCode = @" -using System; + namespace $$N; + """, + FixedCode = """ + using System; -namespace $$N -{ -} -", + namespace $$N + { + } + """, LanguageVersion = LanguageVersion.CSharp10, Options = { @@ -901,17 +897,17 @@ public async Task TestConvertToBlockScopedWithUsing2() { await new VerifyCS.Test { - TestCode = @" -namespace $$N; + TestCode = """ + namespace $$N; -using System; -", - FixedCode = @" -namespace $$N -{ - using System; -} -", + using System; + """, + FixedCode = """ + namespace $$N + { + using System; + } + """, LanguageVersion = LanguageVersion.CSharp10, Options = { @@ -925,21 +921,21 @@ public async Task TestConvertToBlockScopedWithClass() { await new VerifyCS.Test { - TestCode = @" -namespace $$N; + TestCode = """ + namespace $$N; -class C -{ -} -", - FixedCode = @" -namespace $$N -{ - class C - { - } -} -", + class C + { + } + """, + FixedCode = """ + namespace $$N + { + class C + { + } + } + """, LanguageVersion = LanguageVersion.CSharp10, Options = { @@ -953,23 +949,23 @@ public async Task TestConvertToBlockScopedWithClassWithDocComment() { await new VerifyCS.Test { - TestCode = @" -namespace $$N; + TestCode = """ + namespace $$N; -/// -class C -{ -} -", - FixedCode = @" -namespace $$N -{ - /// - class C - { - } -} -", + /// + class C + { + } + """, + FixedCode = """ + namespace $$N + { + /// + class C + { + } + } + """, LanguageVersion = LanguageVersion.CSharp10, Options = { @@ -983,19 +979,21 @@ public async Task TestConvertToBlockScopedWithMissingCloseBrace() { await new VerifyCS.Test { - TestCode = @" -namespace $$N; - -/// -class C -{{|CS1513:|}", - FixedCode = @" -namespace N -{ - /// - class C - { -}{|CS1513:|}", + TestCode = """ + namespace $$N; + + /// + class C + {{|CS1513:|} + """, + FixedCode = """ + namespace N + { + /// + class C + { + }{|CS1513:|} + """, LanguageVersion = LanguageVersion.CSharp10, CodeActionValidationMode = CodeActionValidationMode.None, Options = @@ -1010,21 +1008,21 @@ public async Task TestConvertToBlockScopedWithCommentOnSemicolon() { await new VerifyCS.Test { - TestCode = @" -namespace $$N; // comment + TestCode = """ + namespace $$N; // comment -class C -{ -} -", - FixedCode = @" -namespace $$N -{ // comment - class C - { - } -} -", + class C + { + } + """, + FixedCode = """ + namespace $$N + { // comment + class C + { + } + } + """, LanguageVersion = LanguageVersion.CSharp10, Options = { @@ -1038,23 +1036,23 @@ public async Task TestConvertToBlockScopedWithLeadingComment() { await new VerifyCS.Test { - TestCode = @" -// copyright -namespace $$N; + TestCode = """ + // copyright + namespace $$N; -class C -{ -} -", - FixedCode = @" -// copyright -namespace $$N -{ - class C - { - } -} -", + class C + { + } + """, + FixedCode = """ + // copyright + namespace $$N + { + class C + { + } + } + """, LanguageVersion = LanguageVersion.CSharp10, Options = { From c616ef493b5de433131b51b8d6d2725b1bdd4674 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Sat, 29 Jun 2024 09:45:07 -0700 Subject: [PATCH 2/5] tweak --- .../ConvertNamespaceRefactoringTests.cs | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/src/Features/CSharpTest/ConvertNamespace/ConvertNamespaceRefactoringTests.cs b/src/Features/CSharpTest/ConvertNamespace/ConvertNamespaceRefactoringTests.cs index 18b81030fd799..37b1cc83d28ab 100644 --- a/src/Features/CSharpTest/ConvertNamespace/ConvertNamespaceRefactoringTests.cs +++ b/src/Features/CSharpTest/ConvertNamespace/ConvertNamespaceRefactoringTests.cs @@ -21,16 +21,7 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ConvertNamespace; [UseExportProvider] public sealed class ConvertNamespaceRefactoringTests { - public static IEnumerable EndOfDocumentSequences - { - get - { - yield return new object[] { "" }; - yield return new object[] { """ - - """ }; - } - } + public static IEnumerable EndOfDocumentSequences => [[""], ["\r\n"]]; #region Convert To File Scoped From 3560ab3a72a7498c8f6b8f50b5d512f5362cee66 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Sat, 29 Jun 2024 09:47:59 -0700 Subject: [PATCH 3/5] Add string syntax attribute --- .../CodeActions/CSharpCodeRefactoringVerifier`1+Test.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Features/DiagnosticsTestUtilities/CodeActions/CSharpCodeRefactoringVerifier`1+Test.cs b/src/Features/DiagnosticsTestUtilities/CodeActions/CSharpCodeRefactoringVerifier`1+Test.cs index 1ddb360748015..5e6aa14b29096 100644 --- a/src/Features/DiagnosticsTestUtilities/CodeActions/CSharpCodeRefactoringVerifier`1+Test.cs +++ b/src/Features/DiagnosticsTestUtilities/CodeActions/CSharpCodeRefactoringVerifier`1+Test.cs @@ -11,6 +11,8 @@ using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Testing; using Microsoft.CodeAnalysis.Testing.Verifiers; +using System.Diagnostics.CodeAnalysis; + #if !CODE_STYLE using System; @@ -58,6 +60,9 @@ public Test() /// internal OptionsCollection Options => _sharedState.Options; + [StringSyntax("C#-Test")] public new string TestCode { set => base.TestCode = value; } + [StringSyntax("C#-Test")] public new string FixedCode { set => base.FixedCode = value; } + #if !CODE_STYLE internal CodeActionOptionsProvider CodeActionOptions { From dcf1f17979318c4efaf90b6656fcc06bcecfff8b Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Sat, 29 Jun 2024 09:48:47 -0700 Subject: [PATCH 4/5] Add string syntax attribute --- .../CodeActions/CSharpCodeFixVerifier`2+Test.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Features/DiagnosticsTestUtilities/CodeActions/CSharpCodeFixVerifier`2+Test.cs b/src/Features/DiagnosticsTestUtilities/CodeActions/CSharpCodeFixVerifier`2+Test.cs index adb7a5a8ddeb9..32407153ad640 100644 --- a/src/Features/DiagnosticsTestUtilities/CodeActions/CSharpCodeFixVerifier`2+Test.cs +++ b/src/Features/DiagnosticsTestUtilities/CodeActions/CSharpCodeFixVerifier`2+Test.cs @@ -16,6 +16,7 @@ using Microsoft.CodeAnalysis.CodeActions; using Microsoft.CodeAnalysis.Text; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; #if !CODE_STYLE using Roslyn.Utilities; @@ -61,6 +62,9 @@ public Test() /// internal OptionsCollection Options => _sharedState.Options; + [StringSyntax("C#-Test")] public new string TestCode { set => base.TestCode = value; } + [StringSyntax("C#-Test")] public new string FixedCode { set => base.FixedCode = value; } + #if !CODE_STYLE internal CodeActionOptionsProvider CodeActionOptions { From 44cbba7ce4c3b769bd24a254383d07db03fcb3f5 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Sat, 29 Jun 2024 09:53:20 -0700 Subject: [PATCH 5/5] use constant --- .../CodeActions/CSharpCodeFixVerifier`2+Test.cs | 7 +++++-- .../CodeActions/CSharpCodeRefactoringVerifier`1+Test.cs | 8 +++++--- .../Compiler/Core/CompilerExtensions.projitems | 1 + .../PredefinedEmbeddedLanguageClassifierNames.cs | 0 4 files changed, 11 insertions(+), 5 deletions(-) rename src/{Features/Core/Portable => Workspaces/SharedUtilitiesAndExtensions/Compiler/Core}/EmbeddedLanguages/PredefinedEmbeddedLanguageClassifierNames.cs (100%) diff --git a/src/Features/DiagnosticsTestUtilities/CodeActions/CSharpCodeFixVerifier`2+Test.cs b/src/Features/DiagnosticsTestUtilities/CodeActions/CSharpCodeFixVerifier`2+Test.cs index 32407153ad640..e4ea7e0d33f0d 100644 --- a/src/Features/DiagnosticsTestUtilities/CodeActions/CSharpCodeFixVerifier`2+Test.cs +++ b/src/Features/DiagnosticsTestUtilities/CodeActions/CSharpCodeFixVerifier`2+Test.cs @@ -62,8 +62,11 @@ public Test() /// internal OptionsCollection Options => _sharedState.Options; - [StringSyntax("C#-Test")] public new string TestCode { set => base.TestCode = value; } - [StringSyntax("C#-Test")] public new string FixedCode { set => base.FixedCode = value; } + [StringSyntax(PredefinedEmbeddedLanguageNames.CSharpTest)] + public new string TestCode { set => base.TestCode = value; } + + [StringSyntax(PredefinedEmbeddedLanguageNames.CSharpTest)] + public new string FixedCode { set => base.FixedCode = value; } #if !CODE_STYLE internal CodeActionOptionsProvider CodeActionOptions diff --git a/src/Features/DiagnosticsTestUtilities/CodeActions/CSharpCodeRefactoringVerifier`1+Test.cs b/src/Features/DiagnosticsTestUtilities/CodeActions/CSharpCodeRefactoringVerifier`1+Test.cs index 5e6aa14b29096..09845b71d45c8 100644 --- a/src/Features/DiagnosticsTestUtilities/CodeActions/CSharpCodeRefactoringVerifier`1+Test.cs +++ b/src/Features/DiagnosticsTestUtilities/CodeActions/CSharpCodeRefactoringVerifier`1+Test.cs @@ -13,7 +13,6 @@ using Microsoft.CodeAnalysis.Testing.Verifiers; using System.Diagnostics.CodeAnalysis; - #if !CODE_STYLE using System; using Microsoft.CodeAnalysis.Diagnostics; @@ -60,8 +59,11 @@ public Test() /// internal OptionsCollection Options => _sharedState.Options; - [StringSyntax("C#-Test")] public new string TestCode { set => base.TestCode = value; } - [StringSyntax("C#-Test")] public new string FixedCode { set => base.FixedCode = value; } + [StringSyntax(PredefinedEmbeddedLanguageNames.CSharpTest)] + public new string TestCode { set => base.TestCode = value; } + + [StringSyntax(PredefinedEmbeddedLanguageNames.CSharpTest)] + public new string FixedCode { set => base.FixedCode = value; } #if !CODE_STYLE internal CodeActionOptionsProvider CodeActionOptions diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/CompilerExtensions.projitems b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/CompilerExtensions.projitems index ceb173582171e..732a934109451 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/CompilerExtensions.projitems +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/CompilerExtensions.projitems @@ -244,6 +244,7 @@ + diff --git a/src/Features/Core/Portable/EmbeddedLanguages/PredefinedEmbeddedLanguageClassifierNames.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/EmbeddedLanguages/PredefinedEmbeddedLanguageClassifierNames.cs similarity index 100% rename from src/Features/Core/Portable/EmbeddedLanguages/PredefinedEmbeddedLanguageClassifierNames.cs rename to src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/EmbeddedLanguages/PredefinedEmbeddedLanguageClassifierNames.cs