diff --git a/OmniSharp.sln b/OmniSharp.sln index 33543c91f9..78f5999858 100644 --- a/OmniSharp.sln +++ b/OmniSharp.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.27004.2005 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30804.86 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{2C348365-A9D8-459E-9276-56FC46AAEE31}" EndProject @@ -67,9 +67,13 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OmniSharp.Stdio.Driver", "s EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OmniSharp.Script.Tests", "tests\OmniSharp.Script.Tests\OmniSharp.Script.Tests.csproj", "{9E4BA68C-7F4B-429A-A0C7-8CE7D41D610F}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OmniSharp.Shared", "src\OmniSharp.Shared\OmniSharp.Shared.csproj", "{9571E3FE-E742-44AC-9E1F-64156815B8E1}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OmniSharp.Shared", "src\OmniSharp.Shared\OmniSharp.Shared.csproj", "{9571E3FE-E742-44AC-9E1F-64156815B8E1}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OmniSharp.Lsp.Tests", "tests\OmniSharp.Lsp.Tests\OmniSharp.Lsp.Tests.csproj", "{D67AA10B-8DB6-408D-A4C5-0B1DDCF5B3CC}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OmniSharp.Lsp.Tests", "tests\OmniSharp.Lsp.Tests\OmniSharp.Lsp.Tests.csproj", "{D67AA10B-8DB6-408D-A4C5-0B1DDCF5B3CC}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OmniSharp.Roslyn.VisualBasic.Tests", "tests\OmniSharp.Roslyn.VisualBasic.Tests\OmniSharp.Roslyn.VisualBasic.Tests.csproj", "{F9CDDDB1-3CDF-49AA-9896-BD8516E57D80}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OmniSharp.Roslyn.VisualBasic", "src\OmniSharp.Roslyn.VisualBasic\OmniSharp.Roslyn.VisualBasic.csproj", "{CE85B0B0-87D4-4391-A552-4F8DF6C2C40D}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -369,6 +373,30 @@ Global {D67AA10B-8DB6-408D-A4C5-0B1DDCF5B3CC}.Release|x64.Build.0 = Release|Any CPU {D67AA10B-8DB6-408D-A4C5-0B1DDCF5B3CC}.Release|x86.ActiveCfg = Release|Any CPU {D67AA10B-8DB6-408D-A4C5-0B1DDCF5B3CC}.Release|x86.Build.0 = Release|Any CPU + {F9CDDDB1-3CDF-49AA-9896-BD8516E57D80}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F9CDDDB1-3CDF-49AA-9896-BD8516E57D80}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F9CDDDB1-3CDF-49AA-9896-BD8516E57D80}.Debug|x64.ActiveCfg = Debug|Any CPU + {F9CDDDB1-3CDF-49AA-9896-BD8516E57D80}.Debug|x64.Build.0 = Debug|Any CPU + {F9CDDDB1-3CDF-49AA-9896-BD8516E57D80}.Debug|x86.ActiveCfg = Debug|Any CPU + {F9CDDDB1-3CDF-49AA-9896-BD8516E57D80}.Debug|x86.Build.0 = Debug|Any CPU + {F9CDDDB1-3CDF-49AA-9896-BD8516E57D80}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F9CDDDB1-3CDF-49AA-9896-BD8516E57D80}.Release|Any CPU.Build.0 = Release|Any CPU + {F9CDDDB1-3CDF-49AA-9896-BD8516E57D80}.Release|x64.ActiveCfg = Release|Any CPU + {F9CDDDB1-3CDF-49AA-9896-BD8516E57D80}.Release|x64.Build.0 = Release|Any CPU + {F9CDDDB1-3CDF-49AA-9896-BD8516E57D80}.Release|x86.ActiveCfg = Release|Any CPU + {F9CDDDB1-3CDF-49AA-9896-BD8516E57D80}.Release|x86.Build.0 = Release|Any CPU + {CE85B0B0-87D4-4391-A552-4F8DF6C2C40D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CE85B0B0-87D4-4391-A552-4F8DF6C2C40D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CE85B0B0-87D4-4391-A552-4F8DF6C2C40D}.Debug|x64.ActiveCfg = Debug|Any CPU + {CE85B0B0-87D4-4391-A552-4F8DF6C2C40D}.Debug|x64.Build.0 = Debug|Any CPU + {CE85B0B0-87D4-4391-A552-4F8DF6C2C40D}.Debug|x86.ActiveCfg = Debug|Any CPU + {CE85B0B0-87D4-4391-A552-4F8DF6C2C40D}.Debug|x86.Build.0 = Debug|Any CPU + {CE85B0B0-87D4-4391-A552-4F8DF6C2C40D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CE85B0B0-87D4-4391-A552-4F8DF6C2C40D}.Release|Any CPU.Build.0 = Release|Any CPU + {CE85B0B0-87D4-4391-A552-4F8DF6C2C40D}.Release|x64.ActiveCfg = Release|Any CPU + {CE85B0B0-87D4-4391-A552-4F8DF6C2C40D}.Release|x64.Build.0 = Release|Any CPU + {CE85B0B0-87D4-4391-A552-4F8DF6C2C40D}.Release|x86.ActiveCfg = Release|Any CPU + {CE85B0B0-87D4-4391-A552-4F8DF6C2C40D}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -398,6 +426,8 @@ Global {9E4BA68C-7F4B-429A-A0C7-8CE7D41D610F} = {35E025BF-BBB2-4FAC-9F4B-37CBA083EE47} {9571E3FE-E742-44AC-9E1F-64156815B8E1} = {2C348365-A9D8-459E-9276-56FC46AAEE31} {D67AA10B-8DB6-408D-A4C5-0B1DDCF5B3CC} = {35E025BF-BBB2-4FAC-9F4B-37CBA083EE47} + {F9CDDDB1-3CDF-49AA-9896-BD8516E57D80} = {35E025BF-BBB2-4FAC-9F4B-37CBA083EE47} + {CE85B0B0-87D4-4391-A552-4F8DF6C2C40D} = {2C348365-A9D8-459E-9276-56FC46AAEE31} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {4DD725CE-B49A-4151-8B77-BB33FE88E46E} diff --git a/build/Packages.props b/build/Packages.props index 0ded80066c..df65878bd0 100644 --- a/build/Packages.props +++ b/build/Packages.props @@ -32,6 +32,10 @@ + + + + diff --git a/src/OmniSharp.Abstractions/AssemblyInfo.cs b/src/OmniSharp.Abstractions/AssemblyInfo.cs index 8536ac7d76..2a7d21928f 100644 --- a/src/OmniSharp.Abstractions/AssemblyInfo.cs +++ b/src/OmniSharp.Abstractions/AssemblyInfo.cs @@ -5,6 +5,7 @@ [assembly: InternalsVisibleTo("OmniSharp.MSBuild")] [assembly: InternalsVisibleTo("OmniSharp.Roslyn")] [assembly: InternalsVisibleTo("OmniSharp.Roslyn.CSharp")] +[assembly: InternalsVisibleTo("OmniSharp.Roslyn.VisualBasic")] [assembly: InternalsVisibleTo("OmniSharp.DotNetTest.Tests")] [assembly: InternalsVisibleTo("OmniSharp.Tests")] [assembly: InternalsVisibleTo("OmniSharp.LanguageServerProtocol")] diff --git a/src/OmniSharp.Host/AssemblyInfo.cs b/src/OmniSharp.Host/AssemblyInfo.cs index 28fc7fdf1a..72f4c41469 100644 --- a/src/OmniSharp.Host/AssemblyInfo.cs +++ b/src/OmniSharp.Host/AssemblyInfo.cs @@ -3,5 +3,6 @@ [assembly: InternalsVisibleTo("OmniSharp.Http.Tests")] [assembly: InternalsVisibleTo("OmniSharp.MSBuild.Tests")] [assembly: InternalsVisibleTo("OmniSharp.Roslyn.CSharp.Tests")] +[assembly: InternalsVisibleTo("OmniSharp.Roslyn.VisualBasic.Tests")] [assembly: InternalsVisibleTo("OmniSharp.Stdio.Tests")] [assembly: InternalsVisibleTo("TestUtility")] diff --git a/src/OmniSharp.Http/OmniSharp.Http.csproj b/src/OmniSharp.Http/OmniSharp.Http.csproj index 599b375837..3cbe7aab4c 100644 --- a/src/OmniSharp.Http/OmniSharp.Http.csproj +++ b/src/OmniSharp.Http/OmniSharp.Http.csproj @@ -11,6 +11,7 @@ + diff --git a/src/OmniSharp.LanguageServerProtocol/OmniSharp.LanguageServerProtocol.csproj b/src/OmniSharp.LanguageServerProtocol/OmniSharp.LanguageServerProtocol.csproj index db500319f9..577b6e61b2 100644 --- a/src/OmniSharp.LanguageServerProtocol/OmniSharp.LanguageServerProtocol.csproj +++ b/src/OmniSharp.LanguageServerProtocol/OmniSharp.LanguageServerProtocol.csproj @@ -16,6 +16,7 @@ + diff --git a/src/OmniSharp.MSBuild/OmniSharp.MSBuild.csproj b/src/OmniSharp.MSBuild/OmniSharp.MSBuild.csproj index 5fc93944f6..7d159dd23f 100644 --- a/src/OmniSharp.MSBuild/OmniSharp.MSBuild.csproj +++ b/src/OmniSharp.MSBuild/OmniSharp.MSBuild.csproj @@ -10,6 +10,7 @@ + diff --git a/src/OmniSharp.Roslyn.VisualBasic/OmniSharp.Roslyn.VisualBasic.csproj b/src/OmniSharp.Roslyn.VisualBasic/OmniSharp.Roslyn.VisualBasic.csproj new file mode 100644 index 0000000000..5af770145c --- /dev/null +++ b/src/OmniSharp.Roslyn.VisualBasic/OmniSharp.Roslyn.VisualBasic.csproj @@ -0,0 +1,24 @@ + + + + net472;netcoreapp2.1;netstandard2.0 + AnyCPU + true + true + + + + + + + + + + + + + + + + + diff --git a/src/OmniSharp.Roslyn.VisualBasic/Services/Structure/BlockStructureService.cs b/src/OmniSharp.Roslyn.VisualBasic/Services/Structure/BlockStructureService.cs new file mode 100644 index 0000000000..d5e5f31c6c --- /dev/null +++ b/src/OmniSharp.Roslyn.VisualBasic/Services/Structure/BlockStructureService.cs @@ -0,0 +1,95 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Composition; +using System.Reflection; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Text; +using OmniSharp.Extensions; +using OmniSharp.Mef; +using OmniSharp.Models.V2; +using OmniSharp.Services; +using OmniSharp.Utilities; + +namespace OmniSharp.Roslyn.VisualBasic.Services.Structure +{ + [OmniSharpHandler(OmniSharpEndpoints.V2.BlockStructure, LanguageNames.VisualBasic)] + public class BlockStructureService : IRequestHandler + { + private const string PreprocessorRegion = nameof(PreprocessorRegion); + + private readonly IAssemblyLoader _loader; + private readonly Lazy _featureAssembly; + private readonly Lazy _blockStructureService; + private readonly Lazy _blockStructure; + private readonly Lazy _blockSpan; + private readonly Lazy _getBlockStructure; + private readonly MethodInfo _getSpans; + private readonly MethodInfo _getIsCollpasible; + private readonly MethodInfo _getTextSpan; + private readonly MethodInfo _getType; + private readonly OmniSharpWorkspace _workspace; + + [ImportingConstructor] + public BlockStructureService(IAssemblyLoader loader, OmniSharpWorkspace workspace) + { + _workspace = workspace; + _loader = loader; + _featureAssembly = _loader.LazyLoad(Configuration.RoslynFeatures); + + _blockStructureService = _featureAssembly.LazyGetType("Microsoft.CodeAnalysis.Structure.BlockStructureService"); + _blockStructure = _featureAssembly.LazyGetType("Microsoft.CodeAnalysis.Structure.BlockStructure"); + _blockSpan = _featureAssembly.LazyGetType("Microsoft.CodeAnalysis.Structure.BlockSpan"); + + _getBlockStructure = _blockStructureService.LazyGetMethod("GetBlockStructure"); + _getSpans = _blockStructure.Value.GetProperty("Spans").GetMethod; + _getIsCollpasible = _blockSpan.Value.GetProperty("IsCollapsible").GetMethod; + _getTextSpan = _blockSpan.Value.GetProperty("TextSpan").GetMethod; + _getType = _blockSpan.Value.GetProperty("Type").GetMethod; + } + + public async Task Handle(BlockStructureRequest request) + { + // To provide complete code structure for the document wait until all projects are loaded. + var document = await _workspace.GetDocumentFromFullProjectModelAsync(request.FileName); + if (document == null) + { + return null; + } + + var text = await document.GetTextAsync(); + + var service = _blockStructureService.LazyGetMethod("GetService").InvokeStatic(new[] { document }); + + var structure = _getBlockStructure.Invoke(service, new object[] { document, CancellationToken.None }); + var spans = _getSpans.Invoke(structure, Array.Empty()); + + + var outliningSpans = new List(); + foreach (var span in spans) + { + if (_getIsCollpasible.Invoke(span, Array.Empty())) + { + var textSpan = _getTextSpan.Invoke(span, Array.Empty()); + + outliningSpans.Add(new CodeFoldingBlock( + text.GetRangeFromSpan(textSpan), + type: ConvertToWellKnownBlockType(_getType.Invoke(span, Array.Empty())))); + } + } + + return new BlockStructureResponse() { Spans = outliningSpans }; + } + + private string ConvertToWellKnownBlockType(string kind) + { + return kind == CodeFoldingBlockKinds.Comment || kind == CodeFoldingBlockKinds.Imports + ? kind + : kind == PreprocessorRegion + ? CodeFoldingBlockKinds.Region + : null; + } + } +} diff --git a/src/OmniSharp.Roslyn/AssemblyInfo.cs b/src/OmniSharp.Roslyn/AssemblyInfo.cs index 03cf2732b9..f3aecfad13 100644 --- a/src/OmniSharp.Roslyn/AssemblyInfo.cs +++ b/src/OmniSharp.Roslyn/AssemblyInfo.cs @@ -1,4 +1,5 @@ using System.Runtime.CompilerServices; [assembly: InternalsVisibleTo("OmniSharp.Tests")] -[assembly: InternalsVisibleTo("OmniSharp.Roslyn.CSharp")] \ No newline at end of file +[assembly: InternalsVisibleTo("OmniSharp.Roslyn.CSharp")] +[assembly: InternalsVisibleTo("OmniSharp.Roslyn.VisualBasic")] \ No newline at end of file diff --git a/src/OmniSharp.Roslyn/Properties/AssemblyInfo.cs b/src/OmniSharp.Roslyn/Properties/AssemblyInfo.cs index 869c539915..3b42362417 100644 --- a/src/OmniSharp.Roslyn/Properties/AssemblyInfo.cs +++ b/src/OmniSharp.Roslyn/Properties/AssemblyInfo.cs @@ -1,4 +1,4 @@ using System.Runtime.CompilerServices; [assembly: InternalsVisibleTo("OmniSharp.Roslyn.CSharp.Tests")] - +[assembly: InternalsVisibleTo("OmniSharp.Roslyn.VisualBasic.Tests")] diff --git a/src/OmniSharp.Shared/AssemblyInfo.cs b/src/OmniSharp.Shared/AssemblyInfo.cs index 6abd59bc91..0fe8f4401c 100644 --- a/src/OmniSharp.Shared/AssemblyInfo.cs +++ b/src/OmniSharp.Shared/AssemblyInfo.cs @@ -5,5 +5,6 @@ [assembly: InternalsVisibleTo("OmniSharp.MSBuild")] [assembly: InternalsVisibleTo("OmniSharp.Roslyn")] [assembly: InternalsVisibleTo("OmniSharp.Roslyn.CSharp")] +[assembly: InternalsVisibleTo("OmniSharp.Roslyn.VisualBasic")] [assembly: InternalsVisibleTo("OmniSharp.DotNetTest.Tests")] [assembly: InternalsVisibleTo("OmniSharp.Tests")] diff --git a/src/OmniSharp.Stdio/OmniSharp.Stdio.csproj b/src/OmniSharp.Stdio/OmniSharp.Stdio.csproj index ae3f0d04df..552068b8f7 100644 --- a/src/OmniSharp.Stdio/OmniSharp.Stdio.csproj +++ b/src/OmniSharp.Stdio/OmniSharp.Stdio.csproj @@ -9,6 +9,7 @@ + diff --git a/tests/OmniSharp.Roslyn.VisualBasic.Tests/AssemblyInfo.cs b/tests/OmniSharp.Roslyn.VisualBasic.Tests/AssemblyInfo.cs new file mode 100644 index 0000000000..3969a68e84 --- /dev/null +++ b/tests/OmniSharp.Roslyn.VisualBasic.Tests/AssemblyInfo.cs @@ -0,0 +1 @@ +[assembly: Xunit.CollectionBehavior(DisableTestParallelization = true)] \ No newline at end of file diff --git a/tests/OmniSharp.Roslyn.VisualBasic.Tests/BlockStructureFacts.cs b/tests/OmniSharp.Roslyn.VisualBasic.Tests/BlockStructureFacts.cs new file mode 100644 index 0000000000..0259d67c1f --- /dev/null +++ b/tests/OmniSharp.Roslyn.VisualBasic.Tests/BlockStructureFacts.cs @@ -0,0 +1,90 @@ +using System.Linq; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis; +using OmniSharp.Models.V2; +using OmniSharp.Roslyn.VisualBasic.Services.Structure; +using TestUtility; +using Xunit; +using Xunit.Abstractions; + +namespace OmniSharp.Roslyn.VisualBasic.Tests +{ + public class BlockStructureFacts : AbstractSingleRequestHandlerTestFixture + { + public BlockStructureFacts(ITestOutputHelper output, SharedOmniSharpHostFixture sharedOmniSharpHostFixture) + : base(output, sharedOmniSharpHostFixture) + { + } + + protected override string EndpointName => OmniSharpEndpoints.V2.BlockStructure; + + [Fact] + public async Task UsesRoslynBlockStructureService() + { + var testFile = new TestFile("foo0.vb", @"[|Class Foo + + [|Public Sub M() + [|If True Then + System.Console.WriteLine() + End If|] + End Sub|] +End Class|]"); + var text = testFile.Content.Text; + + var lineSpans = (await GetResponseAsync(testFile)).Spans + .Select(b => b.Range) + .ToArray(); + + var expected = testFile.Content.GetSpans() + .Select(span => testFile.Content.GetRangeFromSpan(span).ToRange()).ToArray(); + + Assert.Equal(expected, lineSpans); + } + + [Fact] + public async Task SupportsRegionBlocks() + { + var testFile = new TestFile("foo.vb", @" +[|#Region ""Code Region Here"" +[|Class Foo + [|Public Sub M() + [|if False Then + End If|] + End Sub|] +End Class|] +#End Region|]"); + + // TODO: Investigate why the Kind is null. + // A starting point for investigation could be 'ConvertToWellKnownBlockType' + //var regionSpan = Assert.Single((await GetResponseAsync(testFile)).Spans, + // span => span.Kind == CodeFoldingBlockKinds.Region); + + //Assert.Equal(1, regionSpan.Range.Start.Line); + //Assert.Equal(0, regionSpan.Range.Start.Column); + //Assert.Equal(11, regionSpan.Range.End.Line); + //Assert.Equal(10, regionSpan.Range.End.Column); + + var lineSpans = (await GetResponseAsync(testFile)).Spans + .Select(b => b.Range) + .OrderBy(b => b.Start.Line) + .ToArray(); + + var expected = testFile.Content.GetSpans() + .Select(span => testFile.Content.GetRangeFromSpan(span).ToRange()).ToArray(); + + Assert.Equal(expected, lineSpans); + } + + private Task GetResponseAsync(TestFile testFile) + { + SharedOmniSharpTestHost.AddFilesToWorkspace(testFile); + var request = new BlockStructureRequest + { + FileName = testFile.FileName, + }; + + var requestHandler = GetRequestHandler(SharedOmniSharpTestHost, LanguageNames.VisualBasic); + return requestHandler.Handle(request); + } + } +} diff --git a/tests/OmniSharp.Roslyn.VisualBasic.Tests/OmniSharp.Roslyn.VisualBasic.Tests.csproj b/tests/OmniSharp.Roslyn.VisualBasic.Tests/OmniSharp.Roslyn.VisualBasic.Tests.csproj new file mode 100644 index 0000000000..796572aa70 --- /dev/null +++ b/tests/OmniSharp.Roslyn.VisualBasic.Tests/OmniSharp.Roslyn.VisualBasic.Tests.csproj @@ -0,0 +1,31 @@ + + + + net472 + AnyCPU + true + CS0618 + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/TestUtility/AbstractSingleRequestHandlerTestFixture.cs b/tests/TestUtility/AbstractSingleRequestHandlerTestFixture.cs index 3e8cc348f1..e7fccf1a27 100644 --- a/tests/TestUtility/AbstractSingleRequestHandlerTestFixture.cs +++ b/tests/TestUtility/AbstractSingleRequestHandlerTestFixture.cs @@ -1,4 +1,5 @@ -using OmniSharp.Mef; +using Microsoft.CodeAnalysis; +using OmniSharp.Mef; using Xunit.Abstractions; namespace TestUtility @@ -18,9 +19,9 @@ protected AbstractSingleRequestHandlerTestFixture(ITestOutputHelper testOutput, protected abstract string EndpointName { get; } - protected TRequestHandler GetRequestHandler(OmniSharpTestHost host) + protected TRequestHandler GetRequestHandler(OmniSharpTestHost host, string languageName = LanguageNames.CSharp) { - return host.GetRequestHandler(EndpointName); + return host.GetRequestHandler(EndpointName, languageName); } } } diff --git a/tests/TestUtility/OmniSharpTestHost.cs b/tests/TestUtility/OmniSharpTestHost.cs index 2a739749e6..6614b80f42 100644 --- a/tests/TestUtility/OmniSharpTestHost.cs +++ b/tests/TestUtility/OmniSharpTestHost.cs @@ -38,6 +38,7 @@ public class OmniSharpTestHost : DisposableObject typeof(ScriptProjectSystem).GetTypeInfo().Assembly, // OmniSharp.Script typeof(OmniSharpWorkspace).GetTypeInfo().Assembly, // OmniSharp.Roslyn typeof(RoslynFeaturesHostServicesProvider).GetTypeInfo().Assembly, // OmniSharp.Roslyn.CSharp + typeof(OmniSharp.Roslyn.VisualBasic.Services.Structure.BlockStructureService).Assembly, // OmniSharp.Roslyn.VisualBasic typeof(CakeProjectSystem).GetTypeInfo().Assembly, // OmniSharp.Cake typeof(LanguageServerHost).Assembly, // OmniSharp.LanguageServerProtocol }); @@ -140,11 +141,27 @@ public IEnumerable AddFilesToWorkspace(params TestFile[] testFiles) public IEnumerable AddFilesToWorkspace(string folderPath, params TestFile[] testFiles) { folderPath = folderPath ?? Directory.GetCurrentDirectory(); + + var csFiles = testFiles.Where(f => f.FileName.EndsWith(".cs", StringComparison.OrdinalIgnoreCase)).ToArray(); + var vbFiles = testFiles.Where(f => f.FileName.EndsWith(".vb", StringComparison.OrdinalIgnoreCase)).ToArray(); + var projects = TestHelpers.AddProjectToWorkspace( - Workspace, - Path.Combine(folderPath, "project.csproj"), - new[] { "net472" }, - testFiles.Where(f => f.FileName.EndsWith(".cs", StringComparison.OrdinalIgnoreCase)).ToArray()); + Workspace, + Path.Combine(folderPath, "project.csproj"), + new[] { "net472" }, + csFiles); + + if (vbFiles.Length > 0) + { + projects = projects.Concat( + TestHelpers.AddProjectToWorkspace( + Workspace, + Path.Combine(folderPath, "project.vbproj"), + new[] { "net472" }, + vbFiles, + languageName: LanguageNames.VisualBasic) + ); + } foreach (var csxFile in testFiles.Where(f => f.FileName.EndsWith(".csx", StringComparison.OrdinalIgnoreCase))) { diff --git a/tests/TestUtility/TestHelpers.cs b/tests/TestUtility/TestHelpers.cs index 93d0f7a2da..328c0e478a 100644 --- a/tests/TestUtility/TestHelpers.cs +++ b/tests/TestUtility/TestHelpers.cs @@ -46,7 +46,7 @@ public static void AddCsxProjectToWorkspace(OmniSharpWorkspace workspace, TestFi workspace.AddDocument(documentInfo); } - public static IEnumerable AddProjectToWorkspace(OmniSharpWorkspace workspace, string filePath, string[] frameworks, TestFile[] testFiles, ImmutableArray analyzerRefs = default) + public static IEnumerable AddProjectToWorkspace(OmniSharpWorkspace workspace, string filePath, string[] frameworks, TestFile[] testFiles, ImmutableArray analyzerRefs = default, string languageName = LanguageNames.CSharp) { var versionStamp = VersionStamp.Create(); var references = GetReferences(); @@ -70,7 +70,7 @@ public static IEnumerable AddProjectToWorkspace(OmniSharpWorkspace wo version: versionStamp, name: "OmniSharp+" + framework, assemblyName: "AssemblyName", - language: LanguageNames.CSharp, + language: languageName, filePath: filePath, metadataReferences: references, analyzerReferences: analyzerRefs)