delete language server (#8241)
This commit is contained in:
Родитель
85e1409e09
Коммит
523bd5154a
30
FSharp.sln
30
FSharp.sln
|
@ -42,10 +42,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Packages", "Packages", "{38
|
|||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.FSharp.Compiler", "src\fsharp\FSharp.Compiler.nuget\Microsoft.FSharp.Compiler.csproj", "{81B9FE26-C976-4FC7-B6CC-C7DB5903CAA7}"
|
||||
EndProject
|
||||
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Compiler.LanguageServer", "src\fsharp\FSharp.Compiler.LanguageServer\FSharp.Compiler.LanguageServer.fsproj", "{99B3F4A5-80B4-41D9-A073-117DB6D7DBBA}"
|
||||
EndProject
|
||||
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Compiler.LanguageServer.UnitTests", "tests\FSharp.Compiler.LanguageServer.UnitTests\FSharp.Compiler.LanguageServer.UnitTests.fsproj", "{C97819B0-B428-4B96-9CD7-497D2D1C738C}"
|
||||
EndProject
|
||||
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.DependencyManager", "src\fsharp\FSharp.DependencyManager\FSharp.DependencyManager.fsproj", "{8B7BF62E-7D8C-4928-BE40-4E392A9EE851}"
|
||||
EndProject
|
||||
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Compiler.Private.Scripting", "src\fsharp\FSharp.Compiler.Private.Scripting\FSharp.Compiler.Private.Scripting.fsproj", "{6771860A-614D-4FDD-A655-4C70EBCC91B0}"
|
||||
|
@ -218,30 +214,6 @@ Global
|
|||
{81B9FE26-C976-4FC7-B6CC-C7DB5903CAA7}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{81B9FE26-C976-4FC7-B6CC-C7DB5903CAA7}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{81B9FE26-C976-4FC7-B6CC-C7DB5903CAA7}.Release|x86.Build.0 = Release|Any CPU
|
||||
{99B3F4A5-80B4-41D9-A073-117DB6D7DBBA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{99B3F4A5-80B4-41D9-A073-117DB6D7DBBA}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{99B3F4A5-80B4-41D9-A073-117DB6D7DBBA}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{99B3F4A5-80B4-41D9-A073-117DB6D7DBBA}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{99B3F4A5-80B4-41D9-A073-117DB6D7DBBA}.Proto|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{99B3F4A5-80B4-41D9-A073-117DB6D7DBBA}.Proto|Any CPU.Build.0 = Debug|Any CPU
|
||||
{99B3F4A5-80B4-41D9-A073-117DB6D7DBBA}.Proto|x86.ActiveCfg = Debug|Any CPU
|
||||
{99B3F4A5-80B4-41D9-A073-117DB6D7DBBA}.Proto|x86.Build.0 = Debug|Any CPU
|
||||
{99B3F4A5-80B4-41D9-A073-117DB6D7DBBA}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{99B3F4A5-80B4-41D9-A073-117DB6D7DBBA}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{99B3F4A5-80B4-41D9-A073-117DB6D7DBBA}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{99B3F4A5-80B4-41D9-A073-117DB6D7DBBA}.Release|x86.Build.0 = Release|Any CPU
|
||||
{C97819B0-B428-4B96-9CD7-497D2D1C738C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C97819B0-B428-4B96-9CD7-497D2D1C738C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C97819B0-B428-4B96-9CD7-497D2D1C738C}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{C97819B0-B428-4B96-9CD7-497D2D1C738C}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{C97819B0-B428-4B96-9CD7-497D2D1C738C}.Proto|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C97819B0-B428-4B96-9CD7-497D2D1C738C}.Proto|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C97819B0-B428-4B96-9CD7-497D2D1C738C}.Proto|x86.ActiveCfg = Debug|Any CPU
|
||||
{C97819B0-B428-4B96-9CD7-497D2D1C738C}.Proto|x86.Build.0 = Debug|Any CPU
|
||||
{C97819B0-B428-4B96-9CD7-497D2D1C738C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C97819B0-B428-4B96-9CD7-497D2D1C738C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{C97819B0-B428-4B96-9CD7-497D2D1C738C}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{C97819B0-B428-4B96-9CD7-497D2D1C738C}.Release|x86.Build.0 = Release|Any CPU
|
||||
{8B7BF62E-7D8C-4928-BE40-4E392A9EE851}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{8B7BF62E-7D8C-4928-BE40-4E392A9EE851}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8B7BF62E-7D8C-4928-BE40-4E392A9EE851}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
|
@ -295,8 +267,6 @@ Global
|
|||
{88E2D422-6852-46E3-A740-83E391DC7973} = {CFE3259A-2D30-4EB0-80D5-E8B5F3D01449}
|
||||
{53C0DAAD-158C-4658-8EC7-D7341530239F} = {CFE3259A-2D30-4EB0-80D5-E8B5F3D01449}
|
||||
{81B9FE26-C976-4FC7-B6CC-C7DB5903CAA7} = {3840F2E7-3898-45F7-8CF7-1E6829E56DB8}
|
||||
{99B3F4A5-80B4-41D9-A073-117DB6D7DBBA} = {B8DDA694-7939-42E3-95E5-265C2217C142}
|
||||
{C97819B0-B428-4B96-9CD7-497D2D1C738C} = {CFE3259A-2D30-4EB0-80D5-E8B5F3D01449}
|
||||
{8B7BF62E-7D8C-4928-BE40-4E392A9EE851} = {3881429D-A97A-49EB-B7AE-A82BA5FE9C77}
|
||||
{6771860A-614D-4FDD-A655-4C70EBCC91B0} = {B8DDA694-7939-42E3-95E5-265C2217C142}
|
||||
{4FEDF286-0252-4EBC-9E75-879CCA3B85DC} = {CFE3259A-2D30-4EB0-80D5-E8B5F3D01449}
|
||||
|
|
|
@ -144,12 +144,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.FSharp.Compiler",
|
|||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FSharp.Core.nuget", "src\fsharp\FSharp.Core.nuget\FSharp.Core.nuget.csproj", "{8EC30B2E-F1F9-4A98-BBB5-DD0CF6C84DDC}"
|
||||
EndProject
|
||||
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Compiler.LanguageServer", "src\fsharp\FSharp.Compiler.LanguageServer\FSharp.Compiler.LanguageServer.fsproj", "{60BAFFA5-6631-4328-B044-2E012AB76DCA}"
|
||||
EndProject
|
||||
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Compiler.LanguageServer.UnitTests", "tests\FSharp.Compiler.LanguageServer.UnitTests\FSharp.Compiler.LanguageServer.UnitTests.fsproj", "{AAF2D233-1C38-4090-8FFA-F7C545625E06}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FSharp.Editor.Helpers", "vsintegration\src\FSharp.Editor.Helpers\FSharp.Editor.Helpers.csproj", "{79255A92-ED00-40BA-9D64-12FCC664A976}"
|
||||
EndProject
|
||||
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Compiler.Private.Scripting", "src\fsharp\FSharp.Compiler.Private.Scripting\FSharp.Compiler.Private.Scripting.fsproj", "{20B7BC36-CF51-4D75-9E13-66681C07977F}"
|
||||
EndProject
|
||||
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Compiler.Private.Scripting.UnitTests", "tests\FSharp.Compiler.Private.Scripting.UnitTests\FSharp.Compiler.Private.Scripting.UnitTests.fsproj", "{09F56540-AFA5-4694-B7A6-0DBF6D4618C2}"
|
||||
|
@ -848,42 +842,6 @@ Global
|
|||
{8EC30B2E-F1F9-4A98-BBB5-DD0CF6C84DDC}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{8EC30B2E-F1F9-4A98-BBB5-DD0CF6C84DDC}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{8EC30B2E-F1F9-4A98-BBB5-DD0CF6C84DDC}.Release|x86.Build.0 = Release|Any CPU
|
||||
{60BAFFA5-6631-4328-B044-2E012AB76DCA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{60BAFFA5-6631-4328-B044-2E012AB76DCA}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{60BAFFA5-6631-4328-B044-2E012AB76DCA}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{60BAFFA5-6631-4328-B044-2E012AB76DCA}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{60BAFFA5-6631-4328-B044-2E012AB76DCA}.Proto|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{60BAFFA5-6631-4328-B044-2E012AB76DCA}.Proto|Any CPU.Build.0 = Debug|Any CPU
|
||||
{60BAFFA5-6631-4328-B044-2E012AB76DCA}.Proto|x86.ActiveCfg = Debug|Any CPU
|
||||
{60BAFFA5-6631-4328-B044-2E012AB76DCA}.Proto|x86.Build.0 = Debug|Any CPU
|
||||
{60BAFFA5-6631-4328-B044-2E012AB76DCA}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{60BAFFA5-6631-4328-B044-2E012AB76DCA}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{60BAFFA5-6631-4328-B044-2E012AB76DCA}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{60BAFFA5-6631-4328-B044-2E012AB76DCA}.Release|x86.Build.0 = Release|Any CPU
|
||||
{AAF2D233-1C38-4090-8FFA-F7C545625E06}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{AAF2D233-1C38-4090-8FFA-F7C545625E06}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{AAF2D233-1C38-4090-8FFA-F7C545625E06}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{AAF2D233-1C38-4090-8FFA-F7C545625E06}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{AAF2D233-1C38-4090-8FFA-F7C545625E06}.Proto|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{AAF2D233-1C38-4090-8FFA-F7C545625E06}.Proto|Any CPU.Build.0 = Debug|Any CPU
|
||||
{AAF2D233-1C38-4090-8FFA-F7C545625E06}.Proto|x86.ActiveCfg = Debug|Any CPU
|
||||
{AAF2D233-1C38-4090-8FFA-F7C545625E06}.Proto|x86.Build.0 = Debug|Any CPU
|
||||
{AAF2D233-1C38-4090-8FFA-F7C545625E06}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{AAF2D233-1C38-4090-8FFA-F7C545625E06}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{AAF2D233-1C38-4090-8FFA-F7C545625E06}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{AAF2D233-1C38-4090-8FFA-F7C545625E06}.Release|x86.Build.0 = Release|Any CPU
|
||||
{79255A92-ED00-40BA-9D64-12FCC664A976}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{79255A92-ED00-40BA-9D64-12FCC664A976}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{79255A92-ED00-40BA-9D64-12FCC664A976}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{79255A92-ED00-40BA-9D64-12FCC664A976}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{79255A92-ED00-40BA-9D64-12FCC664A976}.Proto|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{79255A92-ED00-40BA-9D64-12FCC664A976}.Proto|Any CPU.Build.0 = Release|Any CPU
|
||||
{79255A92-ED00-40BA-9D64-12FCC664A976}.Proto|x86.ActiveCfg = Release|Any CPU
|
||||
{79255A92-ED00-40BA-9D64-12FCC664A976}.Proto|x86.Build.0 = Release|Any CPU
|
||||
{79255A92-ED00-40BA-9D64-12FCC664A976}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{79255A92-ED00-40BA-9D64-12FCC664A976}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{79255A92-ED00-40BA-9D64-12FCC664A976}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{79255A92-ED00-40BA-9D64-12FCC664A976}.Release|x86.Build.0 = Release|Any CPU
|
||||
{20B7BC36-CF51-4D75-9E13-66681C07977F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{20B7BC36-CF51-4D75-9E13-66681C07977F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{20B7BC36-CF51-4D75-9E13-66681C07977F}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
|
@ -1035,9 +993,6 @@ Global
|
|||
{9482211E-23D0-4BD0-9893-E4AA5559F67A} = {6235B3AF-774D-4EA1-8F37-789E767F6368}
|
||||
{04C59F6E-1C76-4F6A-AC21-2EA7F296A1B8} = {647810D0-5307-448F-99A2-E83917010DAE}
|
||||
{8EC30B2E-F1F9-4A98-BBB5-DD0CF6C84DDC} = {647810D0-5307-448F-99A2-E83917010DAE}
|
||||
{60BAFFA5-6631-4328-B044-2E012AB76DCA} = {B8DDA694-7939-42E3-95E5-265C2217C142}
|
||||
{AAF2D233-1C38-4090-8FFA-F7C545625E06} = {CFE3259A-2D30-4EB0-80D5-E8B5F3D01449}
|
||||
{79255A92-ED00-40BA-9D64-12FCC664A976} = {4C7B48D7-19AF-4AE7-9D1D-3BB289D5480D}
|
||||
{20B7BC36-CF51-4D75-9E13-66681C07977F} = {B8DDA694-7939-42E3-95E5-265C2217C142}
|
||||
{09F56540-AFA5-4694-B7A6-0DBF6D4618C2} = {CFE3259A-2D30-4EB0-80D5-E8B5F3D01449}
|
||||
{DFA30881-C0B1-4813-B087-C21B5AF9B77F} = {3881429D-A97A-49EB-B7AE-A82BA5FE9C77}
|
||||
|
|
|
@ -343,7 +343,6 @@ try {
|
|||
|
||||
if ($testDesktop -and -not $noVisualStudio) {
|
||||
TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Compiler.UnitTests\FSharp.Compiler.UnitTests.fsproj" -targetFramework $desktopTargetFramework
|
||||
TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Compiler.LanguageServer.UnitTests\FSharp.Compiler.LanguageServer.UnitTests.fsproj" -targetFramework $desktopTargetFramework
|
||||
TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Compiler.Private.Scripting.UnitTests\FSharp.Compiler.Private.Scripting.UnitTests.fsproj" -targetFramework $desktopTargetFramework
|
||||
TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Build.UnitTests\FSharp.Build.UnitTests.fsproj" -targetFramework $desktopTargetFramework
|
||||
TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Core.UnitTests\FSharp.Core.UnitTests.fsproj" -targetFramework $desktopTargetFramework
|
||||
|
@ -352,7 +351,6 @@ try {
|
|||
|
||||
if ($testCoreClr) {
|
||||
TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Compiler.UnitTests\FSharp.Compiler.UnitTests.fsproj" -targetFramework $coreclrTargetFramework
|
||||
TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Compiler.LanguageServer.UnitTests\FSharp.Compiler.LanguageServer.UnitTests.fsproj" -targetFramework $coreclrTargetFramework
|
||||
TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Compiler.Private.Scripting.UnitTests\FSharp.Compiler.Private.Scripting.UnitTests.fsproj" -targetFramework $coreclrTargetFramework
|
||||
TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Build.UnitTests\FSharp.Build.UnitTests.fsproj" -targetFramework $coreclrTargetFramework
|
||||
TestUsingNUnit -testProject "$RepoRoot\tests\FSharp.Core.UnitTests\FSharp.Core.UnitTests.fsproj" -targetFramework $coreclrTargetFramework
|
||||
|
|
|
@ -122,7 +122,6 @@
|
|||
<MicrosoftVisualStudioGraphModelVersion>16.0.28226-alpha</MicrosoftVisualStudioGraphModelVersion>
|
||||
<MicrosoftVisualStudioImageCatalogVersion>16.1.28916.169</MicrosoftVisualStudioImageCatalogVersion>
|
||||
<MicrosoftVisualStudioImagingVersion>16.1.28917.181</MicrosoftVisualStudioImagingVersion>
|
||||
<MicrosoftVisualStudioLanguageServerClientVersion>16.1.3121</MicrosoftVisualStudioLanguageServerClientVersion>
|
||||
<MicrosoftVisualStudioLanguageStandardClassificationVersion>16.1.89</MicrosoftVisualStudioLanguageStandardClassificationVersion>
|
||||
<MicrosoftVisualStudioLanguageVersion>16.1.89</MicrosoftVisualStudioLanguageVersion>
|
||||
<MicrosoftVisualStudioLanguageIntellisenseVersion>16.1.89</MicrosoftVisualStudioLanguageIntellisenseVersion>
|
||||
|
|
|
@ -290,7 +290,6 @@ BuildSolution
|
|||
if [[ "$test_core_clr" == true ]]; then
|
||||
coreclrtestframework=netcoreapp3.0
|
||||
TestUsingNUnit --testproject "$repo_root/tests/FSharp.Compiler.UnitTests/FSharp.Compiler.UnitTests.fsproj" --targetframework $coreclrtestframework
|
||||
TestUsingNUnit --testproject "$repo_root/tests/FSharp.Compiler.LanguageServer.UnitTests/FSharp.Compiler.LanguageServer.UnitTests.fsproj" --targetframework $coreclrtestframework
|
||||
TestUsingNUnit --testproject "$repo_root/tests/FSharp.Compiler.Private.Scripting.UnitTests/FSharp.Compiler.Private.Scripting.UnitTests.fsproj" --targetframework $coreclrtestframework
|
||||
TestUsingNUnit --testproject "$repo_root/tests/FSharp.Build.UnitTests/FSharp.Build.UnitTests.fsproj" --targetframework $coreclrtestframework
|
||||
TestUsingNUnit --testproject "$repo_root/tests/FSharp.Core.UnitTests/FSharp.Core.UnitTests.fsproj" --targetframework $coreclrtestframework
|
||||
|
|
|
@ -12,9 +12,4 @@
|
|||
<EmbedUntrackedSources>false</EmbedUntrackedSources>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<!-- this should be false for branch `release/dev16.2`, true otherwise -->
|
||||
<IncludeVsLanguageServer>false</IncludeVsLanguageServer>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
<Project>
|
||||
|
||||
<PropertyGroup>
|
||||
<UseFSharpProductVersion>true</UseFSharpProductVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<Import Project="$([MSBuild]::GetPathOfFileAbove('Directory.Build.props', '$(MSBuildThisFileDirectory)../'))" />
|
||||
|
||||
</Project>
|
|
@ -1,49 +0,0 @@
|
|||
<Project DefaultTargets="Build">
|
||||
|
||||
<!--
|
||||
|
||||
Usage: dotnet build <this-file> /p:ProjectFile=<path-to-project>
|
||||
Returns: The project's supported target frameworks, one per line, in the format of:
|
||||
DetectedTargetFramework=<tfm-1>
|
||||
DetectedTargetFramework=<tfm-2>
|
||||
...
|
||||
|
||||
Usage: dotnet build <this-file> /p:ProjectFile=<path-to-project> /p:TargetFramework=<tfm>
|
||||
Returns: The project's command line arguments, one per line, as they would be passed to fsc.exe in the format of:
|
||||
DetectedCommandLineArg=<arg-1>
|
||||
DetectedCommandLineArg=<arg-2>
|
||||
...
|
||||
|
||||
To avoid recreating a distribution of MSBuild just to get some evaluated project values, we instead inject a special
|
||||
targets file into the specified project which then prints the values with a well-known prefix that's easy to parse.
|
||||
|
||||
The benefits of doing it this way are:
|
||||
- We don't have to re-create a copy of MSBuild. That would be difficult, large, and change frequently.
|
||||
- This works on any OS and any TFM.
|
||||
- We use the exact version of MSBuild and the compiler that the user has instead of dealing with the potential
|
||||
mismatch between what this tool would include vs. what they actually have.
|
||||
|
||||
The downsides of this method are:
|
||||
- We're dependent upon the continued existence of some well-known Targets and ItemGroups, but the ones we depend on
|
||||
have been stable for some time.
|
||||
- An external process invoke is slow, but this is only done once at LSP instantiation.
|
||||
|
||||
-->
|
||||
|
||||
<PropertyGroup>
|
||||
<!-- See this file for details on the magic. -->
|
||||
<InjetedTargetsFile>$(MSBuildThisFileDirectory)FSharp.Compiler.LanguageServer.DesignTime.targets</InjetedTargetsFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<Target Name="Build">
|
||||
<Error Text="Property `ProjectFile` must be specified." Condition="'$(ProjectFile)' == ''" />
|
||||
|
||||
<!-- report TFMs if none specified -->
|
||||
<MSBuild Projects="$(ProjectFile)" Targets="ReportTargetFrameworks" Properties="CustomAfterMicrosoftCommonCrossTargetingTargets=$(InjetedTargetsFile);CustomAfterMicrosoftCommonTargets=$(InjetedTargetsFile)" Condition="'$(TargetFramework)' == ''" />
|
||||
|
||||
<!-- report command line arguments when TFM is given -->
|
||||
<MSBuild Projects="$(ProjectFile)" Targets="Restore" Condition="'$(TargetFramework)' != ''" />
|
||||
<MSBuild Projects="$(ProjectFile)" Targets="ReportCommandLineArgs" Properties="DesignTimeBuild=true;CustomAfterMicrosoftCommonTargets=$(InjetedTargetsFile);TargetFramework=$(TargetFramework)" Condition="'$(TargetFramework)' != ''" />
|
||||
</Target>
|
||||
|
||||
</Project>
|
|
@ -1,52 +0,0 @@
|
|||
<Project>
|
||||
|
||||
<!--
|
||||
Accurately reporting the command line arguments requires that the target Restore is run _without_ these values having
|
||||
been set. The project file helper associated with this .targets file calls Restore before calling into the target
|
||||
that prints the command line arguments.
|
||||
-->
|
||||
<PropertyGroup Condition="'$(DesignTimeBuild)' == 'true'">
|
||||
<ProvideCommandLineArgs>true</ProvideCommandLineArgs>
|
||||
<BuildProjectReferences>false</BuildProjectReferences>
|
||||
<SkipCompilerExecution>true</SkipCompilerExecution>
|
||||
<DisableRarCache>true</DisableRarCache>
|
||||
<AutoGenerateBindingRedirects>false</AutoGenerateBindingRedirects>
|
||||
<CopyBuildOutputToOutputDirectory>false</CopyBuildOutputToOutputDirectory>
|
||||
<CopyOutputSymbolsToOutputDirectory>false</CopyOutputSymbolsToOutputDirectory>
|
||||
<SkipCopyBuildProduct>true</SkipCopyBuildProduct>
|
||||
<AddModules>false</AddModules>
|
||||
<UseCommonOutputDirectory>true</UseCommonOutputDirectory>
|
||||
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- displays the target frameworks of a cross-targeted project -->
|
||||
<Target Name="_ComputeDependsOn">
|
||||
<!--
|
||||
In a multi-targeted project, the _ComputeTargetFrameworkItems populates the ItemGroup _TargetFramework with the
|
||||
appropriate values. If the project contains just a single value for $(TargetFramework) then the target
|
||||
_ComputeTargetFrameworkItems doesn't exist, so instead the helper target _PopulateTargetFrameworks is run which
|
||||
populates the same group.
|
||||
-->
|
||||
<PropertyGroup>
|
||||
<WorkerDependsOn Condition="'$(TargetFramework)' == ''">_ComputeTargetFrameworkItems</WorkerDependsOn>
|
||||
<WorkerDependsOn Condition="'$(TargetFramework)' != ''">_PopulateTargetFrameworks</WorkerDependsOn>
|
||||
</PropertyGroup>
|
||||
</Target>
|
||||
<Target Name="_PopulateTargetFrameworks">
|
||||
<ItemGroup>
|
||||
<_TargetFramework Include="$(TargetFramework)" />
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
<Target Name="_ReportTargetFrameworksWorker" DependsOnTargets="_ComputeDependsOn;$(WorkerDependsOn)">
|
||||
<Message Text="DetectedTargetFramework=%(_TargetFramework.Identity)" Importance="High" />
|
||||
</Target>
|
||||
<Target Name="ReportTargetFrameworks" DependsOnTargets="_ComputeDependsOn;_ReportTargetFrameworksWorker">
|
||||
</Target>
|
||||
|
||||
<!-- displays the command line arguments passed to fsc.exe -->
|
||||
<Target Name="ReportCommandLineArgs"
|
||||
DependsOnTargets="Build">
|
||||
<Message Text="DetectedCommandLineArg=%(FscCommandLineArgs.Identity)" Importance="High" />
|
||||
</Target>
|
||||
|
||||
</Project>
|
|
@ -1,59 +0,0 @@
|
|||
<!-- Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -->
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetExt>.exe</TargetExt>
|
||||
<TargetFrameworks>net472;netcoreapp3.0</TargetFrameworks>
|
||||
<TargetFrameworks Condition="'$(OS)' == 'Unix'">netcoreapp3.0</TargetFrameworks>
|
||||
<IsPackable>true</IsPackable>
|
||||
<PackageDescription>Implements the Language Server Protocol (LSP) for F#.</PackageDescription>
|
||||
<ExcludeFromSourceBuild>true</ExcludeFromSourceBuild>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="JsonDUConverter.fs" />
|
||||
<Compile Include="JsonOptionConverter.fs" />
|
||||
<Compile Include="LspTypes.fs" />
|
||||
<Compile Include="LspExternalAccess.fs" />
|
||||
<Compile Include="State.fs" />
|
||||
<Compile Include="TextDocument.fs" />
|
||||
<Compile Include="Methods.fs" />
|
||||
<Compile Include="Server.fs" />
|
||||
<Compile Include="Program.fs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="FSharp.Compiler.LanguageServer.DesignTime.proj" CopyToOutputDirectory="PreserveNewest" />
|
||||
<None Include="FSharp.Compiler.LanguageServer.DesignTime.targets" CopyToOutputDirectory="PreserveNewest" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<InternalsVisibleTo Include="FSharp.Compiler.LanguageServer.UnitTests" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="$(MSBuildThisFileDirectory)..\FSharp.Compiler.Private\FSharp.Compiler.Private.fsproj" />
|
||||
<ProjectReference Include="$(MSBuildThisFileDirectory)..\FSharp.Core\FSharp.Core.fsproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="StreamJsonRpc" Version="$(StreamJsonRpcVersion)" />
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="GatherPublishedProjectOutputGroupItems"
|
||||
DependsOnTargets="Publish">
|
||||
<ItemGroup>
|
||||
<_PublishedProjectOutputGroupFiles Include="$(PublishDir)\**" />
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
<Target Name="PublishedProjectOutputGroup"
|
||||
Returns="@(PublishedProjectOutputGroupOutput)"
|
||||
DependsOnTargets="GatherPublishedProjectOutputGroupItems">
|
||||
<ItemGroup>
|
||||
<PublishedProjectOutputGroupOutput Include="@(_PublishedProjectOutputGroupFiles)" TargetPath="Agent\%(RecursiveDir)%(FileName)%(Extension)" />
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
</Project>
|
|
@ -1,18 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
|
||||
|
||||
namespace FSharp.Compiler.LanguageServer
|
||||
|
||||
open System
|
||||
open FSharp.Reflection
|
||||
open Newtonsoft.Json
|
||||
|
||||
type JsonDUConverter() =
|
||||
inherit JsonConverter()
|
||||
override __.CanConvert(typ) = FSharpType.IsUnion(typ)
|
||||
override __.WriteJson(writer, value, _serializer) =
|
||||
writer.WriteValue(value.ToString().ToLowerInvariant())
|
||||
override __.ReadJson(reader, typ, x, serializer) =
|
||||
let cases = FSharpType.GetUnionCases(typ)
|
||||
let str = serializer.Deserialize(reader, typeof<string>) :?> string
|
||||
let case = cases |> Array.find (fun c -> String.Compare(c.Name, str, StringComparison.OrdinalIgnoreCase) = 0)
|
||||
FSharpValue.MakeUnion(case, [||])
|
|
@ -1,27 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
|
||||
|
||||
namespace FSharp.Compiler.LanguageServer
|
||||
|
||||
open System
|
||||
open FSharp.Reflection
|
||||
open Newtonsoft.Json
|
||||
|
||||
type JsonOptionConverter() =
|
||||
inherit JsonConverter()
|
||||
override __.CanConvert(typ) = typ.IsGenericType && typ.GetGenericTypeDefinition() = typedefof<option<_>>
|
||||
override __.WriteJson(writer, value, serializer) =
|
||||
let value = match value with
|
||||
| null -> null
|
||||
| _ ->
|
||||
let _, fields = FSharpValue.GetUnionFields(value, value.GetType())
|
||||
fields.[0]
|
||||
serializer.Serialize(writer, value)
|
||||
override __.ReadJson(reader, typ, _, serializer) =
|
||||
let innerType = typ.GetGenericArguments().[0]
|
||||
let innerType =
|
||||
if innerType.IsValueType then (typedefof<Nullable<_>>).MakeGenericType([|innerType|])
|
||||
else innerType
|
||||
let value = serializer.Deserialize(reader, innerType)
|
||||
let cases = FSharpType.GetUnionCases(typ)
|
||||
if value = null then FSharpValue.MakeUnion(cases.[0], [||])
|
||||
else FSharpValue.MakeUnion(cases.[1], [|value|])
|
|
@ -1,30 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
|
||||
|
||||
namespace FSharp.Compiler.LanguageServer
|
||||
|
||||
open StreamJsonRpc
|
||||
|
||||
[<AutoOpen>]
|
||||
module FunctionNames =
|
||||
[<Literal>]
|
||||
let OptionsSet = "options/set"
|
||||
|
||||
[<Literal>]
|
||||
let TextDocumentPublishDiagnostics = "textDocument/publishDiagnostics"
|
||||
|
||||
type Options =
|
||||
{ usePreviewTextHover: bool
|
||||
usePreviewDiagnostics: bool }
|
||||
static member Default() =
|
||||
{ usePreviewTextHover = false
|
||||
usePreviewDiagnostics = false }
|
||||
static member AllOn() =
|
||||
{ usePreviewTextHover = true
|
||||
usePreviewDiagnostics = true }
|
||||
|
||||
module Extensions =
|
||||
type JsonRpc with
|
||||
member jsonRpc.SetOptionsAsync (options: Options) =
|
||||
async {
|
||||
do! jsonRpc.InvokeAsync(OptionsSet, options) |> Async.AwaitTask
|
||||
}
|
|
@ -1,87 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
|
||||
|
||||
namespace FSharp.Compiler.LanguageServer
|
||||
|
||||
open Newtonsoft.Json.Linq
|
||||
open Newtonsoft.Json
|
||||
|
||||
// Interfaces as defined at https://microsoft.github.io/language-server-protocol/specifications/specification-3-14/.
|
||||
// The properties on these types are camlCased to match the underlying JSON properties to avoid attributes on every
|
||||
// field:
|
||||
// [<JsonProperty("camlCased")>]
|
||||
|
||||
/// Represents a zero-based line and column of a text document.
|
||||
type Position =
|
||||
{ line: int
|
||||
character: int }
|
||||
|
||||
type Range =
|
||||
{ start: Position
|
||||
``end``: Position }
|
||||
|
||||
type DocumentUri = string
|
||||
|
||||
type Location =
|
||||
{ uri: DocumentUri
|
||||
range: Range }
|
||||
|
||||
type DiagnosticRelatedInformation =
|
||||
{ location: Location
|
||||
message: string }
|
||||
|
||||
type Diagnostic =
|
||||
{ range: Range
|
||||
severity: int option
|
||||
code: string
|
||||
source: string option
|
||||
message: string
|
||||
relatedInformation: DiagnosticRelatedInformation[] option }
|
||||
static member Error = 1
|
||||
static member Warning = 2
|
||||
static member Information = 3
|
||||
static member Hint = 4
|
||||
|
||||
type PublishDiagnosticsParams =
|
||||
{ uri: DocumentUri
|
||||
diagnostics: Diagnostic[] }
|
||||
|
||||
type ClientCapabilities =
|
||||
{ workspace: JToken option // TODO: WorkspaceClientCapabilities
|
||||
textDocument: JToken option // TODO: TextDocumentClientCapabilities, publishDiagnostics: { relatedInformation: bool option }
|
||||
experimental: JToken option
|
||||
supportsVisualStudioExtensions: bool option }
|
||||
|
||||
[<JsonConverter(typeof<JsonDUConverter>)>]
|
||||
type Trace =
|
||||
| Off
|
||||
| Messages
|
||||
| Verbose
|
||||
|
||||
type WorkspaceFolder =
|
||||
{ uri: DocumentUri
|
||||
name: string }
|
||||
|
||||
/// Note, this type has many more optional values that can be expanded as support is added.
|
||||
type ServerCapabilities =
|
||||
{ hoverProvider: bool }
|
||||
static member DefaultCapabilities() =
|
||||
{ ServerCapabilities.hoverProvider = true }
|
||||
|
||||
type InitializeResult =
|
||||
{ capabilities: ServerCapabilities }
|
||||
|
||||
[<JsonConverter(typeof<JsonDUConverter>)>]
|
||||
type MarkupKind =
|
||||
| PlainText
|
||||
| Markdown
|
||||
|
||||
type MarkupContent =
|
||||
{ kind: MarkupKind
|
||||
value: string }
|
||||
|
||||
type Hover =
|
||||
{ contents: MarkupContent
|
||||
range: Range option }
|
||||
|
||||
type TextDocumentIdentifier =
|
||||
{ uri: DocumentUri }
|
|
@ -1,72 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
|
||||
|
||||
namespace FSharp.Compiler.LanguageServer
|
||||
|
||||
open System
|
||||
open System.Runtime.InteropServices
|
||||
open System.Threading
|
||||
open Newtonsoft.Json.Linq
|
||||
open StreamJsonRpc
|
||||
|
||||
// https://microsoft.github.io/language-server-protocol/specifications/specification-3-14/
|
||||
type Methods() =
|
||||
|
||||
let state = State()
|
||||
|
||||
/// Helper to run Async<'T> with a CancellationToken.
|
||||
let runAsync (cancellationToken: CancellationToken) (computation: Async<'T>) = Async.StartAsTask(computation, cancellationToken=cancellationToken)
|
||||
|
||||
member __.State = state
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// official LSP methods
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
[<JsonRpcMethod("initialize")>]
|
||||
member __.Initialize
|
||||
(
|
||||
processId: Nullable<int>,
|
||||
[<Optional; DefaultParameterValue(null: string)>] rootPath: string,
|
||||
[<Optional; DefaultParameterValue(null: string)>] rootUri: DocumentUri,
|
||||
[<Optional; DefaultParameterValue(null: JToken)>] initializationOptions: JToken,
|
||||
capabilities: ClientCapabilities,
|
||||
[<Optional; DefaultParameterValue(null: string)>] trace: string,
|
||||
[<Optional; DefaultParameterValue(null: WorkspaceFolder[])>] workspaceFolders: WorkspaceFolder[],
|
||||
[<Optional; DefaultParameterValue(CancellationToken())>] cancellationToken: CancellationToken
|
||||
) =
|
||||
state.Initialize rootPath rootUri (fun projectOptions -> TextDocument.PublishDiagnostics(state, projectOptions) |> Async.Start)
|
||||
{ InitializeResult.capabilities = ServerCapabilities.DefaultCapabilities() }
|
||||
|
||||
[<JsonRpcMethod("initialized")>]
|
||||
member __.Initialized () = ()
|
||||
|
||||
[<JsonRpcMethod("shutdown")>]
|
||||
member __.Shutdown(): obj = state.DoShutdown(); null
|
||||
|
||||
[<JsonRpcMethod("exit")>]
|
||||
member __.Exit() = state.DoExit()
|
||||
|
||||
[<JsonRpcMethod("$/cancelRequest")>]
|
||||
member __.cancelRequest (id: JToken) = state.DoCancel()
|
||||
|
||||
[<JsonRpcMethod("textDocument/hover")>]
|
||||
member __.TextDocumentHover
|
||||
(
|
||||
textDocument: TextDocumentIdentifier,
|
||||
position: Position,
|
||||
[<Optional; DefaultParameterValue(CancellationToken())>] cancellationToken: CancellationToken
|
||||
) =
|
||||
TextDocument.Hover state textDocument position |> runAsync cancellationToken
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// unofficial LSP methods that we implement separately
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
[<JsonRpcMethod(OptionsSet)>]
|
||||
member __.OptionsSet
|
||||
(
|
||||
options: Options
|
||||
) =
|
||||
eprintfn "got options %A" options
|
||||
state.Options <- options
|
||||
state.InvalidateAllProjects()
|
|
@ -1,16 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
|
||||
|
||||
namespace FSharp.Compiler.LanguageServer
|
||||
|
||||
open System
|
||||
|
||||
module Program =
|
||||
|
||||
[<EntryPoint>]
|
||||
let main(args: string[]) =
|
||||
async {
|
||||
let server = new Server(Console.OpenStandardOutput(), Console.OpenStandardInput())
|
||||
server.StartListening()
|
||||
do! server.WaitForExitAsync()
|
||||
return 0
|
||||
} |> Async.RunSynchronously
|
|
@ -1,30 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
|
||||
|
||||
namespace FSharp.Compiler.LanguageServer
|
||||
|
||||
open System
|
||||
open System.IO
|
||||
open StreamJsonRpc
|
||||
|
||||
type Server(sendingStream: Stream, receivingStream: Stream) =
|
||||
|
||||
let formatter = JsonMessageFormatter()
|
||||
let converter = JsonOptionConverter() // special handler to convert between `Option<'T>` and `obj/null`.
|
||||
do formatter.JsonSerializer.Converters.Add(converter)
|
||||
let handler = new HeaderDelimitedMessageHandler(sendingStream, receivingStream, formatter)
|
||||
let methods = Methods()
|
||||
let rpc = new JsonRpc(handler, methods)
|
||||
do methods.State.JsonRpc <- Some rpc
|
||||
|
||||
member __.StartListening() =
|
||||
rpc.StartListening()
|
||||
|
||||
member __.WaitForExitAsync() =
|
||||
async {
|
||||
do! Async.AwaitEvent (methods.State.Shutdown)
|
||||
do! Async.AwaitEvent (methods.State.Exit)
|
||||
}
|
||||
|
||||
interface IDisposable with
|
||||
member __.Dispose() =
|
||||
rpc.Dispose()
|
|
@ -1,233 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
|
||||
|
||||
namespace FSharp.Compiler.LanguageServer
|
||||
|
||||
open System
|
||||
open System.Collections.Concurrent
|
||||
open System.Collections.Generic
|
||||
open System.Diagnostics
|
||||
open System.IO
|
||||
open System.Text.RegularExpressions
|
||||
open FSharp.Compiler.SourceCodeServices
|
||||
open StreamJsonRpc
|
||||
|
||||
module internal Solution =
|
||||
// easy unit testing
|
||||
let getProjectPaths (solutionContent: string) (solutionDir: string) =
|
||||
// This looks scary, but is much more lightweight than carrying along MSBuild just to have it parse the solution file.
|
||||
//
|
||||
// A valid line in .sln looks like:
|
||||
// Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "ConsoleApp2", "ConsoleApp2\ConsoleApp2.fsproj", "{60A4BE67-7E03-4200-AD38-B0E5E8E049C1}"
|
||||
// and we're hoping to extract this: ------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
//
|
||||
// therefore:
|
||||
// ^Project text 'Project' at the start of the line
|
||||
// .* any number of characters
|
||||
// \"" double quote character (it's doubled up to escape from the raw string literal here)
|
||||
// ( start of capture group
|
||||
// [^\""] not a quote
|
||||
// * many of those
|
||||
// \.fsproj literal string ".fsproj"
|
||||
// ) end of capture group
|
||||
// \"" double quote
|
||||
let pattern = Regex(@"^Project.*\""([^\""]*\.fsproj)\""")
|
||||
let lines = solutionContent.Split('\n')
|
||||
let relativeProjects =
|
||||
lines
|
||||
|> Array.map pattern.Match
|
||||
|> Array.filter (fun m -> m.Success)
|
||||
|> Array.map (fun m -> m.Groups.[1].Value)
|
||||
// .sln files by convention uses backslashes, which might not be appropriate at runtime
|
||||
|> Array.map (fun p -> p.Replace('\\', Path.DirectorySeparatorChar))
|
||||
let projects =
|
||||
relativeProjects
|
||||
|> Array.map (fun p -> if Path.IsPathRooted(p) then p else Path.Combine(solutionDir, p))
|
||||
projects
|
||||
|
||||
type State() =
|
||||
|
||||
let checker = FSharpChecker.Create()
|
||||
|
||||
let sourceFileToProjectMap = ConcurrentDictionary<string, FSharpProjectOptions>()
|
||||
|
||||
let shutdownEvent = new Event<_>()
|
||||
let exitEvent = new Event<_>()
|
||||
let cancelEvent = new Event<_>()
|
||||
let projectInvalidatedEvent = new Event<_>()
|
||||
|
||||
let fileChanged (args: FileSystemEventArgs) =
|
||||
match sourceFileToProjectMap.TryGetValue args.FullPath with
|
||||
| true, projectOptions -> projectInvalidatedEvent.Trigger(projectOptions)
|
||||
| false, _ -> ()
|
||||
let fileRenamed (args: RenamedEventArgs) =
|
||||
match sourceFileToProjectMap.TryGetValue args.FullPath with
|
||||
| true, projectOptions -> projectInvalidatedEvent.Trigger(projectOptions)
|
||||
| false, _ -> ()
|
||||
let fileWatcher = new FileSystemWatcher()
|
||||
do fileWatcher.IncludeSubdirectories <- true
|
||||
do fileWatcher.Changed.Add(fileChanged)
|
||||
do fileWatcher.Created.Add(fileChanged)
|
||||
do fileWatcher.Deleted.Add(fileChanged)
|
||||
do fileWatcher.Renamed.Add(fileRenamed)
|
||||
|
||||
let execProcess (name: string) (args: string) =
|
||||
let startInfo = ProcessStartInfo(name, args)
|
||||
eprintfn "executing: %s %s" name args
|
||||
startInfo.CreateNoWindow <- true
|
||||
startInfo.RedirectStandardOutput <- true
|
||||
startInfo.UseShellExecute <- false
|
||||
let lines = List<string>()
|
||||
use proc = new Process()
|
||||
proc.StartInfo <- startInfo
|
||||
proc.OutputDataReceived.Add(fun args -> lines.Add(args.Data))
|
||||
proc.Start() |> ignore
|
||||
proc.BeginOutputReadLine()
|
||||
proc.WaitForExit()
|
||||
lines.ToArray()
|
||||
|
||||
let linesWithPrefixClean (prefix: string) (lines: string[]) =
|
||||
lines
|
||||
|> Array.filter (isNull >> not)
|
||||
|> Array.map (fun line -> line.TrimStart(' '))
|
||||
|> Array.filter (fun line -> line.StartsWith(prefix))
|
||||
|> Array.map (fun line -> line.Substring(prefix.Length))
|
||||
|
||||
let getProjectOptions (rootDir: string) =
|
||||
if isNull rootDir then [||]
|
||||
else
|
||||
fileWatcher.Path <- rootDir
|
||||
fileWatcher.EnableRaisingEvents <- true
|
||||
|
||||
/// This function is meant to be temporary. Until we figure out what a language server for a project
|
||||
/// system looks like, we have to guess based on the files we find in the root.
|
||||
let getProjectOptions (projectPath: string) =
|
||||
let projectDir = Path.GetDirectoryName(projectPath)
|
||||
let normalizePath (path: string) =
|
||||
if Path.IsPathRooted(path) then path
|
||||
else Path.Combine(projectDir, path)
|
||||
|
||||
// To avoid essentially re-creating a copy of MSBuild alongside this tool, we instead fake a design-
|
||||
// time build with this project. The output of building this helper project is text that's easily
|
||||
// parsable. See the helper project for more information.
|
||||
let reporterProject = Path.Combine(Path.GetDirectoryName(typeof<State>.Assembly.Location), "FSharp.Compiler.LanguageServer.DesignTime.proj")
|
||||
let detectedTfmSentinel = "DetectedTargetFramework="
|
||||
let detectedCommandLineArgSentinel = "DetectedCommandLineArg="
|
||||
|
||||
let execTfmReporter =
|
||||
sprintf "build \"%s\" \"/p:ProjectFile=%s\"" reporterProject projectPath
|
||||
|> execProcess "dotnet"
|
||||
|
||||
let execArgReporter (tfm: string) =
|
||||
sprintf "build \"%s\" \"/p:ProjectFile=%s\" \"/p:TargetFramework=%s\"" reporterProject projectPath tfm
|
||||
|> execProcess "dotnet"
|
||||
|
||||
// find the target frameworks
|
||||
let targetFrameworks =
|
||||
execTfmReporter
|
||||
|> linesWithPrefixClean detectedTfmSentinel
|
||||
|
||||
let getArgs (tfm: string) =
|
||||
execArgReporter tfm
|
||||
|> linesWithPrefixClean detectedCommandLineArgSentinel
|
||||
|
||||
let tfmAndArgs =
|
||||
targetFrameworks
|
||||
|> Array.map (fun tfm -> tfm, getArgs tfm)
|
||||
|
||||
let separateArgs (args: string[]) =
|
||||
args
|
||||
|> Array.partition (fun a -> a.StartsWith("-"))
|
||||
|> (fun (options, files) ->
|
||||
let normalizedFiles = files |> Array.map normalizePath
|
||||
options, normalizedFiles)
|
||||
|
||||
// TODO: for now we're only concerned with the first TFM
|
||||
let _tfm, args = Array.head tfmAndArgs
|
||||
|
||||
let otherOptions, sourceFiles = separateArgs args
|
||||
|
||||
let projectOptions: FSharpProjectOptions =
|
||||
{ ProjectFileName = projectPath
|
||||
ProjectId = None
|
||||
SourceFiles = sourceFiles
|
||||
OtherOptions = otherOptions
|
||||
ReferencedProjects = [||] // TODO: populate from @(ProjectReference)
|
||||
IsIncompleteTypeCheckEnvironment = false
|
||||
UseScriptResolutionRules = false
|
||||
LoadTime = DateTime.Now
|
||||
UnresolvedReferences = None
|
||||
OriginalLoadReferences = []
|
||||
ExtraProjectInfo = None
|
||||
Stamp = None }
|
||||
projectOptions
|
||||
let topLevelProjects = Directory.GetFiles(rootDir, "*.fsproj")
|
||||
let watchableProjectPaths =
|
||||
match topLevelProjects with
|
||||
| [||] ->
|
||||
match Directory.GetFiles(rootDir, "*.sln") with
|
||||
// TODO: what to do with multiple .sln or a combo of .sln/.fsproj?
|
||||
| [| singleSolution |] ->
|
||||
let content = File.ReadAllText(singleSolution)
|
||||
let solutionDir = Path.GetDirectoryName(singleSolution)
|
||||
Solution.getProjectPaths content solutionDir
|
||||
| _ -> [||]
|
||||
| _ -> topLevelProjects
|
||||
let watchableProjectOptions =
|
||||
watchableProjectPaths
|
||||
|> Array.map getProjectOptions
|
||||
|
||||
// associate source files with project options
|
||||
let watchFile file projectOptions =
|
||||
sourceFileToProjectMap.AddOrUpdate(file, projectOptions, fun _ _ -> projectOptions)
|
||||
|
||||
for projectOptions in watchableProjectOptions do
|
||||
// watch .fsproj
|
||||
watchFile projectOptions.ProjectFileName projectOptions |> ignore
|
||||
// TODO: watch .deps.json
|
||||
for sourceFile in projectOptions.SourceFiles do
|
||||
let sourceFileFullPath =
|
||||
if Path.IsPathRooted(sourceFile) then sourceFile
|
||||
else
|
||||
let projectDir = Path.GetDirectoryName(projectOptions.ProjectFileName)
|
||||
Path.Combine(projectDir, sourceFile)
|
||||
watchFile sourceFileFullPath projectOptions |> ignore
|
||||
|
||||
watchableProjectOptions
|
||||
|
||||
member __.Checker = checker
|
||||
|
||||
/// Initialize the LSP at the specified location. According to the spec, `rootUri` is to be preferred over `rootPath`.
|
||||
member __.Initialize (rootPath: string) (rootUri: DocumentUri) (computeDiagnostics: FSharpProjectOptions -> unit) =
|
||||
let rootDir =
|
||||
if not (isNull rootUri) then Uri(rootUri).LocalPath
|
||||
else rootPath
|
||||
let projectOptions = getProjectOptions rootDir
|
||||
projectInvalidatedEvent.Publish.Add computeDiagnostics // compute diagnostics on project invalidation
|
||||
for projectOption in projectOptions do
|
||||
computeDiagnostics projectOption // compute initial set of diagnostics
|
||||
|
||||
[<CLIEvent>]
|
||||
member __.Shutdown = shutdownEvent.Publish
|
||||
|
||||
[<CLIEvent>]
|
||||
member __.Exit = exitEvent.Publish
|
||||
|
||||
[<CLIEvent>]
|
||||
member __.Cancel = cancelEvent.Publish
|
||||
|
||||
[<CLIEvent>]
|
||||
member __.ProjectInvalidated = projectInvalidatedEvent.Publish
|
||||
|
||||
member __.DoShutdown() = shutdownEvent.Trigger()
|
||||
|
||||
member __.DoExit() = exitEvent.Trigger()
|
||||
|
||||
member __.DoCancel() = cancelEvent.Trigger()
|
||||
|
||||
member __.InvalidateAllProjects() =
|
||||
for projectOptions in sourceFileToProjectMap.Values do
|
||||
projectInvalidatedEvent.Trigger(projectOptions)
|
||||
|
||||
member val Options = Options.Default() with get, set
|
||||
|
||||
member val JsonRpc: JsonRpc option = None with get, set
|
|
@ -1,75 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
|
||||
|
||||
namespace FSharp.Compiler.LanguageServer
|
||||
|
||||
open System.Threading
|
||||
|
||||
module TextDocument =
|
||||
|
||||
let mutable publishDiagnosticsCancellationTokenSource = new CancellationTokenSource()
|
||||
|
||||
let Hover (state: State) (textDocument: TextDocumentIdentifier) (position: Position) =
|
||||
async {
|
||||
eprintfn "hover at %d, %d" position.line position.character
|
||||
if not state.Options.usePreviewTextHover then return None
|
||||
else
|
||||
let startCol, endCol =
|
||||
if position.character = 0 then 0, 1
|
||||
else position.character, position.character + 1
|
||||
return Some { contents = { kind = MarkupKind.PlainText
|
||||
value = "serving textDocument/hover from LSP" }
|
||||
range = Some { start = { line = position.line; character = startCol }
|
||||
``end`` = { line = position.line; character = endCol } }
|
||||
}
|
||||
}
|
||||
|
||||
let PublishDiagnostics(state: State, projectOptions: FSharp.Compiler.SourceCodeServices.FSharpProjectOptions) =
|
||||
// TODO: honor TextDocumentClientCapabilities.publishDiagnostics.relatedInformation
|
||||
// cancel any existing request to publish diagnostics
|
||||
publishDiagnosticsCancellationTokenSource.Cancel()
|
||||
publishDiagnosticsCancellationTokenSource <- new CancellationTokenSource()
|
||||
async {
|
||||
if not state.Options.usePreviewDiagnostics then return ()
|
||||
else
|
||||
eprintfn "starting diagnostics computation"
|
||||
match state.JsonRpc with
|
||||
| None -> eprintfn "state.JsonRpc was null; should not be?"
|
||||
| Some jsonRpc ->
|
||||
let! results = state.Checker.ParseAndCheckProject projectOptions
|
||||
let diagnostics = results.Errors
|
||||
let diagnosticsPerFile =
|
||||
diagnostics
|
||||
|> Array.fold (fun state t ->
|
||||
let existing = Map.tryFind t.FileName state |> Option.defaultValue []
|
||||
Map.add t.FileName (t :: existing) state) Map.empty
|
||||
for sourceFile in projectOptions.SourceFiles do
|
||||
let diagnostics =
|
||||
Map.tryFind sourceFile diagnosticsPerFile
|
||||
|> Option.defaultValue []
|
||||
|> List.map (fun d ->
|
||||
// F# errors count lines starting at 1, but LSP starts at 0
|
||||
let range: Range =
|
||||
{ start = { line = d.StartLineAlternate - 1; character = d.StartColumn }
|
||||
``end`` = { line = d.EndLineAlternate - 1; character = d.EndColumn } }
|
||||
let severity =
|
||||
match d.Severity with
|
||||
| FSharp.Compiler.SourceCodeServices.FSharpErrorSeverity.Warning -> Diagnostic.Warning
|
||||
| FSharp.Compiler.SourceCodeServices.FSharpErrorSeverity.Error -> Diagnostic.Error
|
||||
let res: Diagnostic =
|
||||
{ range = range
|
||||
severity = Some severity
|
||||
code = "FS" + d.ErrorNumber.ToString("0000")
|
||||
source = Some d.FileName
|
||||
message = d.Message
|
||||
relatedInformation = None }
|
||||
res)
|
||||
|> List.toArray
|
||||
let args: PublishDiagnosticsParams =
|
||||
{ uri = System.Uri(sourceFile).AbsoluteUri
|
||||
diagnostics = diagnostics }
|
||||
|
||||
// fire each notification separately
|
||||
jsonRpc.NotifyAsync(TextDocumentPublishDiagnostics, args) |> Async.AwaitTask |> Async.Start
|
||||
}
|
||||
|> (fun computation -> Async.StartAsTask(computation, cancellationToken=publishDiagnosticsCancellationTokenSource.Token))
|
||||
|> Async.AwaitTask
|
|
@ -1,154 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
|
||||
|
||||
namespace FSharp.Compiler.LanguageServer.UnitTests
|
||||
|
||||
open System
|
||||
open System.IO
|
||||
open System.Linq
|
||||
open System.Threading.Tasks
|
||||
open FSharp.Compiler.LanguageServer
|
||||
open Nerdbank.Streams
|
||||
open NUnit.Framework
|
||||
|
||||
[<TestFixture>]
|
||||
type DiagnosticsTests() =
|
||||
|
||||
let createTestableProject (tfm: string) (sourceFiles: (string * string) list) =
|
||||
let testDir = new TemporaryDirectory()
|
||||
let directoryBuildText = "<Project />"
|
||||
File.WriteAllText(Path.Combine(testDir.Directory, "Directory.Build.props"), directoryBuildText)
|
||||
File.WriteAllText(Path.Combine(testDir.Directory, "Directory.Build.targets"), directoryBuildText)
|
||||
for name, contents in sourceFiles do
|
||||
File.WriteAllText(Path.Combine(testDir.Directory, name), contents)
|
||||
let compileItems =
|
||||
sourceFiles
|
||||
|> List.map fst
|
||||
|> List.map (sprintf " <Compile Include=\"%s\" />")
|
||||
|> List.fold (fun content line -> content + "\n" + line) ""
|
||||
let replacements =
|
||||
[ "{{COMPILE}}", compileItems
|
||||
"{{TARGETFRAMEWORK}}", tfm ]
|
||||
let projectTemplate =
|
||||
@"
|
||||
<Project Sdk=""Microsoft.NET.Sdk"">
|
||||
<PropertyGroup>
|
||||
<OutputType>Library</OutputType>
|
||||
<TargetFramework>{{TARGETFRAMEWORK}}</TargetFramework>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
{{COMPILE}}
|
||||
</ItemGroup>
|
||||
</Project>"
|
||||
let projectFile =
|
||||
replacements
|
||||
|> List.fold (fun (content: string) (find, replace) -> content.Replace(find, replace)) projectTemplate
|
||||
File.WriteAllText(Path.Combine(testDir.Directory, "test.fsproj"), projectFile)
|
||||
testDir
|
||||
|
||||
let createRpcClient (tempDir: TemporaryDirectory) =
|
||||
let clientStream, serverStream = FullDuplexStream.CreatePair().ToTuple()
|
||||
let server = new Server(serverStream, serverStream)
|
||||
server.StartListening()
|
||||
let client = new TestClient(tempDir, clientStream, clientStream, server)
|
||||
client
|
||||
|
||||
let createClientTest (tfm: string) (sourceFiles: (string * string) list) =
|
||||
let testDir = createTestableProject tfm sourceFiles
|
||||
let client = createRpcClient testDir
|
||||
client
|
||||
|
||||
let getDiagnostics (content: string) =
|
||||
async {
|
||||
use client = createClientTest "netstandard2.0" [ "lib.fs", content ]
|
||||
let! diagnostics = client.WaitForDiagnosticsAsync client.Initialize ["lib.fs"]
|
||||
return diagnostics.["lib.fs"]
|
||||
}
|
||||
|
||||
[<Test>]
|
||||
member __.``No diagnostics for correct code``() =
|
||||
async {
|
||||
let! diagnostics = getDiagnostics @"
|
||||
namespace Test
|
||||
|
||||
module Numbers =
|
||||
let one: int = 1
|
||||
"
|
||||
Assert.AreEqual(0, diagnostics.Length)
|
||||
} |> Async.StartAsTask :> Task
|
||||
|
||||
[<Test>]
|
||||
member __.``Diagnostics for incorrect code``() =
|
||||
async {
|
||||
let! diagnostics = getDiagnostics @"
|
||||
namespace Test
|
||||
|
||||
module Numbers =
|
||||
let one: int = false
|
||||
"
|
||||
let diag = diagnostics.Single()
|
||||
Assert.AreEqual("FS0001", diag.code)
|
||||
Assert.AreEqual(Some 1, diag.severity)
|
||||
Assert.AreEqual(4, diag.range.start.line)
|
||||
Assert.AreEqual(19, diag.range.start.character)
|
||||
Assert.AreEqual(4, diag.range.``end``.line)
|
||||
Assert.AreEqual(24, diag.range.``end``.character)
|
||||
Assert.AreEqual("This expression was expected to have type\n 'int' \nbut here has type\n 'bool'", diag.message.Trim())
|
||||
Assert.IsTrue(diag.source.Value.EndsWith("lib.fs"))
|
||||
} |> Async.StartAsTask :> Task
|
||||
|
||||
[<Test; Ignore("FileSystemWatcher isn't 100% reliable.")>]
|
||||
member __.``Diagnostics added for updated incorrect code``() =
|
||||
async {
|
||||
let correct = @"
|
||||
namespace Test
|
||||
|
||||
module Numbers =
|
||||
let one: int = 1
|
||||
"
|
||||
let incorrect = @"
|
||||
namespace Test
|
||||
|
||||
module Numbers =
|
||||
let one: int = false
|
||||
"
|
||||
|
||||
// verify initial state
|
||||
use client = createClientTest "netstandard2.0" [ "lib.fs", correct ]
|
||||
let! diagnostics = client.WaitForDiagnosticsAsync client.Initialize ["lib.fs"]
|
||||
Assert.AreEqual(0, diagnostics.["lib.fs"].Length)
|
||||
|
||||
// touch file with incorrect data
|
||||
let touch () = File.WriteAllText(Path.Combine(client.RootPath, "lib.fs"), incorrect)
|
||||
let! diagnostics = client.WaitForDiagnostics touch ["lib.fs"]
|
||||
let diag = diagnostics.["lib.fs"].Single()
|
||||
Assert.AreEqual("FS0001", diag.code)
|
||||
} |> Async.StartAsTask :> Task
|
||||
|
||||
[<Test; Ignore("FileSystemWatcher isn't 100% reliable.")>]
|
||||
member __.``Diagnostics removed for updated correct code``() =
|
||||
async {
|
||||
let incorrect = @"
|
||||
namespace Test
|
||||
|
||||
module Numbers =
|
||||
let one: int = false
|
||||
"
|
||||
let correct = @"
|
||||
namespace Test
|
||||
|
||||
module Numbers =
|
||||
let one: int = 1
|
||||
"
|
||||
|
||||
// verify initial state
|
||||
use client = createClientTest "netstandard2.0" [ "lib.fs", incorrect ]
|
||||
let! diagnostics = client.WaitForDiagnosticsAsync client.Initialize ["lib.fs"]
|
||||
let diag = diagnostics.["lib.fs"].Single()
|
||||
Assert.AreEqual("FS0001", diag.code)
|
||||
|
||||
// touch file with correct data
|
||||
let touch () = File.WriteAllText(Path.Combine(client.RootPath, "lib.fs"), correct)
|
||||
let! diagnostics = client.WaitForDiagnostics touch ["lib.fs"]
|
||||
let libActualContents = File.ReadAllText(Path.Combine(client.RootPath, "lib.fs"))
|
||||
Assert.AreEqual(0, diagnostics.["lib.fs"].Length, "Actual on-disk contents of lib.fs:\n" + libActualContents)
|
||||
} |> Async.StartAsTask :> Task
|
|
@ -1,9 +0,0 @@
|
|||
<Project>
|
||||
|
||||
<PropertyGroup>
|
||||
<UseFSharpProductVersion>true</UseFSharpProductVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<Import Project="$([MSBuild]::GetPathOfFileAbove('Directory.Build.props', '$(MSBuildThisFileDirectory)../'))" />
|
||||
|
||||
</Project>
|
|
@ -1,31 +0,0 @@
|
|||
<!-- Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -->
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net472;netcoreapp3.0</TargetFrameworks>
|
||||
<TargetFrameworks Condition="'$(OS)' == 'Unix'">netcoreapp3.0</TargetFrameworks>
|
||||
<OutputType>Library</OutputType>
|
||||
<DisableImplicitFSharpCoreReference>true</DisableImplicitFSharpCoreReference>
|
||||
<UnitTestType>nunit</UnitTestType>
|
||||
<ExcludeFromSourceBuild>true</ExcludeFromSourceBuild>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="TemporaryDirectory.fs" />
|
||||
<Compile Include="TestClient.fs" />
|
||||
<Compile Include="ProtocolTests.fs" />
|
||||
<Compile Include="SerializationTests.fs" />
|
||||
<Compile Include="DiagnosticsTests.fs" />
|
||||
<Compile Include="MiscTests.fs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="$(FSharpSourcesRoot)\fsharp\FSharp.Compiler.LanguageServer\FSharp.Compiler.LanguageServer.fsproj" />
|
||||
<ProjectReference Include="$(FSharpSourcesRoot)\fsharp\FSharp.Core\FSharp.Core.fsproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="StreamJsonRpc" Version="$(StreamJsonRpcVersion)" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -1,43 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
|
||||
|
||||
namespace FSharp.Compiler.LanguageServer.UnitTests
|
||||
|
||||
open System.IO
|
||||
open FSharp.Compiler.LanguageServer
|
||||
open NUnit.Framework
|
||||
|
||||
[<TestFixture>]
|
||||
type MiscTests() =
|
||||
|
||||
[<Test>]
|
||||
member __.``Find F# projects in a .sln file``() =
|
||||
let slnContent = @"
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.29201.188
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project(""{F2A71F9B-5D33-465A-A702-920D77279786}"") = ""ConsoleApp1"", ""ConsoleApp1\ConsoleApp1.fsproj"", ""{60A4BE67-7E03-4200-AD38-B0E5E8E049C1}""
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{60A4BE67-7E03-4200-AD38-B0E5E8E049C1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{60A4BE67-7E03-4200-AD38-B0E5E8E049C1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{60A4BE67-7E03-4200-AD38-B0E5E8E049C1}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{60A4BE67-7E03-4200-AD38-B0E5E8E049C1}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {80902CFC-54E6-4485-AC17-4516930C8B2B}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
"
|
||||
let testDir = @"C:\Dir\With\Solution" // don't care about the potentially improper directory separators here, it's really just a dumb string
|
||||
let foundProjects = Solution.getProjectPaths slnContent testDir
|
||||
let expected = Path.Combine(testDir, "ConsoleApp1", "ConsoleApp1.fsproj") // proper directory separator characters will be used at runtime
|
||||
Assert.AreEqual([| expected |], foundProjects)
|
|
@ -1,55 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
|
||||
|
||||
namespace FSharp.Compiler.LanguageServer.UnitTests
|
||||
|
||||
open System.Diagnostics
|
||||
open System.Threading.Tasks
|
||||
open FSharp.Compiler.LanguageServer
|
||||
open NUnit.Framework
|
||||
open StreamJsonRpc
|
||||
|
||||
[<TestFixture>]
|
||||
type ProtocolTests() =
|
||||
|
||||
#if !NETCOREAPP
|
||||
// The `netcoreapp` version of `FSharp.Compiler.LanguageServer.exe` can't be run without a `publish` step so
|
||||
// we're artificially restricting this test to the full framework.
|
||||
[<Test>]
|
||||
#endif
|
||||
member __.``Server consuming stdin and stdout``() =
|
||||
async {
|
||||
// start server as a console app
|
||||
let serverAssemblyPath = typeof<Server>.Assembly.Location
|
||||
let startInfo = ProcessStartInfo(serverAssemblyPath)
|
||||
startInfo.UseShellExecute <- false
|
||||
startInfo.RedirectStandardInput <- true
|
||||
startInfo.RedirectStandardOutput <- true
|
||||
let proc = Process.Start(startInfo)
|
||||
|
||||
// create a fake client over stdin/stdout
|
||||
let client = new JsonRpc(proc.StandardInput.BaseStream, proc.StandardOutput.BaseStream)
|
||||
client.StartListening()
|
||||
|
||||
// initialize
|
||||
let capabilities: ClientCapabilities =
|
||||
{ workspace = None
|
||||
textDocument = None
|
||||
experimental = None
|
||||
supportsVisualStudioExtensions = None }
|
||||
let! result =
|
||||
client.InvokeWithParameterObjectAsync<InitializeResult>(
|
||||
"initialize",
|
||||
{| processId = Process.GetCurrentProcess().Id
|
||||
capabilities = capabilities |}
|
||||
) |> Async.AwaitTask
|
||||
Assert.True(result.capabilities.hoverProvider)
|
||||
do! client.NotifyAsync("initialized") |> Async.AwaitTask
|
||||
|
||||
// shutdown
|
||||
let! shutdownResponse = client.InvokeAsync<obj>("shutdown") |> Async.AwaitTask
|
||||
Assert.IsNull(shutdownResponse)
|
||||
|
||||
// exit
|
||||
do! client.NotifyAsync("exit") |> Async.AwaitTask
|
||||
if not (proc.WaitForExit(5000)) then failwith "Expected server process to exit."
|
||||
} |> Async.StartAsTask :> Task
|
|
@ -1,33 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
|
||||
|
||||
namespace FSharp.Compiler.LanguageServer.UnitTests
|
||||
|
||||
open System
|
||||
open FSharp.Compiler.LanguageServer
|
||||
open NUnit.Framework
|
||||
open Newtonsoft.Json
|
||||
|
||||
[<TestFixture>]
|
||||
type SerializationTests() =
|
||||
|
||||
let verifyRoundTrip (str: string) (typ: Type) =
|
||||
let deserialized = JsonConvert.DeserializeObject(str, typ)
|
||||
let roundTripped = JsonConvert.SerializeObject(deserialized)
|
||||
Assert.AreEqual(str, roundTripped)
|
||||
|
||||
let verifyRoundTripWithConverter (str: string) (typ: Type) (converter: JsonConverter) =
|
||||
let deserialized = JsonConvert.DeserializeObject(str, typ, converter)
|
||||
let roundTripped = JsonConvert.SerializeObject(deserialized, converter)
|
||||
Assert.AreEqual(str, roundTripped)
|
||||
|
||||
[<Test>]
|
||||
member __.``Discriminated union as lower-case string``() =
|
||||
verifyRoundTrip "\"plaintext\"" typeof<MarkupKind>
|
||||
verifyRoundTrip "\"markdown\"" typeof<MarkupKind>
|
||||
|
||||
[<Test>]
|
||||
member __.``Option<'T> as obj/null``() =
|
||||
verifyRoundTripWithConverter "1" typeof<option<int>> (JsonOptionConverter())
|
||||
verifyRoundTripWithConverter "null" typeof<option<int>> (JsonOptionConverter())
|
||||
verifyRoundTripWithConverter "{\"contents\":{\"kind\":\"plaintext\",\"value\":\"v\"},\"range\":{\"start\":{\"line\":1,\"character\":2},\"end\":{\"line\":3,\"character\":4}}}" typeof<option<Hover>> (JsonOptionConverter())
|
||||
verifyRoundTripWithConverter "null" typeof<option<Hover>> (JsonOptionConverter())
|
|
@ -1,20 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
|
||||
|
||||
namespace FSharp.Compiler.LanguageServer.UnitTests
|
||||
|
||||
open System
|
||||
open System.IO
|
||||
|
||||
type TemporaryDirectory() =
|
||||
|
||||
let directory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString())
|
||||
do Directory.CreateDirectory(directory) |> ignore
|
||||
|
||||
member __.Directory = directory
|
||||
|
||||
interface IDisposable with
|
||||
member __.Dispose() =
|
||||
try
|
||||
Directory.Delete(directory, true)
|
||||
with
|
||||
| _ -> ()
|
|
@ -1,121 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
|
||||
|
||||
namespace FSharp.Compiler.LanguageServer.UnitTests
|
||||
|
||||
open System
|
||||
open System.Collections.Generic
|
||||
open System.Diagnostics
|
||||
open System.IO
|
||||
open System.Threading
|
||||
open FSharp.Compiler.LanguageServer
|
||||
open Newtonsoft.Json.Linq
|
||||
open StreamJsonRpc
|
||||
|
||||
type TestClient(tempDir: TemporaryDirectory, sendingStream: Stream, receivingStream: Stream, server: Server) =
|
||||
|
||||
let rootPath = tempDir.Directory
|
||||
let rootPath = if rootPath.EndsWith(Path.DirectorySeparatorChar.ToString()) then rootPath else rootPath + Path.DirectorySeparatorChar.ToString()
|
||||
let diagnosticsEvent = Event<_>()
|
||||
|
||||
let formatter = JsonMessageFormatter()
|
||||
let converter = JsonOptionConverter() // special handler to convert between `Option<'T>` and `obj/null`.
|
||||
do formatter.JsonSerializer.Converters.Add(converter)
|
||||
let handler = new HeaderDelimitedMessageHandler(sendingStream, receivingStream, formatter)
|
||||
let client = new JsonRpc(handler)
|
||||
let handler (functionName: string) (args: JToken): JToken =
|
||||
match functionName with
|
||||
| TextDocumentPublishDiagnostics ->
|
||||
let args = args.ToObject<PublishDiagnosticsParams>(formatter.JsonSerializer)
|
||||
let fullPath = Uri(args.uri).LocalPath
|
||||
let shortPath = if fullPath.StartsWith(rootPath) then fullPath.Substring(rootPath.Length) else fullPath
|
||||
diagnosticsEvent.Trigger((shortPath, args.diagnostics))
|
||||
null
|
||||
| _ -> null
|
||||
let addHandler (name: string) =
|
||||
client.AddLocalRpcMethod(name, new Func<JToken, JToken>(handler name))
|
||||
do addHandler TextDocumentPublishDiagnostics
|
||||
do client.StartListening()
|
||||
|
||||
member __.RootPath = rootPath
|
||||
|
||||
member __.Server = server
|
||||
|
||||
[<CLIEvent>]
|
||||
member __.PublishDiagnostics = diagnosticsEvent.Publish
|
||||
|
||||
member __.Initialize () =
|
||||
async {
|
||||
do! client.NotifyWithParameterObjectAsync(OptionsSet, {| options = Options.AllOn() |}) |> Async.AwaitTask
|
||||
let capabilities: ClientCapabilities =
|
||||
{ workspace = None
|
||||
textDocument = None
|
||||
experimental = None
|
||||
supportsVisualStudioExtensions = None }
|
||||
let! _result =
|
||||
client.InvokeWithParameterObjectAsync<InitializeResult>(
|
||||
"initialize", // method
|
||||
{| processId = Process.GetCurrentProcess().Id
|
||||
rootPath = rootPath
|
||||
capabilities = capabilities |}
|
||||
) |> Async.AwaitTask
|
||||
return ()
|
||||
}
|
||||
|
||||
member this.WaitForDiagnostics (triggerAction: unit -> unit) (fileNames: string list) =
|
||||
async {
|
||||
// prepare file diagnostic triggers
|
||||
let diagnosticTriggers = Dictionary<string, ManualResetEvent>()
|
||||
fileNames |> List.iter (fun f -> diagnosticTriggers.[f] <- new ManualResetEvent(false))
|
||||
|
||||
// prepare callback handler
|
||||
let diagnosticsMap = Dictionary<string, Diagnostic[]>()
|
||||
let handler (fileName: string, diagnostics: Diagnostic[]) =
|
||||
diagnosticsMap.[fileName] <- diagnostics
|
||||
// auto-generated files (e.g., AssemblyInfo.fs) won't be in the trigger map
|
||||
if diagnosticTriggers.ContainsKey(fileName) then
|
||||
diagnosticTriggers.[fileName].Set() |> ignore
|
||||
|
||||
// subscribe to the event
|
||||
let wrappedHandler = new Handler<string * Diagnostic[]>(fun _sender args -> handler args)
|
||||
this.PublishDiagnostics.AddHandler(wrappedHandler)
|
||||
triggerAction ()
|
||||
|
||||
// wait for all triggers to hit
|
||||
let! results =
|
||||
diagnosticTriggers
|
||||
|> Seq.map (fun entry ->
|
||||
async {
|
||||
let! result = Async.AwaitWaitHandle(entry.Value, millisecondsTimeout = int (TimeSpan.FromSeconds(10.0).TotalMilliseconds))
|
||||
return if result then None
|
||||
else
|
||||
let filePath = Path.Combine(rootPath, entry.Key)
|
||||
let actualContents = File.ReadAllText(filePath)
|
||||
Some <| sprintf "No diagnostics received for file '%s'. Contents:\n%s\n" entry.Key actualContents
|
||||
})
|
||||
|> Async.Parallel
|
||||
let results = results |> Array.choose (fun x -> x)
|
||||
if results.Length > 0 then
|
||||
let combinedErrors = String.Join("-----\n", results)
|
||||
let allDiagnosticsEvents =
|
||||
diagnosticsMap
|
||||
|> Seq.map (fun entry ->
|
||||
sprintf "File '%s' reported %d diagnostics." entry.Key entry.Value.Length)
|
||||
|> (fun s -> String.Join("\n", s))
|
||||
failwith <| sprintf "Error waiting for diagnostics:\n%s\n-----\n%s" combinedErrors allDiagnosticsEvents
|
||||
|
||||
// clean up event
|
||||
this.PublishDiagnostics.RemoveHandler(wrappedHandler)
|
||||
|
||||
// done
|
||||
return diagnosticsMap
|
||||
}
|
||||
|
||||
member this.WaitForDiagnosticsAsync (triggerAction: unit -> Async<unit>) (fileNames: string list) =
|
||||
this.WaitForDiagnostics (fun () -> triggerAction () |> Async.RunSynchronously) fileNames
|
||||
|
||||
interface IDisposable with
|
||||
member __.Dispose() =
|
||||
try
|
||||
(tempDir :> IDisposable).Dispose()
|
||||
with
|
||||
| _ -> ()
|
|
@ -28,10 +28,6 @@
|
|||
<Action Type="Ngen" Path="FSharp.ProjectSystem.FSharp.dll" />
|
||||
<Action Type="Ngen" Path="FSharp.ProjectSystem.PropertyPages.dll" />
|
||||
<Action Type="Ngen" Path="FSharp.VS.FSI.dll" />
|
||||
<!-- this Ngen action should be disabled in branch `release/dev16.2`, enabled otherwise -->
|
||||
<!--
|
||||
<Action Type="Ngen" Path="Agent\FSharp.Compiler.LanguageServer.exe" />
|
||||
-->
|
||||
</Actions>
|
||||
</Installer>
|
||||
<Dependencies>
|
||||
|
|
|
@ -61,14 +61,6 @@
|
|||
<Private>True</Private>
|
||||
<AdditionalProperties>TargetFramework=$(DependencyTargetFramework)</AdditionalProperties>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="$(FSharpSourcesRoot)\fsharp\FSharp.Compiler.LanguageServer\FSharp.Compiler.LanguageServer.fsproj" Condition="'$(IncludeVsLanguageServer)' == 'true'" >
|
||||
<Project>{60BAFFA5-6631-4328-B044-2E012AB76DCA}</Project>
|
||||
<Name>FSharp.Compiler.LanguageServer</Name>
|
||||
<IncludeOutputGroupsInVSIX>PublishedProjectOutputGroup%3b</IncludeOutputGroupsInVSIX>
|
||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||
<Targets>Build;Publish</Targets>
|
||||
<AdditionalProperties>TargetFramework=$(DependencyTargetFramework)</AdditionalProperties>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="$(FSharpSourcesRoot)\fsharp\FSharp.Compiler.Server.Shared\FSharp.Compiler.Server.Shared.fsproj">
|
||||
<Project>{D5870CF0-ED51-4CBC-B3D7-6F56DA84AC06}</Project>
|
||||
<Name>FSharp.Compiler.Server.Shared</Name>
|
||||
|
@ -158,16 +150,6 @@
|
|||
<NgenPriority>2</NgenPriority>
|
||||
<Private>True</Private>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="$(FSharpSourcesRoot)\..\vsintegration\src\FSharp.Editor.Helpers\FSharp.Editor.Helpers.csproj">
|
||||
<Project>{0A3099F1-F0C7-4ADE-AB9B-526EF193A56F}</Project>
|
||||
<Name>FSharp.Editor.Helpers</Name>
|
||||
<IncludeOutputGroupsInVSIX>BuiltProjectOutputGroup%3bGetCopyToOutputDirectoryItems%3bPkgDefProjectOutputGroup%3bSatelliteDllsProjectOutputGroup%3b</IncludeOutputGroupsInVSIX>
|
||||
<IncludeOutputGroupsInVSIXLocalOnly>DebugSymbolsProjectOutputGroup%3b</IncludeOutputGroupsInVSIXLocalOnly>
|
||||
<Ngen>true</Ngen>
|
||||
<NgenArchitecture>All</NgenArchitecture>
|
||||
<NgenPriority>2</NgenPriority>
|
||||
<Private>True</Private>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="$(FSharpSourcesRoot)\..\vsintegration\src\FSharp.UIResources\FSharp.UIResources.csproj">
|
||||
<Project>{c4586a06-1402-48bc-8e35-a1b8642f895b}</Project>
|
||||
<Name>FSharp.UIResources</Name>
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Library</OutputType>
|
||||
<TargetFramework>net472</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.VisualStudio.LanguageServer.Client" Version="$(MicrosoftVisualStudioLanguageServerClientVersion)" PrivateAssets="all" ExcludeAssets="runtime;contentFiles;build;analyzers;native" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Shell.15.0" Version="$(MicrosoftVisualStudioShell150Version)" PrivateAssets="all" ExcludeAssets="runtime;contentFiles;build;analyzers;native" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Threading" Version="$(MicrosoftVisualStudioThreadingVersion)" PrivateAssets="all" ExcludeAssets="runtime;contentFiles;build;analyzers;native" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<AssemblyAttribute Include="Microsoft.VisualStudio.Shell.ProvideCodeBaseAttribute">
|
||||
<AssemblyName>FSharp.Editor.Helpers</AssemblyName>
|
||||
<Version>$(VSAssemblyVersion)</Version>
|
||||
<CodeBase>$PackageFolder$\FSharp.Editor.Helpers.dll</CodeBase>
|
||||
</AssemblyAttribute>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -1,46 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.VisualStudio.LanguageServer.Client;
|
||||
using Microsoft.VisualStudio.Threading;
|
||||
|
||||
namespace Microsoft.VisualStudio.FSharp.Editor.Helpers
|
||||
{
|
||||
/// <summary>
|
||||
/// Exists as an abstract implementor of <see cref="ILanguageClient" /> purely to manage the non-standard async
|
||||
/// event handlers.
|
||||
/// </summary>
|
||||
public abstract class LanguageClient : ILanguageClient
|
||||
{
|
||||
public abstract string Name { get; }
|
||||
|
||||
public abstract IEnumerable<string> ConfigurationSections { get; }
|
||||
|
||||
public abstract object InitializationOptions { get; }
|
||||
|
||||
public abstract IEnumerable<string> FilesToWatch { get; }
|
||||
|
||||
public event AsyncEventHandler<EventArgs> StartAsync;
|
||||
|
||||
#pragma warning disable 67 // The event 'LanguageClient.StopAsync' is never used
|
||||
public event AsyncEventHandler<EventArgs> StopAsync;
|
||||
#pragma warning restore 67
|
||||
|
||||
public abstract Task<Connection> ActivateAsync(CancellationToken token);
|
||||
|
||||
protected abstract Task DoLoadAsync();
|
||||
|
||||
public async Task OnLoadedAsync()
|
||||
{
|
||||
await DoLoadAsync();
|
||||
await StartAsync.InvokeAsync(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
public abstract Task OnServerInitializeFailedAsync(Exception e);
|
||||
|
||||
public abstract Task OnServerInitializedAsync();
|
||||
}
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
|
||||
|
||||
namespace Microsoft.VisualStudio.FSharp.Editor
|
||||
|
||||
open System.ComponentModel.Composition
|
||||
open FSharp.Compiler.LanguageServer
|
||||
open FSharp.Compiler.LanguageServer.Extensions
|
||||
open StreamJsonRpc
|
||||
|
||||
[<Export(typeof<LspService>)>]
|
||||
type LspService() =
|
||||
let mutable options = Options.Default()
|
||||
let mutable jsonRpc: JsonRpc option = None
|
||||
|
||||
let sendOptions () =
|
||||
async {
|
||||
match jsonRpc with
|
||||
| None -> ()
|
||||
| Some rpc -> do! rpc.SetOptionsAsync(options)
|
||||
}
|
||||
|
||||
member __.SetJsonRpc(rpc: JsonRpc) =
|
||||
jsonRpc <- Some rpc
|
||||
sendOptions()
|
||||
|
||||
member __.SetOptions(opt: Options) =
|
||||
options <- opt
|
||||
sendOptions()
|
|
@ -34,9 +34,6 @@ type internal FSharpDocumentDiagnosticAnalyzer [<ImportingConstructor>] () =
|
|||
let getProjectInfoManager(document: Document) =
|
||||
document.Project.Solution.Workspace.Services.GetService<FSharpCheckerWorkspaceService>().FSharpProjectOptionsManager
|
||||
|
||||
let getSettings(document: Document) =
|
||||
document.Project.Solution.Workspace.Services.GetService<EditorOptions>()
|
||||
|
||||
static let errorInfoEqualityComparer =
|
||||
{ new IEqualityComparer<FSharpErrorInfo> with
|
||||
member __.Equals (x, y) =
|
||||
|
@ -123,10 +120,6 @@ type internal FSharpDocumentDiagnosticAnalyzer [<ImportingConstructor>] () =
|
|||
interface IFSharpDocumentDiagnosticAnalyzer with
|
||||
|
||||
member this.AnalyzeSyntaxAsync(document: Document, cancellationToken: CancellationToken): Task<ImmutableArray<Diagnostic>> =
|
||||
// if using LSP, just bail early
|
||||
let settings = getSettings document
|
||||
if settings.Advanced.UsePreviewDiagnostics then Task.FromResult(ImmutableArray<Diagnostic>.Empty)
|
||||
else
|
||||
let projectInfoManager = getProjectInfoManager document
|
||||
asyncMaybe {
|
||||
let! parsingOptions, projectOptions = projectInfoManager.TryGetOptionsForEditingDocumentOrProject(document, cancellationToken)
|
||||
|
@ -140,10 +133,6 @@ type internal FSharpDocumentDiagnosticAnalyzer [<ImportingConstructor>] () =
|
|||
|> RoslynHelpers.StartAsyncAsTask cancellationToken
|
||||
|
||||
member this.AnalyzeSemanticsAsync(document: Document, cancellationToken: CancellationToken): Task<ImmutableArray<Diagnostic>> =
|
||||
// if using LSP, just bail early
|
||||
let settings = getSettings document
|
||||
if settings.Advanced.UsePreviewDiagnostics then Task.FromResult(ImmutableArray<Diagnostic>.Empty)
|
||||
else
|
||||
let projectInfoManager = getProjectInfoManager document
|
||||
asyncMaybe {
|
||||
let! parsingOptions, _, projectOptions = projectInfoManager.TryGetOptionsForDocumentOrProject(document, cancellationToken)
|
||||
|
|
|
@ -98,6 +98,7 @@
|
|||
<Compile Include="Common\CompilerService.fs" />
|
||||
<Compile Include="Common\FSharpProject.fs" />
|
||||
<Compile Include="Common\LanguageService.fs" />
|
||||
<Compile Include="Common\Vs.fs" />
|
||||
<Compile Include="Options\SettingsPersistence.fs" />
|
||||
<None Include="Options\UIHelpers.fs" />
|
||||
<None Include="Options\EditorOptions.fs" />
|
||||
|
@ -274,6 +275,77 @@
|
|||
<Compile Include="VSMac\FSharpProjectFileNodeExtension.fs" />
|
||||
<Compile Include="VSMac\FSharpSymbolHelper.fs" />
|
||||
<Compile Include="VSMac\GlobalSearch.fs" />
|
||||
<Compile Include="CodeLens\AbstractCodeLensDisplayService.fs" />
|
||||
<Compile Include="CodeLens\CodeLensGeneralTagger.fs" />
|
||||
<Compile Include="CodeLens\LineLensDisplayService.fs" />
|
||||
<Compile Include="CodeLens\FSharpCodeLensService.fs" />
|
||||
<Compile Include="CodeLens\CodeLensProvider.fs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="$(FSharpSourcesRoot)\fsharp\FSharp.Core\FSharp.Core.fsproj" />
|
||||
<ProjectReference Include="$(FSharpSourcesRoot)\fsharp\FSharp.Compiler.Private\FSharp.Compiler.Private.fsproj" />
|
||||
<ProjectReference Include="..\FSharp.PatternMatcher\FSharp.PatternMatcher.csproj" />
|
||||
<ProjectReference Include="..\FSharp.UIResources\FSharp.UIResources.csproj" />
|
||||
<ProjectReference Include="..\FSharp.VS.FSI\FSharp.VS.FSI.fsproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="PresentationCore" />
|
||||
<Reference Include="PresentationFramework" />
|
||||
<Reference Include="System.Runtime.Caching" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xaml" />
|
||||
<Reference Include="WindowsBase" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="EnvDTE80" Version="$(EnvDTE80Version)" PrivateAssets="all" ExcludeAssets="runtime;contentFiles;build;analyzers;native" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.EditorFeatures" Version="$(MicrosoftCodeAnalysisEditorFeaturesVersion)" PrivateAssets="all" ExcludeAssets="runtime;contentFiles;build;analyzers;native" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.EditorFeatures.Text" Version="$(MicrosoftCodeAnalysisEditorFeaturesTextVersion)" PrivateAssets="all" ExcludeAssets="runtime;contentFiles;build;analyzers;native" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.EditorFeatures.Wpf" Version="$(MicrosoftCodeAnalysisEditorFeaturesWpfVersion)" PrivateAssets="all" ExcludeAssets="runtime;contentFiles;build;analyzers;native" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.ExternalAccess.FSharp" Version="$(MicrosoftCodeAnalysisExternalAccessFSharpVersion)" PrivateAssets="all" ExcludeAssets="runtime;contentFiles;build;analyzers;native" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.Workspaces.Common" Version="$(MicrosoftCodeAnalysisWorkspacesCommonVersion)" PrivateAssets="all" ExcludeAssets="runtime;contentFiles;build;analyzers;native" />
|
||||
<PackageReference Include="Microsoft.Composition" Version="$(MicrosoftCompositionVersion)" PrivateAssets="all" ExcludeAssets="runtime;contentFiles;build;analyzers;native" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.ComponentModelHost" Version="$(MicrosoftVisualStudioComponentModelHostVersion)" PrivateAssets="all" ExcludeAssets="runtime;contentFiles;build;analyzers;native" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Editor" Version="$(MicrosoftVisualStudioEditorVersion)" PrivateAssets="all" ExcludeAssets="runtime;contentFiles;build;analyzers;native" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Language" Version="$(MicrosoftVisualStudioLanguageVersion)" PrivateAssets="all" ExcludeAssets="runtime;contentFiles;build;analyzers;native" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Language.Intellisense" Version="$(MicrosoftVisualStudioLanguageIntellisenseVersion)" PrivateAssets="all" ExcludeAssets="runtime;contentFiles;build;analyzers;native" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Language.StandardClassification" Version="$(MicrosoftVisualStudioLanguageStandardClassificationVersion)" PrivateAssets="all" ExcludeAssets="runtime;contentFiles;build;analyzers;native" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.LanguageServices" Version="$(MicrosoftVisualStudioLanguageServicesVersion)" PrivateAssets="all" ExcludeAssets="runtime;contentFiles;build;analyzers;native" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Package.LanguageService.15.0" Version="$(MicrosoftVisualStudioPackageLanguageService150Version)" PrivateAssets="all" ExcludeAssets="runtime;contentFiles;build;analyzers;native" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.ProjectAggregator" Version="$(MicrosoftVisualStudioProjectAggregatorVersion)" PrivateAssets="all" ExcludeAssets="runtime;contentFiles;build;analyzers;native" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.ProjectSystem" Version="$(MicrosoftVisualStudioProjectSystemVersion)" PrivateAssets="all" ExcludeAssets="runtime;contentFiles;build;analyzers;native" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.ProjectSystem.Managed" Version="$(MicrosoftVisualStudioProjectSystemManagedVersion)" PrivateAssets="all" ExcludeAssets="runtime;contentFiles;build;analyzers;native" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Shell.15.0" Version="$(MicrosoftVisualStudioShell150Version)" PrivateAssets="all" ExcludeAssets="runtime;contentFiles;build;analyzers;native" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Shell.Design" Version="$(MicrosoftVisualStudioShellDesignVersion)" PrivateAssets="all" ExcludeAssets="runtime;contentFiles;build;analyzers;native" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Shell.Immutable.10.0" Version="$(MicrosoftVisualStudioShellImmutable100Version)" PrivateAssets="all" ExcludeAssets="runtime;contentFiles;build;analyzers;native" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Shell.Immutable.11.0" Version="$(MicrosoftVisualStudioShellImmutable110Version)" PrivateAssets="all" ExcludeAssets="runtime;contentFiles;build;analyzers;native" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Shell.Interop.11.0" Version="$(MicrosoftVisualStudioShellInterop110Version)" PrivateAssets="all" ExcludeAssets="runtime;contentFiles;build;analyzers;native" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Shell.Interop.12.0" Version="$(MicrosoftVisualStudioShellInterop120Version)" PrivateAssets="all" ExcludeAssets="runtime;contentFiles;build;analyzers;native" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Text.UI" Version="$(MicrosoftVisualStudioTextUIVersion)" PrivateAssets="all" ExcludeAssets="runtime;contentFiles;build;analyzers;native" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Text.UI.Wpf" Version="$(MicrosoftVisualStudioTextUIWpfVersion)" PrivateAssets="all" ExcludeAssets="runtime;contentFiles;build;analyzers;native" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.TextManager.Interop" Version="$(MicrosoftVisualStudioTextManagerInteropVersion)" PrivateAssets="all" ExcludeAssets="runtime;contentFiles;build;analyzers;native" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.TextManager.Interop.12.0" Version="$(MicrosoftVisualStudioTextManagerInterop120Version)" PrivateAssets="all" ExcludeAssets="runtime;contentFiles;build;analyzers;native" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Threading" Version="$(MicrosoftVisualStudioThreadingVersion)" PrivateAssets="all" ExcludeAssets="runtime;contentFiles;build;analyzers;native" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="$(NewtonsoftJsonVersion)" PrivateAssets="all" ExcludeAssets="runtime;contentFiles;build;analyzers;native" />
|
||||
<PackageReference Include="System.Design" Version="$(SystemDesignVersion)" />
|
||||
<PackageReference Include="System.ValueTuple" Version="$(SystemValueTupleVersion)" />
|
||||
<PackageReference Include="VSSDK.VSLangProj" Version="$(VSSDKVSLangProjVersion)" PrivateAssets="all" ExcludeAssets="runtime;contentFiles;build;analyzers;native" />
|
||||
<PackageReference Include="StreamJsonRpc" Version="$(StreamJsonRpcVersion)" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<AssemblyAttribute Include="Microsoft.VisualStudio.Shell.ProvideCodeBaseAttribute">
|
||||
<AssemblyName>FSharp.Editor</AssemblyName>
|
||||
<Version>$(VSAssemblyVersion)</Version>
|
||||
<CodeBase>$PackageFolder$\FSharp.Editor.dll</CodeBase>
|
||||
</AssemblyAttribute>
|
||||
<AssemblyAttribute Include="Microsoft.VisualStudio.Shell.ProvideCodeBaseAttribute">
|
||||
<AssemblyName>FSharp.UIResources</AssemblyName>
|
||||
<Version>$(VSAssemblyVersion)</Version>
|
||||
<CodeBase>$PackageFolder$\FSharp.UIResources.dll</CodeBase>
|
||||
</AssemblyAttribute>
|
||||
</ItemGroup>
|
||||
<ProjectExtensions>
|
||||
<MonoDevelop>
|
||||
|
|
|
@ -1,70 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
|
||||
|
||||
namespace Microsoft.VisualStudio.FSharp.Editor.LanguageService
|
||||
|
||||
open System.ComponentModel.Composition
|
||||
open System.Diagnostics
|
||||
open System.IO
|
||||
open System.Threading
|
||||
open System.Threading.Tasks
|
||||
open Microsoft.FSharp.Control
|
||||
open Microsoft.VisualStudio.FSharp.Editor
|
||||
open Microsoft.VisualStudio.FSharp.Editor.Helpers
|
||||
open Microsoft.VisualStudio.LanguageServer.Client
|
||||
open Microsoft.VisualStudio.Utilities
|
||||
open StreamJsonRpc
|
||||
|
||||
// https://docs.microsoft.com/en-us/visualstudio/extensibility/adding-an-lsp-extension?view=vs-2019
|
||||
|
||||
/// Provides exports necessary to register the language client.
|
||||
type FSharpContentDefinition() =
|
||||
|
||||
[<Export>]
|
||||
[<Name(FSharpConstants.FSharpLanguageName)>]
|
||||
[<BaseDefinition(CodeRemoteContentDefinition.CodeRemoteContentTypeName)>]
|
||||
static member val FSharpContentTypeDefinition: ContentTypeDefinition = null with get, set
|
||||
|
||||
[<Export>]
|
||||
[<FileExtension(FSharpConstants.FSharpFileExtension)>]
|
||||
[<ContentType(FSharpConstants.FSharpLanguageName)>]
|
||||
static member val FSharpFileExtensionDefinition: FileExtensionToContentTypeDefinition = null with get, set
|
||||
|
||||
[<Export(typeof<ILanguageClient>)>]
|
||||
[<ContentType(FSharpConstants.FSharpLanguageName)>]
|
||||
type internal FSharpLanguageClient
|
||||
[<ImportingConstructor>]
|
||||
(
|
||||
lspService: LspService,
|
||||
settings: EditorOptions
|
||||
) =
|
||||
inherit LanguageClient()
|
||||
override __.Name = "F# Language Service"
|
||||
override this.ActivateAsync(_token: CancellationToken) =
|
||||
async {
|
||||
let thisAssemblyPath = Path.GetDirectoryName(this.GetType().Assembly.Location)
|
||||
let serverAssemblyPath = Path.Combine(thisAssemblyPath, "Agent", "FSharp.Compiler.LanguageServer.exe")
|
||||
let startInfo = ProcessStartInfo(serverAssemblyPath)
|
||||
startInfo.UseShellExecute <- false
|
||||
startInfo.CreateNoWindow <- true // comment to see log messages written to stderr
|
||||
startInfo.RedirectStandardInput <- true
|
||||
startInfo.RedirectStandardOutput <- true
|
||||
let proc = new Process()
|
||||
proc.StartInfo <- startInfo
|
||||
return
|
||||
if proc.Start() then new Connection(proc.StandardOutput.BaseStream, proc.StandardInput.BaseStream)
|
||||
else null
|
||||
} |> Async.StartAsTask
|
||||
override __.ConfigurationSections = null
|
||||
override __.FilesToWatch = null
|
||||
override __.InitializationOptions = null
|
||||
override __.DoLoadAsync() = Task.CompletedTask
|
||||
override __.OnServerInitializeFailedAsync(_e: exn) = Task.CompletedTask
|
||||
override __.OnServerInitializedAsync() = Task.CompletedTask
|
||||
interface ILanguageClientCustomMessage with
|
||||
member __.CustomMessageTarget = null
|
||||
member __.MiddleLayer = null
|
||||
member __.AttachForCustomMessageAsync(rpc: JsonRpc) =
|
||||
async {
|
||||
do! lspService.SetJsonRpc(rpc)
|
||||
do! lspService.SetOptions(settings.Advanced.AsLspOptions())
|
||||
} |> Async.StartAsTask :> Task
|
|
@ -5,7 +5,6 @@ open System.ComponentModel.Composition
|
|||
open System.Runtime.InteropServices
|
||||
open System.Windows
|
||||
open System.Windows.Controls
|
||||
open FSharp.Compiler.LanguageServer
|
||||
open Microsoft.VisualStudio.Shell
|
||||
open Microsoft.VisualStudio.FSharp.UIResources
|
||||
|
||||
|
@ -92,17 +91,10 @@ type CodeLensOptions =
|
|||
[<CLIMutable>]
|
||||
type AdvancedOptions =
|
||||
{ IsBlockStructureEnabled: bool
|
||||
IsOutliningEnabled: bool
|
||||
UsePreviewTextHover: bool
|
||||
UsePreviewDiagnostics: bool }
|
||||
IsOutliningEnabled: bool }
|
||||
static member Default =
|
||||
{ IsBlockStructureEnabled = true
|
||||
IsOutliningEnabled = true
|
||||
UsePreviewTextHover = false
|
||||
UsePreviewDiagnostics = false }
|
||||
member this.AsLspOptions(): Options =
|
||||
{ usePreviewTextHover = this.UsePreviewTextHover
|
||||
usePreviewDiagnostics = this.UsePreviewDiagnostics }
|
||||
IsOutliningEnabled = true }
|
||||
|
||||
[<CLIMutable>]
|
||||
type FormattingOptions =
|
||||
|
@ -203,14 +195,6 @@ module internal OptionsUI =
|
|||
inherit AbstractOptionPage<AdvancedOptions>()
|
||||
override __.CreateView() =
|
||||
upcast AdvancedOptionsControl()
|
||||
override this.OnApply(args) =
|
||||
base.OnApply(args)
|
||||
async {
|
||||
let lspService = this.GetService<LspService>()
|
||||
let settings = this.GetService<EditorOptions>()
|
||||
let options = settings.Advanced.AsLspOptions()
|
||||
do! lspService.SetOptions options
|
||||
} |> Async.Start
|
||||
|
||||
[<Guid(Guids.formattingOptionPageIdString)>]
|
||||
type internal FormattingOptionPage() =
|
||||
|
|
|
@ -203,10 +203,6 @@ type internal FSharpAsyncQuickInfoSource
|
|||
// This method can be called from the background thread.
|
||||
// Do not call IServiceProvider.GetService here.
|
||||
override __.GetQuickInfoItemAsync(session:IAsyncQuickInfoSession, cancellationToken:CancellationToken) : Task<QuickInfoItem> =
|
||||
// The following lines should be disabled for branch `release/dev16.2`, enabled otherwise
|
||||
//// if using LSP, just bail early
|
||||
//if settings.Advanced.UsePreviewTextHover then Task.FromResult<QuickInfoItem>(null)
|
||||
//else
|
||||
let triggerPoint = session.GetTriggerPoint(textBuffer.CurrentSnapshot)
|
||||
match triggerPoint.HasValue with
|
||||
| false -> Task.FromResult<QuickInfoItem>(null)
|
||||
|
|
|
@ -1828,8 +1828,9 @@ CONSIDER: get this from CodeDom</note>
|
|||
</trans-unit>
|
||||
<trans-unit id="RSE_GraphicSizeFormat">
|
||||
<source>{0} x {1}</source>
|
||||
<target state="translated">{0} x {1}</target>
|
||||
<target state="needs-review-translation">{0} x {1}</target>
|
||||
<note>Format string for showing a graphic's size
|
||||
|
||||
# {0} = width (as an integer)
|
||||
# {1} = height (as an integer)
|
||||
#Example, for a bitmap of width=123, height = 456, the English version of this string would be "123x456"</note>
|
||||
|
|
|
@ -1828,8 +1828,9 @@ CONSIDER: get this from CodeDom</note>
|
|||
</trans-unit>
|
||||
<trans-unit id="RSE_GraphicSizeFormat">
|
||||
<source>{0} x {1}</source>
|
||||
<target state="translated">{0} x {1}</target>
|
||||
<target state="needs-review-translation">{0} x {1}</target>
|
||||
<note>Format string for showing a graphic's size
|
||||
|
||||
# {0} = width (as an integer)
|
||||
# {1} = height (as an integer)
|
||||
#Example, for a bitmap of width=123, height = 456, the English version of this string would be "123x456"</note>
|
||||
|
|
|
@ -1828,8 +1828,9 @@ CONSIDER: get this from CodeDom</note>
|
|||
</trans-unit>
|
||||
<trans-unit id="RSE_GraphicSizeFormat">
|
||||
<source>{0} x {1}</source>
|
||||
<target state="translated">{0} x {1}</target>
|
||||
<target state="needs-review-translation">{0} x {1}</target>
|
||||
<note>Format string for showing a graphic's size
|
||||
|
||||
# {0} = width (as an integer)
|
||||
# {1} = height (as an integer)
|
||||
#Example, for a bitmap of width=123, height = 456, the English version of this string would be "123x456"</note>
|
||||
|
|
|
@ -1828,8 +1828,9 @@ CONSIDER: get this from CodeDom</note>
|
|||
</trans-unit>
|
||||
<trans-unit id="RSE_GraphicSizeFormat">
|
||||
<source>{0} x {1}</source>
|
||||
<target state="translated">{0} x {1}</target>
|
||||
<target state="needs-review-translation">{0} x {1}</target>
|
||||
<note>Format string for showing a graphic's size
|
||||
|
||||
# {0} = width (as an integer)
|
||||
# {1} = height (as an integer)
|
||||
#Example, for a bitmap of width=123, height = 456, the English version of this string would be "123x456"</note>
|
||||
|
|
|
@ -1828,8 +1828,9 @@ CONSIDER: get this from CodeDom</note>
|
|||
</trans-unit>
|
||||
<trans-unit id="RSE_GraphicSizeFormat">
|
||||
<source>{0} x {1}</source>
|
||||
<target state="translated">{0} x {1}</target>
|
||||
<target state="needs-review-translation">{0} x {1}</target>
|
||||
<note>Format string for showing a graphic's size
|
||||
|
||||
# {0} = width (as an integer)
|
||||
# {1} = height (as an integer)
|
||||
#Example, for a bitmap of width=123, height = 456, the English version of this string would be "123x456"</note>
|
||||
|
|
|
@ -1828,8 +1828,9 @@ CONSIDER: get this from CodeDom</note>
|
|||
</trans-unit>
|
||||
<trans-unit id="RSE_GraphicSizeFormat">
|
||||
<source>{0} x {1}</source>
|
||||
<target state="translated">{0} x {1}</target>
|
||||
<target state="needs-review-translation">{0} x {1}</target>
|
||||
<note>Format string for showing a graphic's size
|
||||
|
||||
# {0} = width (as an integer)
|
||||
# {1} = height (as an integer)
|
||||
#Example, for a bitmap of width=123, height = 456, the English version of this string would be "123x456"</note>
|
||||
|
|
|
@ -1828,8 +1828,9 @@ CONSIDER: get this from CodeDom</note>
|
|||
</trans-unit>
|
||||
<trans-unit id="RSE_GraphicSizeFormat">
|
||||
<source>{0} x {1}</source>
|
||||
<target state="translated">{0} x {1}</target>
|
||||
<target state="needs-review-translation">{0} x {1}</target>
|
||||
<note>Format string for showing a graphic's size
|
||||
|
||||
# {0} = width (as an integer)
|
||||
# {1} = height (as an integer)
|
||||
#Example, for a bitmap of width=123, height = 456, the English version of this string would be "123x456"</note>
|
||||
|
|
|
@ -1828,8 +1828,9 @@ CONSIDER: get this from CodeDom</note>
|
|||
</trans-unit>
|
||||
<trans-unit id="RSE_GraphicSizeFormat">
|
||||
<source>{0} x {1}</source>
|
||||
<target state="translated">{0} x {1}</target>
|
||||
<target state="needs-review-translation">{0} x {1}</target>
|
||||
<note>Format string for showing a graphic's size
|
||||
|
||||
# {0} = width (as an integer)
|
||||
# {1} = height (as an integer)
|
||||
#Example, for a bitmap of width=123, height = 456, the English version of this string would be "123x456"</note>
|
||||
|
|
|
@ -1828,8 +1828,9 @@ CONSIDER: get this from CodeDom</note>
|
|||
</trans-unit>
|
||||
<trans-unit id="RSE_GraphicSizeFormat">
|
||||
<source>{0} x {1}</source>
|
||||
<target state="translated">{0} x {1}</target>
|
||||
<target state="needs-review-translation">{0} x {1}</target>
|
||||
<note>Format string for showing a graphic's size
|
||||
|
||||
# {0} = width (as an integer)
|
||||
# {1} = height (as an integer)
|
||||
#Example, for a bitmap of width=123, height = 456, the English version of this string would be "123x456"</note>
|
||||
|
|
|
@ -1828,8 +1828,9 @@ CONSIDER: get this from CodeDom</note>
|
|||
</trans-unit>
|
||||
<trans-unit id="RSE_GraphicSizeFormat">
|
||||
<source>{0} x {1}</source>
|
||||
<target state="translated">{0} x {1}</target>
|
||||
<target state="needs-review-translation">{0} x {1}</target>
|
||||
<note>Format string for showing a graphic's size
|
||||
|
||||
# {0} = width (as an integer)
|
||||
# {1} = height (as an integer)
|
||||
#Example, for a bitmap of width=123, height = 456, the English version of this string would be "123x456"</note>
|
||||
|
|
|
@ -1828,8 +1828,9 @@ CONSIDER: get this from CodeDom</note>
|
|||
</trans-unit>
|
||||
<trans-unit id="RSE_GraphicSizeFormat">
|
||||
<source>{0} x {1}</source>
|
||||
<target state="translated">{0} x {1}</target>
|
||||
<target state="needs-review-translation">{0} x {1}</target>
|
||||
<note>Format string for showing a graphic's size
|
||||
|
||||
# {0} = width (as an integer)
|
||||
# {1} = height (as an integer)
|
||||
#Example, for a bitmap of width=123, height = 456, the English version of this string would be "123x456"</note>
|
||||
|
|
|
@ -1828,8 +1828,9 @@ CONSIDER: get this from CodeDom</note>
|
|||
</trans-unit>
|
||||
<trans-unit id="RSE_GraphicSizeFormat">
|
||||
<source>{0} x {1}</source>
|
||||
<target state="translated">{0} x {1}</target>
|
||||
<target state="needs-review-translation">{0} x {1}</target>
|
||||
<note>Format string for showing a graphic's size
|
||||
|
||||
# {0} = width (as an integer)
|
||||
# {1} = height (as an integer)
|
||||
#Example, for a bitmap of width=123, height = 456, the English version of this string would be "123x456"</note>
|
||||
|
|
|
@ -1828,8 +1828,9 @@ CONSIDER: get this from CodeDom</note>
|
|||
</trans-unit>
|
||||
<trans-unit id="RSE_GraphicSizeFormat">
|
||||
<source>{0} x {1}</source>
|
||||
<target state="translated">{0} x {1}</target>
|
||||
<target state="needs-review-translation">{0} x {1}</target>
|
||||
<note>Format string for showing a graphic's size
|
||||
|
||||
# {0} = width (as an integer)
|
||||
# {1} = height (as an integer)
|
||||
#Example, for a bitmap of width=123, height = 456, the English version of this string would be "123x456"</note>
|
||||
|
|
|
@ -24,17 +24,6 @@
|
|||
<CheckBox x:Name="toggleOutloning" IsChecked="{Binding IsOutliningEnabled}"
|
||||
Content="{x:Static local:Strings.Show_Outlining}"/>
|
||||
</GroupBox>
|
||||
<!-- this group box should be disabled for branch `release/dev16.2`, enabled otherwise -->
|
||||
<!--
|
||||
<GroupBox Header="{x:Static local:Strings.Use_out_of_process_language_server}">
|
||||
<StackPanel>
|
||||
<CheckBox x:Name="usePreviewTextHover" IsChecked="{Binding UsePreviewTextHover}"
|
||||
Content="{x:Static local:Strings.Text_hover}" />
|
||||
<CheckBox x:Name="usePreviewDiagnostics" IsChecked="{Binding UsePreviewDiagnostics}"
|
||||
Content="{x:Static local:Strings.Diagnostics}" />
|
||||
</StackPanel>
|
||||
</GroupBox>
|
||||
-->
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</Grid>
|
||||
|
|
|
@ -419,14 +419,5 @@ namespace Microsoft.VisualStudio.FSharp.UIResources {
|
|||
return ResourceManager.GetString("Unused_opens_code_fix", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to (Preview) Use out of process language server.
|
||||
/// </summary>
|
||||
public static string Use_out_of_process_language_server {
|
||||
get {
|
||||
return ResourceManager.GetString("Use_out_of_process_language_server", resourceCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -231,9 +231,6 @@
|
|||
<data name="Suggest_names_for_errors_code_fix" xml:space="preserve">
|
||||
<value>Suggest names for unresolved identifiers</value>
|
||||
</data>
|
||||
<data name="Use_out_of_process_language_server" xml:space="preserve">
|
||||
<value>(Preview) Use out of process language server</value>
|
||||
</data>
|
||||
<data name="Text_hover" xml:space="preserve">
|
||||
<value>Text hover</value>
|
||||
</data>
|
||||
|
|
|
@ -202,11 +202,6 @@
|
|||
<target state="translated">Navrhovat názvy pro nerozpoznané identifikátory</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="Use_out_of_process_language_server">
|
||||
<source>(Preview) Use out of process language server</source>
|
||||
<target state="translated">(Preview) Použít mimoprocesový jazykový server</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
|
@ -202,11 +202,6 @@
|
|||
<target state="translated">Namen für nicht aufgelöste Bezeichner vorschlagen</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="Use_out_of_process_language_server">
|
||||
<source>(Preview) Use out of process language server</source>
|
||||
<target state="translated">(Vorschauversion) Prozessexternen Sprachserver verwenden</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
|
@ -202,11 +202,6 @@
|
|||
<target state="translated">Sugerir nombres para los identificadores no resueltos</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="Use_out_of_process_language_server">
|
||||
<source>(Preview) Use out of process language server</source>
|
||||
<target state="translated">(Versión preliminar) Usar el servidor de lenguaje fuera del proceso</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
|
@ -202,11 +202,6 @@
|
|||
<target state="translated">Suggérer des noms pour les identificateurs non résolus</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="Use_out_of_process_language_server">
|
||||
<source>(Preview) Use out of process language server</source>
|
||||
<target state="translated">(Préversion) Utiliser un serveur de langage hors processus</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
|
@ -202,11 +202,6 @@
|
|||
<target state="translated">Suggerisci nomi per gli identificatori non risolti</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="Use_out_of_process_language_server">
|
||||
<source>(Preview) Use out of process language server</source>
|
||||
<target state="translated">(Anteprima) Usa server di linguaggio out-of-process</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
|
@ -202,11 +202,6 @@
|
|||
<target state="translated">未解決の識別子の名前を提案します</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="Use_out_of_process_language_server">
|
||||
<source>(Preview) Use out of process language server</source>
|
||||
<target state="translated">(プレビュー) プロセス外言語サーバーの使用</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
|
@ -202,11 +202,6 @@
|
|||
<target state="translated">확인되지 않은 식별자의 이름 제안</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="Use_out_of_process_language_server">
|
||||
<source>(Preview) Use out of process language server</source>
|
||||
<target state="translated">(미리 보기) Out of Process 언어 서버 사용</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
|
@ -202,11 +202,6 @@
|
|||
<target state="translated">Sugeruj nazwy w przypadku nierozpoznanych identyfikatorów</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="Use_out_of_process_language_server">
|
||||
<source>(Preview) Use out of process language server</source>
|
||||
<target state="translated">(Wersja zapoznawcza) Korzystanie z serwera języka poza procesem</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
|
@ -202,11 +202,6 @@
|
|||
<target state="translated">Sugerir nomes para identificadores não resolvidos</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="Use_out_of_process_language_server">
|
||||
<source>(Preview) Use out of process language server</source>
|
||||
<target state="translated">(Versão Prévia) Usar um servidor de idioma fora do processo</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
|
@ -202,11 +202,6 @@
|
|||
<target state="translated">Предлагать имена для неразрешенных идентификаторов</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="Use_out_of_process_language_server">
|
||||
<source>(Preview) Use out of process language server</source>
|
||||
<target state="translated">(Предварительная версия) Использование сервера языка процессов</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
|
@ -202,11 +202,6 @@
|
|||
<target state="translated">Çözümlenmemiş tanımlayıcılar için ad öner</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="Use_out_of_process_language_server">
|
||||
<source>(Preview) Use out of process language server</source>
|
||||
<target state="translated">(Önizleme) İşlem dışı dil sunucusunu kullanma</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
|
@ -202,11 +202,6 @@
|
|||
<target state="translated">为未解析标识符建议名称</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="Use_out_of_process_language_server">
|
||||
<source>(Preview) Use out of process language server</source>
|
||||
<target state="translated">(预览)使用进程外语言服务器</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
|
@ -202,11 +202,6 @@
|
|||
<target state="translated">為未解析的識別碼建議名稱</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
<trans-unit id="Use_out_of_process_language_server">
|
||||
<source>(Preview) Use out of process language server</source>
|
||||
<target state="translated">(預覽) 使用處理序語言伺服器</target>
|
||||
<note />
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
Загрузка…
Ссылка в новой задаче