From d94e4d73bf718283b60afe3f7c6c70f6a17ad45a Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 21 May 2024 17:30:21 -0700 Subject: [PATCH 1/7] Search less tokens while finding constructors --- .../FindReferences/FindReferenceCache.cs | 30 ++++++++++---- .../ConstructorSymbolReferenceFinder.cs | 40 ++++++++++++------- .../Services/SyntaxFacts/CSharpSyntaxKinds.cs | 3 +- .../Core/Services/SyntaxFacts/ISyntaxKinds.cs | 7 ++-- .../SyntaxFacts/VisualBasicSyntaxKinds.vb | 3 +- 5 files changed, 56 insertions(+), 27 deletions(-) diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/FindReferenceCache.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/FindReferenceCache.cs index 7fec0716af601..9793905be7415 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/FindReferenceCache.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/FindReferenceCache.cs @@ -130,11 +130,25 @@ public ImmutableArray FindMatchingIdentifierTokens( // walks the root and checks all identifier tokens. // // otherwise, we can use the text of the document to quickly find candidates and test those directly. - return this.SyntaxTreeIndex.ProbablyContainsEscapedIdentifier(identifier) - ? _identifierCache.GetOrAdd(identifier, identifier => FindMatchingIdentifierTokensFromTree(identifier, cancellationToken)) - : _identifierCache.GetOrAdd(identifier, _ => FindMatchingIdentifierTokensFromText(identifier, cancellationToken)); + if (this.SyntaxTreeIndex.ProbablyContainsEscapedIdentifier(identifier)) + { + return _identifierCache.GetOrAdd( + identifier, + identifier => FindMatchingIdentifierTokensFromTree(identifier, cancellationToken)); + } + + return _identifierCache.GetOrAdd( + identifier, + identifier => FindMatchingIdentifierTokensFromText( + identifier, + static (identifier, token, @this) => @this.IsMatch(identifier, token), + this, cancellationToken)); } + public ImmutableArray FindMatchingTextTokens( + string text, Func isMatch, TArgs args, CancellationToken cancellationToken) + => _identifierCache.GetOrAdd(text, _ => FindMatchingIdentifierTokensFromText(text, isMatch, args, cancellationToken)); + private bool IsMatch(string identifier, SyntaxToken token) => !token.IsMissing && this.SyntaxFacts.IsIdentifier(token) && this.SyntaxFacts.TextMatch(token.ValueText, identifier); @@ -176,22 +190,22 @@ private ImmutableArray FindMatchingIdentifierTokensFromTree( return result.ToImmutableAndClear(); } - private ImmutableArray FindMatchingIdentifierTokensFromText( - string identifier, CancellationToken cancellationToken) + private ImmutableArray FindMatchingIdentifierTokensFromText( + string text, Func isMatch, TArgs args, CancellationToken cancellationToken) { using var _ = ArrayBuilder.GetInstance(out var result); var index = 0; - while ((index = this.Text.IndexOf(identifier, index, this.SyntaxFacts.IsCaseSensitive)) >= 0) + while ((index = this.Text.IndexOf(text, index, this.SyntaxFacts.IsCaseSensitive)) >= 0) { cancellationToken.ThrowIfCancellationRequested(); var token = this.Root.FindToken(index, findInsideTrivia: true); var span = token.Span; - if (span.Start == index && span.Length == identifier.Length && IsMatch(identifier, token)) + if (span.Start == index && span.Length == text.Length && isMatch(text, token, args)) result.Add(token); - var nextIndex = index + identifier.Length; + var nextIndex = index + text.Length; nextIndex = Math.Max(nextIndex, token.SpanStart); index = nextIndex; } diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ConstructorSymbolReferenceFinder.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ConstructorSymbolReferenceFinder.cs index 19c6c488915ad..3c76b1548075d 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ConstructorSymbolReferenceFinder.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ConstructorSymbolReferenceFinder.cs @@ -190,13 +190,28 @@ private static void FindAttributeReferences( FindReferencesInDocumentUsingIdentifier(symbol, simpleName, state, processResult, processResultData, cancellationToken); } - private void FindReferencesInImplicitObjectCreationExpression( + private static void FindReferencesInImplicitObjectCreationExpression( IMethodSymbol symbol, FindReferencesDocumentState state, Action processResult, TData processResultData, CancellationToken cancellationToken) { + if (!state.Cache.SyntaxTreeIndex.ContainsImplicitObjectCreation) + return; + + // Note: only C# supports implicit object creation. So we don't need to do anything special around case + // insensitive matching here. + // + // Search for all the `new` tokens in the file. + var newKeywordTokens = state.Cache.FindMatchingTextTokens( + "new", + (_, token, syntaxKinds) => token.RawKind == syntaxKinds.NewKeyword, + state.SyntaxFacts.SyntaxKinds, + cancellationToken); + if (newKeywordTokens.IsEmpty) + return; + // Only check `new (...)` calls that supply enough arguments to match all the required parameters for the constructor. var minimumArgumentCount = symbol.Parameters.Count(p => !p.IsOptional && !p.IsParams); var maximumArgumentCount = symbol.Parameters is [.., { IsParams: true }] @@ -208,16 +223,12 @@ private void FindReferencesInImplicitObjectCreationExpression( : symbol.Parameters.Length; var implicitObjectKind = state.SyntaxFacts.SyntaxKinds.ImplicitObjectCreationExpression; - FindReferencesInDocument(state, IsRelevantDocument, CollectMatchingReferences, processResult, processResultData, cancellationToken); - return; - - static bool IsRelevantDocument(SyntaxTreeIndex syntaxTreeInfo) - => syntaxTreeInfo.ContainsImplicitObjectCreation; - - void CollectMatchingReferences( - SyntaxNode node, FindReferencesDocumentState state, Action processResult, TData processResultData) + foreach (var newKeywordToken in newKeywordTokens) { - if (node.RawKind != implicitObjectKind) + cancellationToken.ThrowIfCancellationRequested(); + + var node = newKeywordToken.Parent; + if (node is null || node.RawKind != implicitObjectKind) return; // if there are too few or too many arguments, then don't bother checking. @@ -232,11 +243,12 @@ void CollectMatchingReferences( var constructor = state.SemanticModel.GetSymbolInfo(node, cancellationToken).Symbol; if (Matches(constructor, symbol)) { - var location = node.GetFirstToken().GetLocation(); - var symbolUsageInfo = GetSymbolUsageInfo(node, state, cancellationToken); - var result = new FinderLocation(node, new ReferenceLocation( - state.Document, alias: null, location, isImplicit: true, symbolUsageInfo, + state.Document, + alias: null, + newKeywordToken.GetLocation(), + isImplicit: true, + GetSymbolUsageInfo(node, state, cancellationToken), GetAdditionalFindUsagesProperties(node, state), CandidateReason.None)); processResult(result, processResultData); } diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Services/SyntaxFacts/CSharpSyntaxKinds.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Services/SyntaxFacts/CSharpSyntaxKinds.cs index c5e112ab1bc25..3aefcfa76563a 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Services/SyntaxFacts/CSharpSyntaxKinds.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/CSharp/Services/SyntaxFacts/CSharpSyntaxKinds.cs @@ -65,9 +65,10 @@ public int Convert(TSyntaxKind kind) where TSyntaxKind : struct public int XmlTextLiteralToken => (int)SyntaxKind.XmlTextLiteralToken; public int DelegateKeyword => (int)SyntaxKind.DelegateKeyword; + public int FalseKeyword => (int)SyntaxKind.FalseKeyword; public int IfKeyword => (int)SyntaxKind.IfKeyword; + public int NewKeyword => (int)SyntaxKind.NewKeyword; public int TrueKeyword => (int)SyntaxKind.TrueKeyword; - public int FalseKeyword => (int)SyntaxKind.FalseKeyword; public int UsingKeyword => (int)SyntaxKind.UsingKeyword; public int GenericName => (int)SyntaxKind.GenericName; diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Services/SyntaxFacts/ISyntaxKinds.cs b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Services/SyntaxFacts/ISyntaxKinds.cs index 4d304e6a3f4ae..ddaf52a46398e 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Services/SyntaxFacts/ISyntaxKinds.cs +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Services/SyntaxFacts/ISyntaxKinds.cs @@ -46,14 +46,15 @@ internal interface ISyntaxKinds #region keywords - int AwaitKeyword { get; } int AsyncKeyword { get; } + int AwaitKeyword { get; } int DelegateKeyword { get; } + int FalseKeyword { get; } int GlobalKeyword { get; } - int IfKeyword { get; } int? GlobalStatement { get; } + int IfKeyword { get; } + int NewKeyword { get; } int TrueKeyword { get; } - int FalseKeyword { get; } int UsingKeyword { get; } #endregion diff --git a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/VisualBasic/Services/SyntaxFacts/VisualBasicSyntaxKinds.vb b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/VisualBasic/Services/SyntaxFacts/VisualBasicSyntaxKinds.vb index 24f77d43ecd10..b6de084b165a3 100644 --- a/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/VisualBasic/Services/SyntaxFacts/VisualBasicSyntaxKinds.vb +++ b/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/VisualBasic/Services/SyntaxFacts/VisualBasicSyntaxKinds.vb @@ -67,9 +67,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.LanguageService Public ReadOnly Property XmlTextLiteralToken As Integer = SyntaxKind.XmlTextLiteralToken Implements ISyntaxKinds.XmlTextLiteralToken Public ReadOnly Property DelegateKeyword As Integer = SyntaxKind.DelegateKeyword Implements ISyntaxKinds.DelegateKeyword + Public ReadOnly Property FalseKeyword As Integer = SyntaxKind.FalseKeyword Implements ISyntaxKinds.FalseKeyword Public ReadOnly Property IfKeyword As Integer = SyntaxKind.IfKeyword Implements ISyntaxKinds.IfKeyword + Public ReadOnly Property NewKeyword As Integer = SyntaxKind.NewKeyword Implements ISyntaxKinds.NewKeyword Public ReadOnly Property TrueKeyword As Integer = SyntaxKind.TrueKeyword Implements ISyntaxKinds.TrueKeyword - Public ReadOnly Property FalseKeyword As Integer = SyntaxKind.FalseKeyword Implements ISyntaxKinds.FalseKeyword Public ReadOnly Property UsingKeyword As Integer = SyntaxKind.UsingKeyword Implements ISyntaxKinds.UsingKeyword Public ReadOnly Property GenericName As Integer = SyntaxKind.GenericName Implements ISyntaxKinds.GenericName From b8b677619172bc42c611a5d78bf7fa66db3fd851 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 21 May 2024 17:37:26 -0700 Subject: [PATCH 2/7] Search less tokens while finding constructors --- .../FindReferences/FindReferenceCache.cs | 55 +++++++++++-------- ...tructorInitializerSymbolReferenceFinder.cs | 2 +- .../ConstructorSymbolReferenceFinder.cs | 6 +- 3 files changed, 35 insertions(+), 28 deletions(-) diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/FindReferenceCache.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/FindReferenceCache.cs index 9793905be7415..f76b366efde47 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/FindReferenceCache.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/FindReferenceCache.cs @@ -68,6 +68,7 @@ static async Task ComputeCacheAsync(Document document, Cance private ImmutableHashSet? _aliasNameSet; private ImmutableArray _constructorInitializerCache; + private ImmutableArray _newKeywordsCache; private FindReferenceCache( Document document, SourceText text, SemanticModel semanticModel, SemanticModel nullableEnabledSemanticModel, SyntaxNode root, SyntaxTreeIndex syntaxTreeIndex) @@ -139,16 +140,12 @@ public ImmutableArray FindMatchingIdentifierTokens( return _identifierCache.GetOrAdd( identifier, - identifier => FindMatchingIdentifierTokensFromText( + identifier => FindMatchingTokensFromText( identifier, static (identifier, token, @this) => @this.IsMatch(identifier, token), this, cancellationToken)); } - public ImmutableArray FindMatchingTextTokens( - string text, Func isMatch, TArgs args, CancellationToken cancellationToken) - => _identifierCache.GetOrAdd(text, _ => FindMatchingIdentifierTokensFromText(text, isMatch, args, cancellationToken)); - private bool IsMatch(string identifier, SyntaxToken token) => !token.IsMissing && this.SyntaxFacts.IsIdentifier(token) && this.SyntaxFacts.TextMatch(token.ValueText, identifier); @@ -190,7 +187,7 @@ private ImmutableArray FindMatchingIdentifierTokensFromTree( return result.ToImmutableAndClear(); } - private ImmutableArray FindMatchingIdentifierTokensFromText( + private ImmutableArray FindMatchingTokensFromText( string text, Func isMatch, TArgs args, CancellationToken cancellationToken) { using var _ = ArrayBuilder.GetInstance(out var result); @@ -212,33 +209,47 @@ private ImmutableArray FindMatchingIdentifierTokensFromText( return result.ToImmutableAndClear(); } - public IEnumerable GetConstructorInitializerTokens( - ISyntaxFactsService syntaxFacts, SyntaxNode root, CancellationToken cancellationToken) + + public ImmutableArray GetConstructorInitializerTokens(CancellationToken cancellationToken) { // this one will only get called when we know given document contains constructor initializer. // no reason to use text to check whether it exist first. if (_constructorInitializerCache.IsDefault) - { - var initializers = GetConstructorInitializerTokensWorker(syntaxFacts, root, cancellationToken); - ImmutableInterlocked.InterlockedInitialize(ref _constructorInitializerCache, initializers); - } + ImmutableInterlocked.InterlockedInitialize(ref _constructorInitializerCache, GetConstructorInitializerTokensWorker()); return _constructorInitializerCache; - } - private static ImmutableArray GetConstructorInitializerTokensWorker( - ISyntaxFactsService syntaxFacts, SyntaxNode root, CancellationToken cancellationToken) - { - using var _ = ArrayBuilder.GetInstance(out var initializers); - foreach (var constructor in syntaxFacts.GetConstructors(root, cancellationToken)) + ImmutableArray GetConstructorInitializerTokensWorker() { - foreach (var token in constructor.DescendantTokens(descendIntoTrivia: false)) + var syntaxFacts = this.SyntaxFacts; + using var _ = ArrayBuilder.GetInstance(out var initializers); + foreach (var constructor in syntaxFacts.GetConstructors(this.Root, cancellationToken)) { - if (syntaxFacts.IsThisConstructorInitializer(token) || syntaxFacts.IsBaseConstructorInitializer(token)) - initializers.Add(token); + foreach (var token in constructor.DescendantTokens(descendIntoTrivia: false)) + { + if (syntaxFacts.IsThisConstructorInitializer(token) || syntaxFacts.IsBaseConstructorInitializer(token)) + initializers.Add(token); + } } + + return initializers.ToImmutableAndClear(); } + } + + public ImmutableArray GetNewKeywordTokens(CancellationToken cancellationToken) + { + if (_newKeywordsCache.IsDefault) + ImmutableInterlocked.InterlockedInitialize(ref _newKeywordsCache, GetNewKeywordTokensWorker()); + + return _newKeywordsCache; - return initializers.ToImmutableAndClear(); + ImmutableArray GetNewKeywordTokensWorker() + { + return this.FindMatchingTokensFromText( + this.SyntaxFacts.GetText(this.SyntaxFacts.SyntaxKinds.NewKeyword), + static (_, token, syntaxKinds) => token.RawKind == syntaxKinds.NewKeyword, + this.SyntaxFacts.SyntaxKinds, + cancellationToken); + } } } diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ConstructorInitializerSymbolReferenceFinder.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ConstructorInitializerSymbolReferenceFinder.cs index b15a9593de89c..1fcfdd74b8f02 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ConstructorInitializerSymbolReferenceFinder.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ConstructorInitializerSymbolReferenceFinder.cs @@ -59,7 +59,7 @@ protected sealed override void FindReferencesInDocument( FindReferencesSearchOptions options, CancellationToken cancellationToken) { - var tokens = state.Cache.GetConstructorInitializerTokens(state.SyntaxFacts, state.Root, cancellationToken); + var tokens = state.Cache.GetConstructorInitializerTokens(cancellationToken); if (state.SemanticModel.Language == LanguageNames.VisualBasic) tokens = tokens.Concat(FindMatchingIdentifierTokens(state, "New", cancellationToken)).Distinct(); diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ConstructorSymbolReferenceFinder.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ConstructorSymbolReferenceFinder.cs index 3c76b1548075d..3a88fc96b8d14 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ConstructorSymbolReferenceFinder.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ConstructorSymbolReferenceFinder.cs @@ -204,11 +204,7 @@ private static void FindReferencesInImplicitObjectCreationExpression( // insensitive matching here. // // Search for all the `new` tokens in the file. - var newKeywordTokens = state.Cache.FindMatchingTextTokens( - "new", - (_, token, syntaxKinds) => token.RawKind == syntaxKinds.NewKeyword, - state.SyntaxFacts.SyntaxKinds, - cancellationToken); + var newKeywordTokens = state.Cache.GetNewKeywordTokens(cancellationToken); if (newKeywordTokens.IsEmpty) return; From db2efaf2b7ec66e9e31b4e01c454728171797e42 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 21 May 2024 17:54:16 -0700 Subject: [PATCH 3/7] Make static --- .../FindReferences/Finders/ConstructorSymbolReferenceFinder.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ConstructorSymbolReferenceFinder.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ConstructorSymbolReferenceFinder.cs index 3a88fc96b8d14..224be8c2c8429 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ConstructorSymbolReferenceFinder.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ConstructorSymbolReferenceFinder.cs @@ -209,7 +209,7 @@ private static void FindReferencesInImplicitObjectCreationExpression( return; // Only check `new (...)` calls that supply enough arguments to match all the required parameters for the constructor. - var minimumArgumentCount = symbol.Parameters.Count(p => !p.IsOptional && !p.IsParams); + var minimumArgumentCount = symbol.Parameters.Count(static p => !p.IsOptional && !p.IsParams); var maximumArgumentCount = symbol.Parameters is [.., { IsParams: true }] ? int.MaxValue : symbol.Parameters.Length; From f11d4ca60b52bc82699c77bf4c8795810c7c02bd Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 21 May 2024 18:52:15 -0700 Subject: [PATCH 4/7] Continue not return --- .../FindReferencesTests.ConstructorSymbols.vb | 27 +++++++++++++++++++ .../ConstructorSymbolReferenceFinder.cs | 6 ++--- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/src/EditorFeatures/Test2/FindReferences/FindReferencesTests.ConstructorSymbols.vb b/src/EditorFeatures/Test2/FindReferences/FindReferencesTests.ConstructorSymbols.vb index 145f379319bc2..89cc1601bf898 100644 --- a/src/EditorFeatures/Test2/FindReferences/FindReferencesTests.ConstructorSymbols.vb +++ b/src/EditorFeatures/Test2/FindReferences/FindReferencesTests.ConstructorSymbols.vb @@ -872,6 +872,33 @@ class C Await TestAPIAndFeature(input, kind, host) End Function + + Public Async Function TestConstructor_ImplicitAndExplicitObjectCreation_Local(kind As TestKind, host As TestHost) As Task + Dim input = + + + +class D +{ + public {|Definition:$$D|}() { } +} + + +class C +{ + void M() + { + D d = [|new|](); + D d2 = new [|D|](); + D d3 = [|new|](); + } +} + + + + Await TestAPIAndFeature(input, kind, host) + End Function + Public Async Function TestConstructor_ImplicitObjectCreation_Local_WithArguments(kind As TestKind, host As TestHost) As Task Dim input = diff --git a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ConstructorSymbolReferenceFinder.cs b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ConstructorSymbolReferenceFinder.cs index 224be8c2c8429..a3724613a3df6 100644 --- a/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ConstructorSymbolReferenceFinder.cs +++ b/src/Workspaces/Core/Portable/FindSymbols/FindReferences/Finders/ConstructorSymbolReferenceFinder.cs @@ -225,16 +225,16 @@ private static void FindReferencesInImplicitObjectCreationExpression( var node = newKeywordToken.Parent; if (node is null || node.RawKind != implicitObjectKind) - return; + continue; // if there are too few or too many arguments, then don't bother checking. var actualArgumentCount = state.SyntaxFacts.GetArgumentsOfObjectCreationExpression(node).Count; if (actualArgumentCount < minimumArgumentCount || actualArgumentCount > maximumArgumentCount) - return; + continue; // if we need an exact count then make sure that the count we have fits the count we need. if (exactArgumentCount != -1 && exactArgumentCount != actualArgumentCount) - return; + continue; var constructor = state.SemanticModel.GetSymbolInfo(node, cancellationToken).Symbol; if (Matches(constructor, symbol)) From fd25ebc58b152191ee1173a02202f465009a6066 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 21 May 2024 21:20:27 -0700 Subject: [PATCH 5/7] Skip flakey test --- .../IntegrationTest/New.IntegrationTests/CSharp/CSharpRename.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/VisualStudio/IntegrationTest/New.IntegrationTests/CSharp/CSharpRename.cs b/src/VisualStudio/IntegrationTest/New.IntegrationTests/CSharp/CSharpRename.cs index a30f071de61ef..83dea6287ae2a 100644 --- a/src/VisualStudio/IntegrationTest/New.IntegrationTests/CSharp/CSharpRename.cs +++ b/src/VisualStudio/IntegrationTest/New.IntegrationTests/CSharp/CSharpRename.cs @@ -719,7 +719,7 @@ public class Class2 }", HangMitigatingCancellationToken); } - [IdeFact, WorkItem("https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1903953/")] + [IdeFact(Skip = "https://github.com/dotnet/roslyn/issues/73630"), WorkItem("https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1903953/")] public async Task VerifyRenameLinkedDocumentsAsync() { var globalOptions = await TestServices.Shell.GetComponentModelServiceAsync(HangMitigatingCancellationToken); From 37e781c368fdc584d5065c0b098efcb789fc00ce Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 21 May 2024 21:29:21 -0700 Subject: [PATCH 6/7] Raw strings --- .../CSharp/CSharpRename.cs | 68 ++++++++++--------- 1 file changed, 35 insertions(+), 33 deletions(-) diff --git a/src/VisualStudio/IntegrationTest/New.IntegrationTests/CSharp/CSharpRename.cs b/src/VisualStudio/IntegrationTest/New.IntegrationTests/CSharp/CSharpRename.cs index 83dea6287ae2a..39c1831c6fe82 100644 --- a/src/VisualStudio/IntegrationTest/New.IntegrationTests/CSharp/CSharpRename.cs +++ b/src/VisualStudio/IntegrationTest/New.IntegrationTests/CSharp/CSharpRename.cs @@ -725,33 +725,34 @@ public async Task VerifyRenameLinkedDocumentsAsync() var globalOptions = await TestServices.Shell.GetComponentModelServiceAsync(HangMitigatingCancellationToken); globalOptions.SetGlobalOption(InlineRenameUIOptionsStorage.UseInlineAdornment, true); var projectName = "MultiTFMProject"; - await TestServices.SolutionExplorer.AddCustomProjectAsync(projectName, ".csproj", @" - - - Exe - net6.0-windows;net48 - enable - enable - preview - - -", HangMitigatingCancellationToken); - - var startCode = @" -public class TestClass -{ -} -"; + await TestServices.SolutionExplorer.AddCustomProjectAsync(projectName, ".csproj", """ + + + Exe + net6.0-windows;net48 + enable + enable + preview + + + """, HangMitigatingCancellationToken); + + var startCode = """ + public class TestClass + { + } + """; await TestServices.SolutionExplorer.AddFileAsync(projectName, "TestClass.cs", startCode, cancellationToken: HangMitigatingCancellationToken); - var referencedCode = @" -public class MyClass -{ - void Method() - { - TestClass x = new TestClass(); - } -}"; + var referencedCode = """ + public class MyClass + { + void Method() + { + TestClass x = new TestClass(); + } + } + """; await TestServices.SolutionExplorer.AddFileAsync(projectName, "MyClass.cs", referencedCode, cancellationToken: HangMitigatingCancellationToken); // We made csproj changes, so need to wait for PS to finish all the tasks before moving on. await TestServices.Workspace.WaitForProjectSystemAsync(HangMitigatingCancellationToken); @@ -763,14 +764,15 @@ void Method() await TestServices.Input.SendWithoutActivateAsync([VirtualKeyCode.HOME, "M", "y", VirtualKeyCode.RETURN], HangMitigatingCancellationToken); await TestServices.Workspace.WaitForRenameAsync(HangMitigatingCancellationToken); await TestServices.EditorVerifier.TextEqualsAsync( - @" -public class MyClass -{ - void Method() - { - MyTestClass$$ x = new MyTestClass(); - } -}", HangMitigatingCancellationToken); + """ + public class MyClass + { + void Method() + { + MyTestClass$$ x = new MyTestClass(); + } + } + """, HangMitigatingCancellationToken); // Make sure the file is renamed. If the file is not found, this call would throw exception await TestServices.SolutionExplorer.GetProjectItemAsync(projectName, "MyTestClass.cs", HangMitigatingCancellationToken); } From 281dfab6228e3e7405573f7dc5887ed87dd91a52 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 21 May 2024 21:45:41 -0700 Subject: [PATCH 7/7] Raw strings --- .../CSharp/CSharpRename.cs | 747 +++++++++--------- 1 file changed, 389 insertions(+), 358 deletions(-) diff --git a/src/VisualStudio/IntegrationTest/New.IntegrationTests/CSharp/CSharpRename.cs b/src/VisualStudio/IntegrationTest/New.IntegrationTests/CSharp/CSharpRename.cs index 39c1831c6fe82..564e8c5dd959c 100644 --- a/src/VisualStudio/IntegrationTest/New.IntegrationTests/CSharp/CSharpRename.cs +++ b/src/VisualStudio/IntegrationTest/New.IntegrationTests/CSharp/CSharpRename.cs @@ -48,25 +48,26 @@ public override async Task InitializeAsync() [IdeFact] public async Task VerifyLocalVariableRename() { - var markup = @" -using System; -using System.Collections.Generic; -using System.Linq; + var markup = """ + using System; + using System.Collections.Generic; + using System.Linq; -class Program -{ - static void Main(string[] args) - { - int [|x|]$$ = 0; - [|x|] = 5; - TestMethod([|x|]); - } + class Program + { + static void Main(string[] args) + { + int [|x|]$$ = 0; + [|x|] = 5; + TestMethod([|x|]); + } - static void TestMethod(int y) - { + static void TestMethod(int y) + { - } -}"; + } + } + """; await using (var telemetry = await TestServices.Telemetry.EnableTestTelemetryChannelAsync(HangMitigatingCancellationToken)) { await SetUpEditorAsync(markup, HangMitigatingCancellationToken); @@ -79,25 +80,26 @@ static void TestMethod(int y) await TestServices.Input.SendWithoutActivateAsync([VirtualKeyCode.VK_Y, VirtualKeyCode.RETURN], HangMitigatingCancellationToken); await TestServices.Workspace.WaitForRenameAsync(HangMitigatingCancellationToken); - await TestServices.EditorVerifier.TextEqualsAsync(@" -using System; -using System.Collections.Generic; -using System.Linq; + await TestServices.EditorVerifier.TextEqualsAsync(""" + using System; + using System.Collections.Generic; + using System.Linq; -class Program -{ - static void Main(string[] args) - { - int y$$ = 0; - y = 5; - TestMethod(y); - } + class Program + { + static void Main(string[] args) + { + int y$$ = 0; + y = 5; + TestMethod(y); + } - static void TestMethod(int y) - { + static void TestMethod(int y) + { - } -}", HangMitigatingCancellationToken); + } + } + """, HangMitigatingCancellationToken); await telemetry.VerifyFiredAsync(["vs/ide/vbcs/rename/inlinesession/session", "vs/ide/vbcs/rename/commitcore"], HangMitigatingCancellationToken); } } @@ -105,13 +107,13 @@ static void TestMethod(int y) [IdeFact, WorkItem("https://github.com/dotnet/roslyn/issues/21657")] public async Task VerifyAttributeRename() { - var markup = @" -using System; + var markup = """ + using System; -class [|$$ustom|]Attribute : Attribute -{ -} -"; + class [|$$ustom|]Attribute : Attribute + { + } + """; await SetUpEditorAsync(markup, HangMitigatingCancellationToken); await TestServices.InlineRename.InvokeAsync(HangMitigatingCancellationToken); @@ -122,25 +124,25 @@ class [|$$ustom|]Attribute : Attribute await TestServices.Input.SendWithoutActivateAsync(["Custom", VirtualKeyCode.RETURN], HangMitigatingCancellationToken); await TestServices.Workspace.WaitForRenameAsync(HangMitigatingCancellationToken); - await TestServices.EditorVerifier.TextEqualsAsync(@" -using System; + await TestServices.EditorVerifier.TextEqualsAsync(""" + using System; -class Custom$$Attribute : Attribute -{ -} -", HangMitigatingCancellationToken); + class Custom$$Attribute : Attribute + { + } + """, HangMitigatingCancellationToken); } [IdeFact, WorkItem("https://github.com/dotnet/roslyn/issues/21657")] public async Task VerifyAttributeRenameWhileRenameClasss() { - var markup = @" -using System; + var markup = """ + using System; -class [|$$stom|]Attribute : Attribute -{ -} -"; + class [|$$stom|]Attribute : Attribute + { + } + """; await SetUpEditorAsync(markup, HangMitigatingCancellationToken); await TestServices.InlineRename.InvokeAsync(HangMitigatingCancellationToken); @@ -151,30 +153,30 @@ class [|$$stom|]Attribute : Attribute await TestServices.Input.SendWithoutActivateAsync("Custom", HangMitigatingCancellationToken); await TestServices.Workspace.WaitForRenameAsync(HangMitigatingCancellationToken); - await TestServices.EditorVerifier.TextEqualsAsync(@" -using System; + await TestServices.EditorVerifier.TextEqualsAsync(""" + using System; -class Custom$$Attribute : Attribute -{ -} -", HangMitigatingCancellationToken); + class Custom$$Attribute : Attribute + { + } + """, HangMitigatingCancellationToken); } [IdeFact, WorkItem("https://github.com/dotnet/roslyn/issues/21657")] public async Task VerifyAttributeRenameWhileRenameAttribute() { - var markup = @" -using System; + var markup = """ + using System; -[[|$$stom|]] -class Bar -{ -} + [[|$$stom|]] + class Bar + { + } -class [|stom|]Attribute : Attribute -{ -} -"; + class [|stom|]Attribute : Attribute + { + } + """; await SetUpEditorAsync(markup, HangMitigatingCancellationToken); await TestServices.InlineRename.InvokeAsync(HangMitigatingCancellationToken); @@ -185,35 +187,35 @@ class [|stom|]Attribute : Attribute await TestServices.Input.SendWithoutActivateAsync("Custom", HangMitigatingCancellationToken); await TestServices.Workspace.WaitForRenameAsync(HangMitigatingCancellationToken); - await TestServices.EditorVerifier.TextEqualsAsync(@" -using System; + await TestServices.EditorVerifier.TextEqualsAsync(""" + using System; -[Custom$$] -class Bar -{ -} + [Custom$$] + class Bar + { + } -class CustomAttribute : Attribute -{ -} -", HangMitigatingCancellationToken); + class CustomAttribute : Attribute + { + } + """, HangMitigatingCancellationToken); } [IdeFact, WorkItem("https://github.com/dotnet/roslyn/issues/21657")] public async Task VerifyAttributeRenameWhileRenameAttributeClass() { - var markup = @" -using System; + var markup = """ + using System; -[[|stom|]] -class Bar -{ -} + [[|stom|]] + class Bar + { + } -class [|$$stom|]Attribute : Attribute -{ -} -"; + class [|$$stom|]Attribute : Attribute + { + } + """; await SetUpEditorAsync(markup, HangMitigatingCancellationToken); await TestServices.InlineRename.InvokeAsync(HangMitigatingCancellationToken); @@ -224,18 +226,18 @@ class [|$$stom|]Attribute : Attribute await TestServices.Input.SendWithoutActivateAsync("Custom", HangMitigatingCancellationToken); await TestServices.Workspace.WaitForRenameAsync(HangMitigatingCancellationToken); - await TestServices.EditorVerifier.TextEqualsAsync(@" -using System; + await TestServices.EditorVerifier.TextEqualsAsync(""" + using System; -[Custom] -class Bar -{ -} + [Custom] + class Bar + { + } -class Custom$$Attribute : Attribute -{ -} -", HangMitigatingCancellationToken); + class Custom$$Attribute : Attribute + { + } + """, HangMitigatingCancellationToken); } [IdeFact] @@ -244,33 +246,34 @@ public async Task VerifyLocalVariableRenameWithCommentsUpdated() // "variable" is intentionally misspelled as "varixable" and "this" is misspelled as // "thix" below to ensure we don't change instances of "x" in comments that are part of // larger words - var markup = @" -using System; -using System.Collections.Generic; -using System.Linq; + var markup = """ + using System; + using System.Collections.Generic; + using System.Linq; -class Program -{ - /// - /// creates a varixable named [|x|] xx - /// - /// - static void Main(string[] args) - { - // thix varixable is named [|x|] xx - int [|x|]$$ = 0; - [|x|] = 5; - TestMethod([|x|]); - } + class Program + { + /// + /// creates a varixable named [|x|] xx + /// + /// + static void Main(string[] args) + { + // thix varixable is named [|x|] xx + int [|x|]$$ = 0; + [|x|] = 5; + TestMethod([|x|]); + } - static void TestMethod(int y) - { - /* - * [|x|] - * xx - */ - } -}"; + static void TestMethod(int y) + { + /* + * [|x|] + * xx + */ + } + } + """; await SetUpEditorAsync(markup, HangMitigatingCancellationToken); await TestServices.InlineRename.InvokeAsync(HangMitigatingCancellationToken); await TestServices.InlineRename.ToggleIncludeCommentsAsync(HangMitigatingCancellationToken); @@ -282,56 +285,58 @@ static void TestMethod(int y) await TestServices.Input.SendWithoutActivateAsync([VirtualKeyCode.VK_Y, VirtualKeyCode.RETURN], HangMitigatingCancellationToken); await TestServices.Workspace.WaitForRenameAsync(HangMitigatingCancellationToken); - await TestServices.EditorVerifier.TextEqualsAsync(@" -using System; -using System.Collections.Generic; -using System.Linq; + await TestServices.EditorVerifier.TextEqualsAsync(""" + using System; + using System.Collections.Generic; + using System.Linq; -class Program -{ - /// - /// creates a varixable named y xx - /// - /// - static void Main(string[] args) - { - // thix varixable is named y xx - int y$$ = 0; - y = 5; - TestMethod(y); - } + class Program + { + /// + /// creates a varixable named y xx + /// + /// + static void Main(string[] args) + { + // thix varixable is named y xx + int y$$ = 0; + y = 5; + TestMethod(y); + } - static void TestMethod(int y) - { - /* - * y - * xx - */ - } -}", HangMitigatingCancellationToken); + static void TestMethod(int y) + { + /* + * y + * xx + */ + } + } + """, HangMitigatingCancellationToken); } [IdeFact] public async Task VerifyLocalVariableRenameWithStringsUpdated() { - var markup = @" -class Program -{ - static void Main(string[] args) - { - int [|x|]$$ = 0; - [|x|] = 5; - var s = ""[|x|] xx [|x|]""; - var sLiteral = - @"" - [|x|] - xx - [|x|] - ""; - char c = 'x'; - char cUnit = '\u0078'; - } -}"; + var markup = """ + class Program + { + static void Main(string[] args) + { + int [|x|]$$ = 0; + [|x|] = 5; + var s = "[|x|] xx [|x|]"; + var sLiteral = + @" + [|x|] + xx + [|x|] + "; + char c = 'x'; + char cUnit = '\u0078'; + } + } + """; await SetUpEditorAsync(markup, HangMitigatingCancellationToken); await TestServices.InlineRename.InvokeAsync(HangMitigatingCancellationToken); @@ -344,44 +349,46 @@ static void Main(string[] args) await TestServices.Input.SendWithoutActivateAsync([VirtualKeyCode.VK_Y, VirtualKeyCode.RETURN], HangMitigatingCancellationToken); await TestServices.Workspace.WaitForRenameAsync(HangMitigatingCancellationToken); - await TestServices.EditorVerifier.TextEqualsAsync(@" -class Program -{ - static void Main(string[] args) - { - int y$$ = 0; - y = 5; - var s = ""y xx y""; - var sLiteral = - @"" - y - xx - y - ""; - char c = 'x'; - char cUnit = '\u0078'; - } -}", HangMitigatingCancellationToken); + await TestServices.EditorVerifier.TextEqualsAsync(""" + class Program + { + static void Main(string[] args) + { + int y$$ = 0; + y = 5; + var s = "y xx y"; + var sLiteral = + @" + y + xx + y + "; + char c = 'x'; + char cUnit = '\u0078'; + } + } + """, HangMitigatingCancellationToken); } [IdeFact] public async Task VerifyOverloadsUpdated() { - var markup = @" -interface I -{ - void [|TestMethod|]$$(int y); - void [|TestMethod|](string y); -} + var markup = """ + interface I + { + void [|TestMethod|]$$(int y); + void [|TestMethod|](string y); + } -class B : I -{ - public virtual void [|TestMethod|](int y) - { } + class B : I + { + public virtual void [|TestMethod|](int y) + { } - public virtual void [|TestMethod|](string y) - { } -}"; + public virtual void [|TestMethod|](string y) + { } + } + """; await SetUpEditorAsync(markup, HangMitigatingCancellationToken); await TestServices.InlineRename.InvokeAsync(HangMitigatingCancellationToken); @@ -394,41 +401,44 @@ class B : I await TestServices.Input.SendWithoutActivateAsync([VirtualKeyCode.VK_Y, VirtualKeyCode.RETURN], HangMitigatingCancellationToken); await TestServices.Workspace.WaitForRenameAsync(HangMitigatingCancellationToken); - await TestServices.EditorVerifier.TextEqualsAsync(@" -interface I -{ - void y$$(int y); - void y(string y); -} + await TestServices.EditorVerifier.TextEqualsAsync(""" + interface I + { + void y$$(int y); + void y(string y); + } -class B : I -{ - public virtual void y(int y) - { } + class B : I + { + public virtual void y(int y) + { } - public virtual void y(string y) - { } -}", HangMitigatingCancellationToken); + public virtual void y(string y) + { } + } + """, HangMitigatingCancellationToken); } [IdeFact] public async Task VerifyMultiFileRename() { - await SetUpEditorAsync(@" -class $$Program -{ -}", HangMitigatingCancellationToken); + await SetUpEditorAsync(""" + class $$Program + { + } + """, HangMitigatingCancellationToken); await TestServices.SolutionExplorer.AddFileAsync(ProjectName, "Class2.cs", @"", cancellationToken: HangMitigatingCancellationToken); await TestServices.SolutionExplorer.OpenFileAsync(ProjectName, "Class2.cs", HangMitigatingCancellationToken); - const string class2Markup = @" -class SomeOtherClass -{ - void M() - { - [|Program|] p = new [|Program|](); - } -}"; + const string class2Markup = """ + class SomeOtherClass + { + void M() + { + [|Program|] p = new [|Program|](); + } + } + """; MarkupTestFile.GetSpans(class2Markup, out var code, out var renameSpans); await TestServices.Editor.SetTextAsync(code, HangMitigatingCancellationToken); @@ -442,91 +452,100 @@ void M() await TestServices.Input.SendWithoutActivateAsync([VirtualKeyCode.VK_Y, VirtualKeyCode.RETURN], HangMitigatingCancellationToken); await TestServices.Workspace.WaitForRenameAsync(HangMitigatingCancellationToken); - await TestServices.EditorVerifier.TextEqualsAsync(@" -class SomeOtherClass -{ - void M() - { - y$$ p = new y(); - } -}", HangMitigatingCancellationToken); + await TestServices.EditorVerifier.TextEqualsAsync(""" + class SomeOtherClass + { + void M() + { + y$$ p = new y(); + } + } + """, HangMitigatingCancellationToken); await TestServices.SolutionExplorer.OpenFileAsync(ProjectName, "Class1.cs", HangMitigatingCancellationToken); - await TestServices.EditorVerifier.TextEqualsAsync(@" -class y$$ -{ -}", HangMitigatingCancellationToken); + await TestServices.EditorVerifier.TextEqualsAsync(""" + class y$$ + { + } + """, HangMitigatingCancellationToken); } [IdeFact] public async Task VerifyRenameCancellation() { - await SetUpEditorAsync(@" -class $$Program -{ -}", HangMitigatingCancellationToken); + await SetUpEditorAsync(""" + class $$Program + { + } + """, HangMitigatingCancellationToken); await TestServices.SolutionExplorer.AddFileAsync(ProjectName, "Class2.cs", @"", cancellationToken: HangMitigatingCancellationToken); await TestServices.SolutionExplorer.OpenFileAsync(ProjectName, "Class2.cs", HangMitigatingCancellationToken); - await TestServices.Editor.SetTextAsync(@" -class SomeOtherClass -{ - void M() - { - Program p = new Program(); - } -}", HangMitigatingCancellationToken); + await TestServices.Editor.SetTextAsync(""" + class SomeOtherClass + { + void M() + { + Program p = new Program(); + } + } + """, HangMitigatingCancellationToken); await TestServices.Editor.PlaceCaretAsync("Program", charsOffset: 0, HangMitigatingCancellationToken); await TestServices.InlineRename.InvokeAsync(HangMitigatingCancellationToken); await TestServices.Input.SendWithoutActivateAsync(VirtualKeyCode.VK_Y, HangMitigatingCancellationToken); await TestServices.Workspace.WaitForRenameAsync(HangMitigatingCancellationToken); - await TestServices.EditorVerifier.TextEqualsAsync(@" -class SomeOtherClass -{ - void M() - { - y$$ p = new y(); - } -}", HangMitigatingCancellationToken); + await TestServices.EditorVerifier.TextEqualsAsync(""" + class SomeOtherClass + { + void M() + { + y$$ p = new y(); + } + } + """, HangMitigatingCancellationToken); await TestServices.SolutionExplorer.OpenFileAsync(ProjectName, "Class1.cs", HangMitigatingCancellationToken); - await TestServices.EditorVerifier.TextEqualsAsync(@" -class y$$ -{ -}", HangMitigatingCancellationToken); + await TestServices.EditorVerifier.TextEqualsAsync(""" + class y$$ + { + } + """, HangMitigatingCancellationToken); await TestServices.Input.SendWithoutActivateAsync(VirtualKeyCode.ESCAPE, HangMitigatingCancellationToken); await TestServices.Workspace.WaitForRenameAsync(HangMitigatingCancellationToken); - await TestServices.EditorVerifier.TextEqualsAsync(@" -class Program$$ -{ -}", HangMitigatingCancellationToken); + await TestServices.EditorVerifier.TextEqualsAsync(""" + class Program$$ + { + } + """, HangMitigatingCancellationToken); await TestServices.SolutionExplorer.OpenFileAsync(ProjectName, "Class2.cs", HangMitigatingCancellationToken); - await TestServices.EditorVerifier.TextEqualsAsync(@" -class SomeOtherClass -{ - void M() - { - Program$$ p = new Program(); - } -}", HangMitigatingCancellationToken); + await TestServices.EditorVerifier.TextEqualsAsync(""" + class SomeOtherClass + { + void M() + { + Program$$ p = new Program(); + } + } + """, HangMitigatingCancellationToken); } [IdeFact] public async Task VerifyCrossProjectRename() { - await SetUpEditorAsync(@" -$$class RenameRocks -{ - static void Main(string[] args) - { - Class2 c = null; - c.ToString(); - } -}", HangMitigatingCancellationToken); + await SetUpEditorAsync(""" + $$class RenameRocks + { + static void Main(string[] args) + { + Class2 c = null; + c.ToString(); + } + } + """, HangMitigatingCancellationToken); var project1 = ProjectName; var project2 = "Project2"; @@ -545,15 +564,16 @@ public class Class2 { static void Main(string [] args) { } }", HangMitigatingCan await TestServices.InlineRename.InvokeAsync(HangMitigatingCancellationToken); await TestServices.Input.SendWithoutActivateAsync([VirtualKeyCode.VK_Y, VirtualKeyCode.RETURN], HangMitigatingCancellationToken); await TestServices.Workspace.WaitForRenameAsync(HangMitigatingCancellationToken); - await TestServices.EditorVerifier.TextEqualsAsync(@" -class RenameRocks -{ - static void Main(string[] args) - { - y$$ c = null; - c.ToString(); - } -}", HangMitigatingCancellationToken); + await TestServices.EditorVerifier.TextEqualsAsync(""" + class RenameRocks + { + static void Main(string[] args) + { + y$$ c = null; + c.ToString(); + } + } + """, HangMitigatingCancellationToken); await TestServices.SolutionExplorer.OpenFileAsync(project2, "y.cs", HangMitigatingCancellationToken); await TestServices.EditorVerifier.TextEqualsAsync(@" @@ -571,15 +591,16 @@ await TestServices.EditorVerifier.TextEqualsAsync(@" public class Class2 { static void Main(string [] args) { } }$$", HangMitigatingCancellationToken); await TestServices.SolutionExplorer.OpenFileAsync(ProjectName, "Class1.cs", HangMitigatingCancellationToken); - await TestServices.EditorVerifier.TextEqualsAsync(@" -class RenameRocks -{ - static void Main(string[] args) - { - Class2$$ c = null; - c.ToString(); - } -}", HangMitigatingCancellationToken); + await TestServices.EditorVerifier.TextEqualsAsync(""" + class RenameRocks + { + static void Main(string[] args) + { + Class2$$ c = null; + c.ToString(); + } + } + """, HangMitigatingCancellationToken); } [IdeFact] @@ -587,43 +608,46 @@ public async Task VerifyRenameInStandaloneFiles() { await TestServices.SolutionExplorer.CloseSolutionAsync(HangMitigatingCancellationToken); await TestServices.SolutionExplorer.AddStandaloneFileAsync("StandaloneFile1.cs", HangMitigatingCancellationToken); - await TestServices.Editor.SetTextAsync(@" -class Program -{ - void Goo() - { - var ids = 1; - ids = 2; - } -}", HangMitigatingCancellationToken); + await TestServices.Editor.SetTextAsync(""" + class Program + { + void Goo() + { + var ids = 1; + ids = 2; + } + } + """, HangMitigatingCancellationToken); await TestServices.Editor.PlaceCaretAsync("ids", charsOffset: 0, HangMitigatingCancellationToken); await TestServices.InlineRename.InvokeAsync(HangMitigatingCancellationToken); await TestServices.Input.SendWithoutActivateAsync([VirtualKeyCode.VK_Y, VirtualKeyCode.RETURN], HangMitigatingCancellationToken); await TestServices.Workspace.WaitForRenameAsync(HangMitigatingCancellationToken); - await TestServices.EditorVerifier.TextEqualsAsync(@" -class Program -{ - void Goo() - { - var y$$ = 1; - y = 2; - } -}", HangMitigatingCancellationToken); + await TestServices.EditorVerifier.TextEqualsAsync(""" + class Program + { + void Goo() + { + var y$$ = 1; + y = 2; + } + } + """, HangMitigatingCancellationToken); } [IdeFact, WorkItem("https://github.com/dotnet/roslyn/issues/39617")] public async Task VerifyRenameCaseChange() { await TestServices.SolutionExplorer.AddFileAsync(ProjectName, "Program.cs", -@" -class Program -{ - static void Main(string[] args) - { - } -}", cancellationToken: HangMitigatingCancellationToken); + """ + class Program + { + static void Main(string[] args) + { + } + } + """, cancellationToken: HangMitigatingCancellationToken); await TestServices.SolutionExplorer.OpenFileAsync(ProjectName, "Program.cs", HangMitigatingCancellationToken); await TestServices.Editor.PlaceCaretAsync("Program", charsOffset: 0, HangMitigatingCancellationToken); @@ -634,13 +658,14 @@ static void Main(string[] args) await TestServices.Workspace.WaitForRenameAsync(HangMitigatingCancellationToken); await TestServices.EditorVerifier.TextEqualsAsync( - @" -class p$$rogram -{ - static void Main(string[] args) - { - } -}", HangMitigatingCancellationToken); + """ + class p$$rogram + { + static void Main(string[] args) + { + } + } + """, HangMitigatingCancellationToken); } [IdeFact] @@ -649,11 +674,12 @@ public async Task VerifyTextSync() var globalOptions = await TestServices.Shell.GetComponentModelServiceAsync(HangMitigatingCancellationToken); globalOptions.SetGlobalOption(InlineRenameUIOptionsStorage.UseInlineAdornment, true); await TestServices.SolutionExplorer.AddFileAsync(ProjectName, "Program.cs", -@" -public class Class2 -{ - public int Field123; -}", cancellationToken: HangMitigatingCancellationToken); + """ + public class Class2 + { + public int Field123; + } + """, cancellationToken: HangMitigatingCancellationToken); await TestServices.SolutionExplorer.OpenFileAsync(ProjectName, "Program.cs", HangMitigatingCancellationToken); await TestServices.Editor.PlaceCaretAsync("Field123", charsOffset: 0, HangMitigatingCancellationToken); @@ -661,22 +687,24 @@ public class Class2 await TestServices.Input.SendWithoutActivateAsync(["F", "i"], HangMitigatingCancellationToken); await TestServices.Workspace.WaitForRenameAsync(HangMitigatingCancellationToken); await TestServices.EditorVerifier.TextEqualsAsync( - @" -public class Class2 -{ - public int Fi$$; -}", HangMitigatingCancellationToken); + """ + public class Class2 + { + public int Fi$$; + } + """, HangMitigatingCancellationToken); await TestServices.InlineRename.VerifyStringInFlyout("Fi", HangMitigatingCancellationToken); await TestServices.Input.SendWithoutActivateAsync(["e", "l", "d", "3", "2", "1"], HangMitigatingCancellationToken); await TestServices.Workspace.WaitForRenameAsync(HangMitigatingCancellationToken); await TestServices.EditorVerifier.TextEqualsAsync( - @" -public class Class2 -{ - public int Field321$$; -}", HangMitigatingCancellationToken); + """ + public class Class2 + { + public int Field321$$; + } + """, HangMitigatingCancellationToken); await TestServices.InlineRename.VerifyStringInFlyout("Field321", HangMitigatingCancellationToken); } @@ -685,13 +713,14 @@ public async Task VerifySelectionAsync() { var globalOptions = await TestServices.Shell.GetComponentModelServiceAsync(HangMitigatingCancellationToken); globalOptions.SetGlobalOption(InlineRenameUIOptionsStorage.UseInlineAdornment, true); - var startCode = @" -public class Class2 -{ - public int LongLongField; -}"; + var startCode = """ + public class Class2 + { + public int LongLongField; + } + """; await TestServices.SolutionExplorer.AddFileAsync(ProjectName, "Program.cs", -startCode, cancellationToken: HangMitigatingCancellationToken); + startCode, cancellationToken: HangMitigatingCancellationToken); await TestServices.SolutionExplorer.OpenFileAsync(ProjectName, "Program.cs", HangMitigatingCancellationToken); await TestServices.Editor.PlaceCaretAsync("LongLongField", charsOffset: 0, HangMitigatingCancellationToken); @@ -700,11 +729,12 @@ await TestServices.SolutionExplorer.AddFileAsync(ProjectName, "Program.cs", await TestServices.Editor.SendExplicitFocusAsync(HangMitigatingCancellationToken); await TestServices.Editor.PlaceCaretAsync("LongLongField", charsOffset: "Long".Length, HangMitigatingCancellationToken); - var markedCode = @" -public class Class2 -{ - public int Long{|selection:Long|}Field; -}"; + var markedCode = """ + public class Class2 + { + public int Long{|selection:Long|}Field; + } + """; MarkupTestFile.GetPositionAndSpans(markedCode, out var _, out int? _, out var spans); var selectedSpan = spans["selection"].Single(); await TestServices.Editor.SetSelectionAsync(selectedSpan, HangMitigatingCancellationToken); @@ -712,11 +742,12 @@ await TestServices.Input.SendWithoutActivateAsync( new InputKey(VirtualKeyCode.BACK, ImmutableArray.Empty), HangMitigatingCancellationToken); await TestServices.Input.SendWithoutActivateAsync(["Other", "Stuff"], HangMitigatingCancellationToken); await TestServices.EditorVerifier.TextEqualsAsync( - @" -public class Class2 -{ - public int LongOtherStuff$$Field; -}", HangMitigatingCancellationToken); + """ + public class Class2 + { + public int LongOtherStuff$$Field; + } + """, HangMitigatingCancellationToken); } [IdeFact(Skip = "https://github.com/dotnet/roslyn/issues/73630"), WorkItem("https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1903953/")]