File: VisualBasic\BasicRename.cs
Web Access
Project: ..\..\..\src\VisualStudio\IntegrationTest\New.IntegrationTests\Microsoft.VisualStudio.LanguageServices.New.IntegrationTests.csproj (Microsoft.VisualStudio.LanguageServices.New.IntegrationTests)
// Licensed to the .NET Foundation under one or more agreements.
// 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.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Editor.InlineRename;
using Microsoft.CodeAnalysis.InlineRename;
using Microsoft.CodeAnalysis.Options;
using Microsoft.CodeAnalysis.Test.Utilities;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Test.Utilities;
using Roslyn.VisualStudio.IntegrationTests;
using Roslyn.VisualStudio.IntegrationTests.InProcess;
using WindowsInput.Native;
using Xunit;
using Xunit.Sdk;
 
namespace Roslyn.VisualStudio.NewIntegrationTests.VisualBasic
{
    [Trait(Traits.Feature, Traits.Features.Rename)]
    public class BasicRename : AbstractEditorTest
    {
        protected override string LanguageName => LanguageNames.VisualBasic;
 
        public BasicRename()
            : base(nameof(BasicRename))
        {
        }
 
        public override async Task InitializeAsync()
        {
            await base.InitializeAsync();
 
            // reset relevant global options to default values:
            var globalOptions = await TestServices.Shell.GetComponentModelServiceAsync<IGlobalOptionService>(HangMitigatingCancellationToken);
            globalOptions.SetGlobalOption(InlineRenameUIOptionsStorage.UseInlineAdornment, false);
            globalOptions.SetGlobalOption(InlineRenameSessionOptionsStorage.RenameInComments, false);
            globalOptions.SetGlobalOption(InlineRenameSessionOptionsStorage.RenameInStrings, false);
            globalOptions.SetGlobalOption(InlineRenameSessionOptionsStorage.RenameOverloads, false);
            globalOptions.SetGlobalOption(InlineRenameSessionOptionsStorage.RenameFile, true);
            globalOptions.SetGlobalOption(InlineRenameSessionOptionsStorage.PreviewChanges, false);
        }
 
