From 58c84301a32145c2cd00a034d8100d11a877b6f8 Mon Sep 17 00:00:00 2001 From: akhera99 Date: Wed, 16 Jul 2025 09:54:30 -0700 Subject: [PATCH 1/6] fix bug --- .../Test2/Rename/InlineRenameTests.vb | 54 +++++++++++++++++++ .../InlineRename/InlineRenameUndoManager.cs | 22 +++++++- 2 files changed, 75 insertions(+), 1 deletion(-) diff --git a/src/EditorFeatures/Test2/Rename/InlineRenameTests.vb b/src/EditorFeatures/Test2/Rename/InlineRenameTests.vb index 0d6e86c3b498f..78dc6db6ff8d9 100644 --- a/src/EditorFeatures/Test2/Rename/InlineRenameTests.vb +++ b/src/EditorFeatures/Test2/Rename/InlineRenameTests.vb @@ -2473,5 +2473,59 @@ class [|C|] , host:=host, renameTo:="MyNewProperty") End Using End Sub + + + + Public Sub RenameClassWithAttributeName(host As RenameTestHost) + Using result = RenameEngineResult.Create(_outputHelper, + + + + + + + , host:=host, renameTo:="MyClassAttribute2") + End Using + End Sub + + + + Public Async Function RenameClassWithAttributeName2(host As RenameTestHost) As Task + Using workspace = CreateWorkspaceWithWaiter( + + + + public class [|MyClassAttribute$$|] : System.Attribute + { + public [|MyClassAttribute|]() + { + + } + } + + + , host) + + Dim session = StartSession(workspace) + + ' Type a bit in the file + Dim caretPosition = workspace.Documents.Single(Function(d) d.CursorPosition.HasValue).CursorPosition.Value + Dim textBuffer = workspace.Documents.Single().GetTextBuffer() + + textBuffer.Insert(caretPosition, "2") + + Await session.CommitAsync(previewChanges:=False, editorOperationContext:=Nothing) + + Await VerifyTagsAreCorrect(workspace) + End Using + End Function End Class End Namespace diff --git a/src/VisualStudio/Core/Def/InlineRename/InlineRenameUndoManager.cs b/src/VisualStudio/Core/Def/InlineRename/InlineRenameUndoManager.cs index 3548aa6d7dc5a..5e8fc9cb0ee53 100644 --- a/src/VisualStudio/Core/Def/InlineRename/InlineRenameUndoManager.cs +++ b/src/VisualStudio/Core/Def/InlineRename/InlineRenameUndoManager.cs @@ -15,6 +15,9 @@ using Microsoft.CodeAnalysis.ErrorReporting; using Microsoft.CodeAnalysis.Host; using Microsoft.CodeAnalysis.Host.Mef; +using Microsoft.CodeAnalysis.LanguageService; +using Microsoft.CodeAnalysis.Shared.Extensions; +using Microsoft.CodeAnalysis.Text; using Microsoft.VisualStudio.Editor; using Microsoft.VisualStudio.OLE.Interop; using Microsoft.VisualStudio.Text; @@ -171,7 +174,14 @@ public void ApplyCurrentState(ITextBuffer subjectBuffer, object propagateSpansEd return; } - ApplyReplacementText(subjectBuffer, bufferUndoState.TextUndoHistory, propagateSpansEditTag, spans, this.currentState.ReplacementText); + var document = subjectBuffer.CurrentSnapshot.GetOpenDocumentInCurrentContextWithChanges(); + if (document is null) + { + return; + } + + ApplyReplacementText(subjectBuffer, bufferUndoState.TextUndoHistory, propagateSpansEditTag, spans, + GetWithoutAttributeSuffix(currentState.ReplacementText, document.GetLanguageService().IsCaseSensitive)); // Here we create the descriptions for the redo list dropdown. var undoManager = bufferUndoState.UndoManager; @@ -230,5 +240,15 @@ private static IEnumerable GetUndoUnits(IOleUndoManager undoManage } } } + + private static string GetWithoutAttributeSuffix(string text, bool isCaseSensitive) + { + if (!text.TryGetWithoutAttributeSuffix(isCaseSensitive, out var replaceText)) + { + replaceText = text; + } + + return replaceText; + } } } From 9b09b23f0da7bc516e6b7aaf6806efc82fa33702 Mon Sep 17 00:00:00 2001 From: akhera99 Date: Wed, 16 Jul 2025 09:58:40 -0700 Subject: [PATCH 2/6] update test --- src/EditorFeatures/Test2/Rename/InlineRenameTests.vb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/EditorFeatures/Test2/Rename/InlineRenameTests.vb b/src/EditorFeatures/Test2/Rename/InlineRenameTests.vb index 78dc6db6ff8d9..2013f15300b3b 100644 --- a/src/EditorFeatures/Test2/Rename/InlineRenameTests.vb +++ b/src/EditorFeatures/Test2/Rename/InlineRenameTests.vb @@ -2503,7 +2503,7 @@ class [|C|] - public class [|MyClassAttribute$$|] : System.Attribute + public class [|MyClass$$Attribute|] : System.Attribute { public [|MyClassAttribute|]() { From 42095984ed30a9567bc1fc656cd86f3701bb61de Mon Sep 17 00:00:00 2001 From: akhera99 Date: Wed, 16 Jul 2025 11:50:38 -0700 Subject: [PATCH 3/6] simplify --- .../Core/Def/InlineRename/InlineRenameUndoManager.cs | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/src/VisualStudio/Core/Def/InlineRename/InlineRenameUndoManager.cs b/src/VisualStudio/Core/Def/InlineRename/InlineRenameUndoManager.cs index 5e8fc9cb0ee53..3db8bccd13094 100644 --- a/src/VisualStudio/Core/Def/InlineRename/InlineRenameUndoManager.cs +++ b/src/VisualStudio/Core/Def/InlineRename/InlineRenameUndoManager.cs @@ -181,7 +181,7 @@ public void ApplyCurrentState(ITextBuffer subjectBuffer, object propagateSpansEd } ApplyReplacementText(subjectBuffer, bufferUndoState.TextUndoHistory, propagateSpansEditTag, spans, - GetWithoutAttributeSuffix(currentState.ReplacementText, document.GetLanguageService().IsCaseSensitive)); + currentState.ReplacementText.GetWithoutAttributeSuffix(document.GetLanguageService().IsCaseSensitive) ?? currentState.ReplacementText); // Here we create the descriptions for the redo list dropdown. var undoManager = bufferUndoState.UndoManager; @@ -240,15 +240,5 @@ private static IEnumerable GetUndoUnits(IOleUndoManager undoManage } } } - - private static string GetWithoutAttributeSuffix(string text, bool isCaseSensitive) - { - if (!text.TryGetWithoutAttributeSuffix(isCaseSensitive, out var replaceText)) - { - replaceText = text; - } - - return replaceText; - } } } From c838f652371b6e50ab5ab772ae898b1910f24524 Mon Sep 17 00:00:00 2001 From: akhera99 Date: Wed, 16 Jul 2025 11:55:47 -0700 Subject: [PATCH 4/6] comment --- .../Core/Def/InlineRename/InlineRenameUndoManager.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/VisualStudio/Core/Def/InlineRename/InlineRenameUndoManager.cs b/src/VisualStudio/Core/Def/InlineRename/InlineRenameUndoManager.cs index 3db8bccd13094..e4e31dcdf0cdb 100644 --- a/src/VisualStudio/Core/Def/InlineRename/InlineRenameUndoManager.cs +++ b/src/VisualStudio/Core/Def/InlineRename/InlineRenameUndoManager.cs @@ -180,6 +180,9 @@ public void ApplyCurrentState(ITextBuffer subjectBuffer, object propagateSpansEd return; } + // This is where we apply the replacement text to each inline preview in the buffer. + // Needs to remove the "Attribute" suffix since the inline preview does not include the "Attribute" suffix in the replacement span + // so that the user does not see the suffix twice. ApplyReplacementText(subjectBuffer, bufferUndoState.TextUndoHistory, propagateSpansEditTag, spans, currentState.ReplacementText.GetWithoutAttributeSuffix(document.GetLanguageService().IsCaseSensitive) ?? currentState.ReplacementText); From 9dc8b6b1956b290815d622e1a17565f09a80650f Mon Sep 17 00:00:00 2001 From: akhera99 Date: Wed, 16 Jul 2025 11:57:27 -0700 Subject: [PATCH 5/6] clarity --- .../Core/Def/InlineRename/InlineRenameUndoManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/VisualStudio/Core/Def/InlineRename/InlineRenameUndoManager.cs b/src/VisualStudio/Core/Def/InlineRename/InlineRenameUndoManager.cs index e4e31dcdf0cdb..78620f4fce420 100644 --- a/src/VisualStudio/Core/Def/InlineRename/InlineRenameUndoManager.cs +++ b/src/VisualStudio/Core/Def/InlineRename/InlineRenameUndoManager.cs @@ -181,7 +181,7 @@ public void ApplyCurrentState(ITextBuffer subjectBuffer, object propagateSpansEd } // This is where we apply the replacement text to each inline preview in the buffer. - // Needs to remove the "Attribute" suffix since the inline preview does not include the "Attribute" suffix in the replacement span + // Needs to remove the "Attribute" suffix, since the inline preview does not include the "Attribute" suffix in the replacement span, // so that the user does not see the suffix twice. ApplyReplacementText(subjectBuffer, bufferUndoState.TextUndoHistory, propagateSpansEditTag, spans, currentState.ReplacementText.GetWithoutAttributeSuffix(document.GetLanguageService().IsCaseSensitive) ?? currentState.ReplacementText); From 86ff202a85345bd314ae3bc5bf11740836765239 Mon Sep 17 00:00:00 2001 From: akhera99 Date: Wed, 16 Jul 2025 12:57:00 -0700 Subject: [PATCH 6/6] gracefully handle the document or languageservice being null --- .../Core/Def/InlineRename/InlineRenameUndoManager.cs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/VisualStudio/Core/Def/InlineRename/InlineRenameUndoManager.cs b/src/VisualStudio/Core/Def/InlineRename/InlineRenameUndoManager.cs index 78620f4fce420..ad7fce549b32a 100644 --- a/src/VisualStudio/Core/Def/InlineRename/InlineRenameUndoManager.cs +++ b/src/VisualStudio/Core/Def/InlineRename/InlineRenameUndoManager.cs @@ -175,16 +175,13 @@ public void ApplyCurrentState(ITextBuffer subjectBuffer, object propagateSpansEd } var document = subjectBuffer.CurrentSnapshot.GetOpenDocumentInCurrentContextWithChanges(); - if (document is null) - { - return; - } + var isCaseSensitive = document?.GetLanguageService()?.IsCaseSensitive ?? true; // This is where we apply the replacement text to each inline preview in the buffer. // Needs to remove the "Attribute" suffix, since the inline preview does not include the "Attribute" suffix in the replacement span, // so that the user does not see the suffix twice. ApplyReplacementText(subjectBuffer, bufferUndoState.TextUndoHistory, propagateSpansEditTag, spans, - currentState.ReplacementText.GetWithoutAttributeSuffix(document.GetLanguageService().IsCaseSensitive) ?? currentState.ReplacementText); + currentState.ReplacementText.GetWithoutAttributeSuffix(isCaseSensitive) ?? currentState.ReplacementText); // Here we create the descriptions for the redo list dropdown. var undoManager = bufferUndoState.UndoManager;