|
// 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.
#nullable disable
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Shared.TestHooks;
using Microsoft.CodeAnalysis.Test.Utilities;
using Microsoft.VisualStudio.IntegrationTest.Utilities;
using Microsoft.VisualStudio.IntegrationTest.Utilities.Input;
using Roslyn.Test.Utilities;
using Xunit;
using Xunit.Abstractions;
using ProjectUtils = Microsoft.VisualStudio.IntegrationTest.Utilities.Common.ProjectUtils;
namespace Roslyn.VisualStudio.IntegrationTests.VisualBasic
{
[Collection(nameof(SharedIntegrationHostFixture))]
[Trait(Traits.Feature, Traits.Features.DebuggingEditAndContinue)]
public class BasicEditAndContinue : AbstractEditorTest
{
private const string module1FileName = "Module1.vb";
public BasicEditAndContinue(VisualStudioInstanceFactory instanceFactory)
: base(instanceFactory)
{
}
protected override string LanguageName => LanguageNames.VisualBasic;
public override async Task InitializeAsync()
{
await base.InitializeAsync();
VisualStudio.SolutionExplorer.CreateSolution(nameof(BasicEditAndContinue));
var testProj = new ProjectUtils.Project("TestProj");
VisualStudio.SolutionExplorer.AddProject(testProj, WellKnownProjectTemplates.ConsoleApplication, LanguageNames.VisualBasic);
}
// Also "https://github.com/dotnet/roslyn/issues/37689")]
[WpfFact(Skip = "https://github.com/dotnet/roslyn/issues/35965")]
public void UpdateActiveStatementLeafNode()
{
VisualStudio.Editor.SetText(@"
Imports System
Imports System.Collections.Generic
Imports System.Linq
Module Module1
Sub Main()
Dim names(2) As String
names(0) = ""goo""
names(1) = ""bar""
For index = 0 To names.GetUpperBound(0)
Console.WriteLine(names(index))
Next
End Sub
End Module
");
VisualStudio.Workspace.WaitForAsyncOperations(Helper.HangMitigatingTimeout, FeatureAttribute.Workspace);
VisualStudio.Debugger.SetBreakPoint(module1FileName, "names(0)");
VisualStudio.Debugger.Go(waitForBreakMode: true);
VisualStudio.Editor.Activate();
VisualStudio.Editor.ReplaceText("names(0)", "names(1)");
VisualStudio.Debugger.StepOver(waitForBreakOrEnd: true);
VisualStudio.Debugger.CheckExpression("names(1)", "String", "\"goo\"");
VisualStudio.Debugger.StepOver(waitForBreakOrEnd: true);
VisualStudio.Debugger.CheckExpression("names(1)", "String", "\"bar\"");
}
// Also "https://github.com/dotnet/roslyn/issues/37689")]
[WpfFact(Skip = "https://github.com/dotnet/roslyn/issues/35965")]
public void AddTryCatchAroundActiveStatement()
{
VisualStudio.Editor.SetText(@"
Imports System
Module Module1
Sub Main()
Goo()
End Sub
Private Sub Goo()
Console.WriteLine(1)
End Sub
End Module");
VisualStudio.Workspace.WaitForAsyncOperations(Helper.HangMitigatingTimeout, FeatureAttribute.Workspace);
VisualStudio.Debugger.SetBreakPoint(module1FileName, "Console.WriteLine(1)");
VisualStudio.Debugger.Go(waitForBreakMode: true);
VisualStudio.Editor.Activate();
VisualStudio.Editor.ReplaceText("Console.WriteLine(1)",
@"Try
Console.WriteLine(1)
Catch ex As Exception
End Try");
VisualStudio.Workspace.WaitForAsyncOperations(Helper.HangMitigatingTimeout, FeatureAttribute.Workspace);
VisualStudio.Debugger.StepOver(waitForBreakOrEnd: true);
VisualStudio.Editor.Verify.CurrentLineText("End Try");
}
// Also "https://github.com/dotnet/roslyn/issues/37689")]
[WpfFact(Skip = "https://github.com/dotnet/roslyn/issues/35965")]
public void EditLambdaExpression()
{
VisualStudio.Editor.SetText(@"
Imports System
Module Module1
Private Delegate Function del(i As Integer) As Integer
Sub Main()
Dim myDel As del = Function(x) x * x
Dim j As Integer = myDel(5)
End Sub
End Module");
VisualStudio.Workspace.WaitForAsyncOperations(Helper.HangMitigatingTimeout, FeatureAttribute.Workspace);
VisualStudio.Debugger.SetBreakPoint(module1FileName, "x * x", charsOffset: -1);
VisualStudio.Debugger.Go(waitForBreakMode: true);
VisualStudio.Editor.Activate();
VisualStudio.Editor.ReplaceText("x * x", "x * 2");
VisualStudio.Debugger.StepOver(waitForBreakOrEnd: false);
VisualStudio.Debugger.Stop(waitForDesignMode: true);
VisualStudio.ErrorList.Verify.NoBuildErrors();
VisualStudio.Debugger.Go(waitForBreakMode: true);
VisualStudio.Editor.Activate();
VisualStudio.Editor.ReplaceText("x * 2", "x * x");
VisualStudio.Debugger.StepOver(waitForBreakOrEnd: true);
VisualStudio.Debugger.Stop(waitForDesignMode: true);
VisualStudio.ErrorList.Verify.NoBuildErrors();
}
// Also "https://github.com/dotnet/roslyn/issues/37689")]
[WpfFact(Skip = "https://github.com/dotnet/roslyn/issues/35965")]
public void EnCWhileDebuggingFromImmediateWindow()
{
VisualStudio.Editor.SetText(@"
Imports System
Module Module1
Sub Main()
Dim x = 4
Console.WriteLine(x)
End Sub
End Module");
VisualStudio.Workspace.WaitForAsyncOperations(Helper.HangMitigatingTimeout, FeatureAttribute.Workspace);
VisualStudio.Debugger.Go(waitForBreakMode: true);
VisualStudio.Debugger.SetBreakPoint(module1FileName, "Dim x", charsOffset: 1);
VisualStudio.Debugger.ExecuteStatement("Module1.Main()");
VisualStudio.Editor.ReplaceText("x = 4", "x = 42");
VisualStudio.Debugger.StepOver(waitForBreakOrEnd: true);
VisualStudio.Debugger.CheckExpression("x", "Integer", "42");
VisualStudio.Debugger.ExecuteStatement("Module1.Main()");
}
private void SetupMultiProjectSolution()
{
var basicLibrary = new ProjectUtils.Project("BasicLibrary1");
VisualStudio.SolutionExplorer.AddProject(basicLibrary, WellKnownProjectTemplates.ClassLibrary, LanguageNames.VisualBasic);
var cSharpLibrary = new ProjectUtils.Project("CSharpLibrary1");
VisualStudio.SolutionExplorer.AddProject(cSharpLibrary, WellKnownProjectTemplates.ClassLibrary, LanguageNames.CSharp);
VisualStudio.SolutionExplorer.AddFile(cSharpLibrary, "File1.cs");
VisualStudio.SolutionExplorer.OpenFile(basicLibrary, "Class1.vb");
VisualStudio.Editor.SetText(@"
Imports System
Public Class Class1
Public Sub New()
End Sub
Public Sub PrintX(x As Integer)
Console.WriteLine(x)
End Sub
End Class
");
var project = new ProjectUtils.Project(ProjectName);
VisualStudio.SolutionExplorer.AddProjectReference(project, new ProjectUtils.ProjectReference("BasicLibrary1"));
VisualStudio.SolutionExplorer.OpenFile(project, module1FileName);
VisualStudio.Editor.SetText(@"
Imports System
Imports BasicLibrary1
Module Module1
Sub Main()
Dim c As New Class1()
c.PrintX(5)
End Sub
End Module
");
VisualStudio.Workspace.WaitForAsyncOperations(Helper.HangMitigatingTimeout, FeatureAttribute.Workspace);
}
// Also https://github.com/dotnet/roslyn/issues/36763
[WpfFact(Skip = "https://github.com/dotnet/roslyn/issues/35965")]
public void MultiProjectDebuggingWhereNotAllModulesAreLoaded()
{
SetupMultiProjectSolution();
VisualStudio.Debugger.SetBreakPoint(module1FileName, "PrintX", charsOffset: 1);
VisualStudio.Debugger.Go(waitForBreakMode: true);
VisualStudio.Editor.Activate();
VisualStudio.Editor.ReplaceText("5", "42");
VisualStudio.Debugger.StepOver(waitForBreakOrEnd: false);
VisualStudio.ErrorList.Verify.NoErrors();
}
// Also "https://github.com/dotnet/roslyn/issues/37689")]
[WpfFact(Skip = "https://github.com/dotnet/roslyn/issues/35965")]
public void LocalsWindowUpdatesAfterLocalGetsItsTypeUpdatedDuringEnC()
{
VisualStudio.Editor.SetText(@"
Imports System
Module Module1
Sub Main()
Dim goo As String = ""abc""
Console.WriteLine(goo)
End Sub
End Module
");
VisualStudio.Workspace.WaitForAsyncOperations(Helper.HangMitigatingTimeout, FeatureAttribute.Workspace);
VisualStudio.Debugger.SetBreakPoint(module1FileName, "End Sub");
VisualStudio.Debugger.Go(waitForBreakMode: true);
VisualStudio.Editor.Activate();
VisualStudio.Editor.ReplaceText("Dim goo As String = \"abc\"", "Dim goo As Single = 10");
VisualStudio.Editor.SelectTextInCurrentDocument("Sub Main()");
VisualStudio.Debugger.SetNextStatement();
VisualStudio.Debugger.Go(waitForBreakMode: true);
VisualStudio.LocalsWindow.Verify.CheckEntry("goo", "Single", "10");
}
// Also "https://github.com/dotnet/roslyn/issues/37689")]
[WpfFact(Skip = "https://github.com/dotnet/roslyn/issues/35965")]
public void LocalsWindowUpdatesCorrectlyDuringEnC()
{
VisualStudio.Editor.SetText(@"
Imports System
Module Module1
Sub Main()
bar(5)
End Sub
Function bar(ByVal moo As Long) As Decimal
Dim iInt As Integer = 0
Dim lLng As Long = 5
iInt += 30
Return 4
End Function
End Module
");
VisualStudio.Workspace.WaitForAsyncOperations(Helper.HangMitigatingTimeout, FeatureAttribute.Workspace);
VisualStudio.Debugger.SetBreakPoint(module1FileName, "Function bar(ByVal moo As Long) As Decimal");
VisualStudio.Debugger.Go(waitForBreakMode: true);
VisualStudio.Editor.Activate();
VisualStudio.Editor.ReplaceText("Dim lLng As Long = 5", "Dim lLng As Long = 444");
VisualStudio.Debugger.SetBreakPoint(module1FileName, "Return 4");
VisualStudio.Debugger.Go(waitForBreakMode: true);
VisualStudio.LocalsWindow.Verify.CheckEntry("bar", "Decimal", "0");
VisualStudio.LocalsWindow.Verify.CheckEntry("moo", "Long", "5");
VisualStudio.LocalsWindow.Verify.CheckEntry("iInt", "Integer", "30");
VisualStudio.LocalsWindow.Verify.CheckEntry("lLng", "Long", "444");
}
// Also "https://github.com/dotnet/roslyn/issues/37689")]
[WpfFact(Skip = "https://github.com/dotnet/roslyn/issues/35965")]
public void WatchWindowUpdatesCorrectlyDuringEnC()
{
VisualStudio.Editor.SetText(@"
Imports System
Module Module1
Sub Main()
Dim iInt As Integer = 0
System.Diagnostics.Debugger.Break()
End Sub
End Module
");
VisualStudio.Workspace.WaitForAsyncOperations(Helper.HangMitigatingTimeout, FeatureAttribute.Workspace);
VisualStudio.Debugger.Go(waitForBreakMode: true);
VisualStudio.Editor.Activate();
VisualStudio.Debugger.CheckExpression("iInt", "Integer", "0");
VisualStudio.Editor.ReplaceText("System.Diagnostics.Debugger.Break()", @"iInt = 5
System.Diagnostics.Debugger.Break()");
VisualStudio.Editor.SelectTextInCurrentDocument("iInt = 5");
VisualStudio.Debugger.SetNextStatement();
VisualStudio.Debugger.Go(waitForBreakMode: true);
VisualStudio.Debugger.CheckExpression("iInt", "Integer", "5");
}
}
}
|