        [IdeFact]
        public async Task VerifyLocalVariableRename()
        {
            var markup = @"
Imports System
Imports System.Collections.Generic
Imports System.Linq
 
Module Program
    Sub Main(args As String())
        Dim [|x|]$$ As Integer = 0
        [|x|] = 5
        TestMethod([|x|])
    End Sub
    Sub TestMethod(y As Integer)
 
    End Sub
End Module";
            await SetUpEditorAsync(markup, HangMitigatingCancellationToken);
            await TestServices.InlineRename.InvokeAsync(HangMitigatingCancellationToken);
 
            MarkupTestFile.GetSpans(markup, out var _, out ImmutableArray<TextSpan> renameSpans);
            var tags = await TestServices.Editor.GetRenameTagsAsync(HangMitigatingCancellationToken);
            var tagSpans = tags.SelectAsArray(tag => new TextSpan(tag.Span.Start, tag.Span.Length));
            AssertEx.SetEqual(renameSpans, tagSpans);
 
            await TestServices.Input.SendWithoutActivateAsync(new InputKey[] { VirtualKeyCode.VK_Y, VirtualKeyCode.RETURN }, HangMitigatingCancellationToken);
            await TestServices.Workspace.WaitForRenameAsync(HangMitigatingCancellationToken);
            await TestServices.EditorVerifier.TextEqualsAsync(@"
Imports System
Imports System.Collections.Generic
Imports System.Linq
 
Module Program
    Sub Main(args As String())
        Dim y$$ As Integer = 0
        y = 5
        TestMethod(y)
    End Sub
    Sub TestMethod(y As Integer)
 
    End Sub
End Module", HangMitigatingCancellationToken);
        }
 
        [IdeFact]
        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 = @"
Imports System
Imports System.Collections.Generic
Imports System.Linq
 
Module Program
    ''' <summary>
    ''' creates a varixable named [|x|] xx
    ''' </summary>
    ''' <param name=""args""></param>
    Sub Main(args As String())
        ' thix varixable is named [|x|] xx
        Dim [|x|]$$ As Integer = 0
        [|x|] = 5
        TestMethod([|x|])
End Module";
            await SetUpEditorAsync(markup, HangMitigatingCancellationToken);
            await TestServices.InlineRename.InvokeAsync(HangMitigatingCancellationToken);
            await TestServices.InlineRename.ToggleIncludeCommentsAsync(HangMitigatingCancellationToken);
 
            MarkupTestFile.GetSpans(markup, out var _, out ImmutableArray<TextSpan> renameSpans);
            var tags = await TestServices.Editor.GetRenameTagsAsync(HangMitigatingCancellationToken);
            var tagSpans = tags.SelectAsArray(tag => new TextSpan(tag.Span.Start, tag.Span.Length));
            AssertEx.SetEqual(renameSpans, tagSpans);
 
            await TestServices.Input.SendWithoutActivateAsync(new InputKey[] { VirtualKeyCode.VK_Y, VirtualKeyCode.RETURN }, HangMitigatingCancellationToken);
            await TestServices.Workspace.WaitForRenameAsync(HangMitigatingCancellationToken);
            await TestServices.EditorVerifier.TextEqualsAsync(@"
Imports System
Imports System.Collections.Generic
Imports System.Linq
 
Module Program
    ''' <summary>
    ''' creates a varixable named y xx
    ''' </summary>
    ''' <param name=""args""></param>
    Sub Main(args As String())
        ' thix varixable is named y xx
        Dim y$$ As Integer = 0
        y = 5
        TestMethod(y)
End Module", HangMitigatingCancellationToken);
        }
 
        [IdeFact]
        public async Task VerifyLocalVariableRenameWithStringsUpdated()
        {
            var markup = @"
Imports System
Imports System.Collections.Generic
Imports System.Linq
 
Module Program
    Sub Main(args As String())
        Dim [|x|]$$ As Integer = 0
        [|x|] = 5
        Dim s = ""[|x|] xx [|x|]""
    End Sub
End Module";
            await SetUpEditorAsync(markup, HangMitigatingCancellationToken);
 
            await TestServices.InlineRename.InvokeAsync(HangMitigatingCancellationToken);
            await TestServices.InlineRename.ToggleIncludeStringsAsync(HangMitigatingCancellationToken);
 
            MarkupTestFile.GetSpans(markup, out var _, out ImmutableArray<TextSpan> renameSpans);
            var tags = await TestServices.Editor.GetRenameTagsAsync(HangMitigatingCancellationToken);
            var tagSpans = tags.SelectAsArray(tag => new TextSpan(tag.Span.Start, tag.Span.Length));
            AssertEx.SetEqual(renameSpans, tagSpans);
 
            await TestServices.Input.SendWithoutActivateAsync(new InputKey[] { VirtualKeyCode.VK_Y, VirtualKeyCode.RETURN }, HangMitigatingCancellationToken);
            await TestServices.Workspace.WaitForRenameAsync(HangMitigatingCancellationToken);
            await TestServices.EditorVerifier.TextEqualsAsync(@"
Imports System
Imports System.Collections.Generic
Imports System.Linq
 
Module Program
    Sub Main(args As String())
        Dim y$$ As Integer = 0
        y = 5
        Dim s = ""y xx y""
    End Sub
End Module", HangMitigatingCancellationToken);
        }
 
        [IdeFact]
        public async Task VerifyOverloadsUpdated()
        {
            var markup = @"
Interface I
    Sub [|TestMethod|]$$(y As Integer)
    Sub [|TestMethod|](y As String)
End Interface
 
Public MustInherit Class A
    Implements I
    Public MustOverride Sub [|TestMethod|](y As Integer) Implements I.[|TestMethod|]
    Public MustOverride Sub [|TestMethod|](y As String) Implements I.[|TestMethod|]
End Class";
            await SetUpEditorAsync(markup, HangMitigatingCancellationToken);
 
            await TestServices.InlineRename.InvokeAsync(HangMitigatingCancellationToken);
            await TestServices.InlineRename.ToggleIncludeOverloadsAsync(HangMitigatingCancellationToken);
 
            MarkupTestFile.GetSpans(markup, out var _, out ImmutableArray<TextSpan> renameSpans);
            var tags = await TestServices.Editor.GetRenameTagsAsync(HangMitigatingCancellationToken);
            var tagSpans = tags.SelectAsArray(tag => new TextSpan(tag.Span.Start, tag.Span.Length));
            AssertEx.SetEqual(renameSpans, tagSpans);
 
            await TestServices.Input.SendWithoutActivateAsync(new InputKey[] { VirtualKeyCode.VK_Y, VirtualKeyCode.RETURN }, HangMitigatingCancellationToken);
            await TestServices.Workspace.WaitForRenameAsync(HangMitigatingCancellationToken);
            await TestServices.EditorVerifier.TextEqualsAsync(@"
Interface I
    Sub y$$(y As Integer)
    Sub y(y As String)
End Interface
 
Public MustInherit Class A
    Implements I
    Public MustOverride Sub y(y As Integer) Implements I.y
    Public MustOverride Sub y(y As String) Implements I.y
End Class", HangMitigatingCancellationToken);
        }
 
        [IdeFact, WorkItem("https://github.com/dotnet/roslyn/issues/21657")]
        public async Task VerifyAttributeRename()
        {
            var markup = @"
Imports System
 
Public Class [|$$ustom|]Attribute 
        Inherits Attribute
End Class";
            await SetUpEditorAsync(markup, HangMitigatingCancellationToken);
            await TestServices.InlineRename.InvokeAsync(HangMitigatingCancellationToken);
 
            MarkupTestFile.GetSpans(markup, out var _, out ImmutableArray<TextSpan> renameSpans);
            var tags = await TestServices.Editor.GetRenameTagsAsync(HangMitigatingCancellationToken);
            var tagSpans = tags.SelectAsArray(tag => new TextSpan(tag.Span.Start, tag.Span.Length));
            AssertEx.SetEqual(renameSpans, tagSpans);
 
            await TestServices.Input.SendWithoutActivateAsync(new InputKey[] { "Custom", VirtualKeyCode.RETURN }, HangMitigatingCancellationToken);
            await TestServices.Workspace.WaitForRenameAsync(HangMitigatingCancellationToken);
            await TestServices.EditorVerifier.TextEqualsAsync(@"
Imports System
 
Public Class Custom$$Attribute
    Inherits Attribute
End Class", HangMitigatingCancellationToken);
        }
 
        [IdeFact, WorkItem("https://github.com/dotnet/roslyn/issues/21657")]
        public async Task VerifyAttributeRenameWhileRenameClasss()
        {
            var markup = @"
Imports System
 
Public Class [|$$ustom|]Attribute 
        Inherits Attribute
End Class";
 
            await SetUpEditorAsync(markup, HangMitigatingCancellationToken);
            await TestServices.InlineRename.InvokeAsync(HangMitigatingCancellationToken);
 
            MarkupTestFile.GetSpans(markup, out var _, out ImmutableArray<TextSpan> renameSpans);
            var tags = await TestServices.Editor.GetRenameTagsAsync(HangMitigatingCancellationToken);
            var tagSpans = tags.SelectAsArray(tag => new TextSpan(tag.Span.Start, tag.Span.Length));
            AssertEx.SetEqual(renameSpans, tagSpans);
 
            await TestServices.Input.SendWithoutActivateAsync("Custom", HangMitigatingCancellationToken);
            await TestServices.Workspace.WaitForRenameAsync(HangMitigatingCancellationToken);
            await TestServices.EditorVerifier.TextEqualsAsync(@"
Imports System
 
Public Class Custom$$Attribute 
        Inherits Attribute
End Class", HangMitigatingCancellationToken);
        }
 
        [IdeFact, WorkItem("https://github.com/dotnet/roslyn/issues/21657")]
        public async Task VerifyAttributeRenameWhileRenameAttribute()
        {
            var markup = @"
Imports System
 
<[|$$ustom|]>
Class Bar
End Class
 
Public Class [|ustom|]Attribute 
        Inherits Attribute
End Class";
            await SetUpEditorAsync(markup, HangMitigatingCancellationToken);
            await TestServices.InlineRename.InvokeAsync(HangMitigatingCancellationToken);
 
            MarkupTestFile.GetSpans(markup, out _, out ImmutableArray<TextSpan> renameSpans);
            var tags = await TestServices.Editor.GetRenameTagsAsync(HangMitigatingCancellationToken);
            var tagSpans = tags.SelectAsArray(tag => new TextSpan(tag.Span.Start, tag.Span.Length));
            AssertEx.SetEqual(renameSpans, tagSpans);
 
            await TestServices.Input.SendWithoutActivateAsync("Custom", HangMitigatingCancellationToken);
            await TestServices.Workspace.WaitForRenameAsync(HangMitigatingCancellationToken);
            await TestServices.EditorVerifier.TextEqualsAsync(@"
Imports System
 
<Custom$$>
Class Bar
End Class
 
Public Class CustomAttribute 
        Inherits Attribute
End Class", HangMitigatingCancellationToken);
        }
 
        [IdeFact, WorkItem("https://github.com/dotnet/roslyn/issues/21657")]
        public async Task VerifyAttributeRenameWhileRenameAttributeClass()
        {
            var markup = @"
Imports System
 
<[|ustom|]>
Class Bar
End Class
 
Public Class [|$$ustom|]Attribute 
        Inherits Attribute
End Class";
            await SetUpEditorAsync(markup, HangMitigatingCancellationToken);
            await TestServices.InlineRename.InvokeAsync(HangMitigatingCancellationToken);
 
            MarkupTestFile.GetSpans(markup, out _, out ImmutableArray<TextSpan> renameSpans);
            var tags = await TestServices.Editor.GetRenameTagsAsync(HangMitigatingCancellationToken);
            var tagSpans = tags.SelectAsArray(tag => new TextSpan(tag.Span.Start, tag.Span.Length));
            AssertEx.SetEqual(renameSpans, tagSpans);
 
            await TestServices.Input.SendWithoutActivateAsync("Custom", HangMitigatingCancellationToken);
            await TestServices.Workspace.WaitForRenameAsync(HangMitigatingCancellationToken);
            await TestServices.EditorVerifier.TextEqualsAsync(@"
Imports System
 
<Custom>
Class Bar
End Class
 
Public Class Custom$$Attribute 
        Inherits Attribute
End Class", HangMitigatingCancellationToken);
        }
 
        [IdeFact, WorkItem("https://github.com/dotnet/roslyn/issues/21657")]
        public async Task VerifyAttributeCapitalizedRename()
        {
            var markup = @"
Imports System
 
Public Class [|$$ustom|]ATTRIBUTE
        Inherits Attribute
End Class";
            await SetUpEditorAsync(markup, HangMitigatingCancellationToken);
            await TestServices.InlineRename.InvokeAsync(HangMitigatingCancellationToken);
 
            MarkupTestFile.GetSpans(markup, out var _, out ImmutableArray<TextSpan> renameSpans);
            var tags = await TestServices.Editor.GetRenameTagsAsync(HangMitigatingCancellationToken);
            var tagSpans = tags.SelectAsArray(tag => new TextSpan(tag.Span.Start, tag.Span.Length));
            AssertEx.SetEqual(renameSpans, tagSpans);
 
            await TestServices.Input.SendWithoutActivateAsync(new InputKey[] { "Custom", VirtualKeyCode.RETURN }, HangMitigatingCancellationToken);
            await TestServices.Workspace.WaitForRenameAsync(HangMitigatingCancellationToken);
            await TestServices.EditorVerifier.TextEqualsAsync(@"
Imports System
 
Public Class CustomAttribute$$
    Inherits Attribute
End Class", HangMitigatingCancellationToken);
        }
 
        [IdeFact, WorkItem("https://github.com/dotnet/roslyn/issues/21657")]
        public async Task VerifyAttributeNotCapitalizedRename()
        {
            var markup = @"
Imports System
 
Public Class [|$$ustom|]attribute
        Inherits Attribute
End Class";
            await SetUpEditorAsync(markup, HangMitigatingCancellationToken);
            await TestServices.InlineRename.InvokeAsync(HangMitigatingCancellationToken);
 
            MarkupTestFile.GetSpans(markup, out var _, out ImmutableArray<TextSpan> renameSpans);
            var tags = await TestServices.Editor.GetRenameTagsAsync(HangMitigatingCancellationToken);
            var tagSpans = tags.SelectAsArray(tag => new TextSpan(tag.Span.Start, tag.Span.Length));
            AssertEx.SetEqual(renameSpans, tagSpans);
 
            await TestServices.Input.SendWithoutActivateAsync(new InputKey[] { "Custom", VirtualKeyCode.RETURN }, HangMitigatingCancellationToken);
            await TestServices.Workspace.WaitForRenameAsync(HangMitigatingCancellationToken);
            try
            {
                // This is the expected behavior
                await TestServices.EditorVerifier.TextEqualsAsync(@"
Imports System
 
Public Class CustomAttribute$$
    Inherits Attribute
End Class", HangMitigatingCancellationToken);
            }
            catch (XunitException)
            {
                // But sometimes we get this instead
                await TestServices.EditorVerifier.TextEqualsAsync(@"
Imports System
 
Public Class CustomA$$ttribute
    Inherits Attribute
End Class", HangMitigatingCancellationToken);
            }
        }
    }
}