Skip to content

Commit dc14f59

Browse files
authored
Merge branch 'lsp' into merges/main-to-lsp
2 parents 327d96c + c88e4c3 commit dc14f59

23 files changed

+1187
-1
lines changed

VSFSharpExtension.sln

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio Version 17
4+
VisualStudioVersion = 17.0.31903.59
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{B4A1E626-4A48-4977-B291-219882DB3413}"
7+
EndProject
8+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FSharp.VisualStudio.Extension", "src\FSharp.VisualStudio.Extension\FSharp.VisualStudio.Extension.csproj", "{14B9AB0E-2FC0-43F1-9775-20C262202D12}"
9+
EndProject
10+
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Compiler.LanguageServer", "src\FSharp.Compiler.LanguageServer\FSharp.Compiler.LanguageServer.fsproj", "{7EDDFB35-2428-4433-8ABF-47233480B746}"
11+
EndProject
12+
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Compiler.Service", "src\Compiler\FSharp.Compiler.Service.fsproj", "{0B24DCA6-902F-409E-A18C-7B1BFDDC8849}"
13+
EndProject
14+
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Core", "src\FSharp.Core\FSharp.Core.fsproj", "{5A4B66D5-A6C3-402C-A010-7A3635098DA7}"
15+
EndProject
16+
Global
17+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
18+
Debug|Any CPU = Debug|Any CPU
19+
Proto|Any CPU = Proto|Any CPU
20+
Release|Any CPU = Release|Any CPU
21+
EndGlobalSection
22+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
23+
{14B9AB0E-2FC0-43F1-9775-20C262202D12}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
24+
{14B9AB0E-2FC0-43F1-9775-20C262202D12}.Debug|Any CPU.Build.0 = Debug|Any CPU
25+
{14B9AB0E-2FC0-43F1-9775-20C262202D12}.Proto|Any CPU.ActiveCfg = Release|Any CPU
26+
{14B9AB0E-2FC0-43F1-9775-20C262202D12}.Proto|Any CPU.Build.0 = Release|Any CPU
27+
{14B9AB0E-2FC0-43F1-9775-20C262202D12}.Proto|Any CPU.Deploy.0 = Release|Any CPU
28+
{14B9AB0E-2FC0-43F1-9775-20C262202D12}.Release|Any CPU.ActiveCfg = Release|Any CPU
29+
{14B9AB0E-2FC0-43F1-9775-20C262202D12}.Release|Any CPU.Build.0 = Release|Any CPU
30+
{7EDDFB35-2428-4433-8ABF-47233480B746}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
31+
{7EDDFB35-2428-4433-8ABF-47233480B746}.Debug|Any CPU.Build.0 = Debug|Any CPU
32+
{7EDDFB35-2428-4433-8ABF-47233480B746}.Proto|Any CPU.ActiveCfg = Release|Any CPU
33+
{7EDDFB35-2428-4433-8ABF-47233480B746}.Proto|Any CPU.Build.0 = Release|Any CPU
34+
{7EDDFB35-2428-4433-8ABF-47233480B746}.Release|Any CPU.ActiveCfg = Release|Any CPU
35+
{7EDDFB35-2428-4433-8ABF-47233480B746}.Release|Any CPU.Build.0 = Release|Any CPU
36+
{0B24DCA6-902F-409E-A18C-7B1BFDDC8849}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
37+
{0B24DCA6-902F-409E-A18C-7B1BFDDC8849}.Debug|Any CPU.Build.0 = Debug|Any CPU
38+
{0B24DCA6-902F-409E-A18C-7B1BFDDC8849}.Proto|Any CPU.ActiveCfg = Debug|Any CPU
39+
{0B24DCA6-902F-409E-A18C-7B1BFDDC8849}.Proto|Any CPU.Build.0 = Debug|Any CPU
40+
{0B24DCA6-902F-409E-A18C-7B1BFDDC8849}.Release|Any CPU.ActiveCfg = Release|Any CPU
41+
{0B24DCA6-902F-409E-A18C-7B1BFDDC8849}.Release|Any CPU.Build.0 = Release|Any CPU
42+
{5A4B66D5-A6C3-402C-A010-7A3635098DA7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
43+
{5A4B66D5-A6C3-402C-A010-7A3635098DA7}.Debug|Any CPU.Build.0 = Debug|Any CPU
44+
{5A4B66D5-A6C3-402C-A010-7A3635098DA7}.Proto|Any CPU.ActiveCfg = Proto|Any CPU
45+
{5A4B66D5-A6C3-402C-A010-7A3635098DA7}.Proto|Any CPU.Build.0 = Proto|Any CPU
46+
{5A4B66D5-A6C3-402C-A010-7A3635098DA7}.Release|Any CPU.ActiveCfg = Release|Any CPU
47+
{5A4B66D5-A6C3-402C-A010-7A3635098DA7}.Release|Any CPU.Build.0 = Release|Any CPU
48+
EndGlobalSection
49+
GlobalSection(SolutionProperties) = preSolution
50+
HideSolutionNode = FALSE
51+
EndGlobalSection
52+
GlobalSection(NestedProjects) = preSolution
53+
{14B9AB0E-2FC0-43F1-9775-20C262202D12} = {B4A1E626-4A48-4977-B291-219882DB3413}
54+
EndGlobalSection
55+
EndGlobal

VisualFSharp.sln

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,11 @@ EndProject
192192
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "MicroPerf", "tests\benchmarks\CompiledCodeBenchmarks\MicroPerf\MicroPerf.fsproj", "{601CD5C1-EAFA-4AE3-8FB9-F667B5728213}"
193193
EndProject
194194
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MicroPerfCSharp", "tests\benchmarks\CompiledCodeBenchmarks\MicroPerf\CS\MicroPerfCSharp.csproj", "{9F9DD315-37DA-4413-928E-1CFC6924B64F}"
195+
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Compiler.LanguageServer", "src\FSharp.Compiler.LanguageServer\FSharp.Compiler.LanguageServer.fsproj", "{D72F6593-DB2D-47AC-8E15-8DCE8527972E}"
196+
EndProject
197+
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FSharp.Compiler.LanguageServer.Tests", "tests\FSharp.Compiler.LanguageServer.Tests\FSharp.Compiler.LanguageServer.Tests.fsproj", "{1E83A6C8-FA4D-42BD-B4A5-B7F9AAD1B388}"
198+
EndProject
199+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FSharp.VisualStudio.Extension", "src\FSharp.VisualStudio.Extension\FSharp.VisualStudio.Extension.csproj", "{E1013576-6257-47BA-AAFB-F95B68DAB1FF}"
195200
EndProject
196201
Global
197202
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -1019,6 +1024,42 @@ Global
10191024
{9F9DD315-37DA-4413-928E-1CFC6924B64F}.Release|Any CPU.Build.0 = Release|Any CPU
10201025
{9F9DD315-37DA-4413-928E-1CFC6924B64F}.Release|x86.ActiveCfg = Release|Any CPU
10211026
{9F9DD315-37DA-4413-928E-1CFC6924B64F}.Release|x86.Build.0 = Release|Any CPU
1027+
{D72F6593-DB2D-47AC-8E15-8DCE8527972E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
1028+
{D72F6593-DB2D-47AC-8E15-8DCE8527972E}.Debug|Any CPU.Build.0 = Debug|Any CPU
1029+
{D72F6593-DB2D-47AC-8E15-8DCE8527972E}.Debug|x86.ActiveCfg = Debug|Any CPU
1030+
{D72F6593-DB2D-47AC-8E15-8DCE8527972E}.Debug|x86.Build.0 = Debug|Any CPU
1031+
{D72F6593-DB2D-47AC-8E15-8DCE8527972E}.Proto|Any CPU.ActiveCfg = Debug|Any CPU
1032+
{D72F6593-DB2D-47AC-8E15-8DCE8527972E}.Proto|Any CPU.Build.0 = Debug|Any CPU
1033+
{D72F6593-DB2D-47AC-8E15-8DCE8527972E}.Proto|x86.ActiveCfg = Debug|Any CPU
1034+
{D72F6593-DB2D-47AC-8E15-8DCE8527972E}.Proto|x86.Build.0 = Debug|Any CPU
1035+
{D72F6593-DB2D-47AC-8E15-8DCE8527972E}.Release|Any CPU.ActiveCfg = Release|Any CPU
1036+
{D72F6593-DB2D-47AC-8E15-8DCE8527972E}.Release|Any CPU.Build.0 = Release|Any CPU
1037+
{D72F6593-DB2D-47AC-8E15-8DCE8527972E}.Release|x86.ActiveCfg = Release|Any CPU
1038+
{D72F6593-DB2D-47AC-8E15-8DCE8527972E}.Release|x86.Build.0 = Release|Any CPU
1039+
{1E83A6C8-FA4D-42BD-B4A5-B7F9AAD1B388}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
1040+
{1E83A6C8-FA4D-42BD-B4A5-B7F9AAD1B388}.Debug|Any CPU.Build.0 = Debug|Any CPU
1041+
{1E83A6C8-FA4D-42BD-B4A5-B7F9AAD1B388}.Debug|x86.ActiveCfg = Debug|Any CPU
1042+
{1E83A6C8-FA4D-42BD-B4A5-B7F9AAD1B388}.Debug|x86.Build.0 = Debug|Any CPU
1043+
{1E83A6C8-FA4D-42BD-B4A5-B7F9AAD1B388}.Proto|Any CPU.ActiveCfg = Debug|Any CPU
1044+
{1E83A6C8-FA4D-42BD-B4A5-B7F9AAD1B388}.Proto|Any CPU.Build.0 = Debug|Any CPU
1045+
{1E83A6C8-FA4D-42BD-B4A5-B7F9AAD1B388}.Proto|x86.ActiveCfg = Debug|Any CPU
1046+
{1E83A6C8-FA4D-42BD-B4A5-B7F9AAD1B388}.Proto|x86.Build.0 = Debug|Any CPU
1047+
{1E83A6C8-FA4D-42BD-B4A5-B7F9AAD1B388}.Release|Any CPU.ActiveCfg = Release|Any CPU
1048+
{1E83A6C8-FA4D-42BD-B4A5-B7F9AAD1B388}.Release|Any CPU.Build.0 = Release|Any CPU
1049+
{1E83A6C8-FA4D-42BD-B4A5-B7F9AAD1B388}.Release|x86.ActiveCfg = Release|Any CPU
1050+
{1E83A6C8-FA4D-42BD-B4A5-B7F9AAD1B388}.Release|x86.Build.0 = Release|Any CPU
1051+
{E1013576-6257-47BA-AAFB-F95B68DAB1FF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
1052+
{E1013576-6257-47BA-AAFB-F95B68DAB1FF}.Debug|Any CPU.Build.0 = Debug|Any CPU
1053+
{E1013576-6257-47BA-AAFB-F95B68DAB1FF}.Debug|x86.ActiveCfg = Debug|Any CPU
1054+
{E1013576-6257-47BA-AAFB-F95B68DAB1FF}.Debug|x86.Build.0 = Debug|Any CPU
1055+
{E1013576-6257-47BA-AAFB-F95B68DAB1FF}.Proto|Any CPU.ActiveCfg = Debug|Any CPU
1056+
{E1013576-6257-47BA-AAFB-F95B68DAB1FF}.Proto|Any CPU.Build.0 = Debug|Any CPU
1057+
{E1013576-6257-47BA-AAFB-F95B68DAB1FF}.Proto|x86.ActiveCfg = Debug|Any CPU
1058+
{E1013576-6257-47BA-AAFB-F95B68DAB1FF}.Proto|x86.Build.0 = Debug|Any CPU
1059+
{E1013576-6257-47BA-AAFB-F95B68DAB1FF}.Release|Any CPU.ActiveCfg = Release|Any CPU
1060+
{E1013576-6257-47BA-AAFB-F95B68DAB1FF}.Release|Any CPU.Build.0 = Release|Any CPU
1061+
{E1013576-6257-47BA-AAFB-F95B68DAB1FF}.Release|x86.ActiveCfg = Release|Any CPU
1062+
{E1013576-6257-47BA-AAFB-F95B68DAB1FF}.Release|x86.Build.0 = Release|Any CPU
10221063
EndGlobalSection
10231064
GlobalSection(SolutionProperties) = preSolution
10241065
HideSolutionNode = FALSE
@@ -1099,6 +1140,7 @@ Global
10991140
{6734FC6F-B5F3-45E1-9A72-720378BB49C9} = {DFB6ADD7-3149-43D9-AFA0-FC4A818B472B}
11001141
{601CD5C1-EAFA-4AE3-8FB9-F667B5728213} = {DFB6ADD7-3149-43D9-AFA0-FC4A818B472B}
11011142
{9F9DD315-37DA-4413-928E-1CFC6924B64F} = {DFB6ADD7-3149-43D9-AFA0-FC4A818B472B}
1143+
{1E83A6C8-FA4D-42BD-B4A5-B7F9AAD1B388} = {CFE3259A-2D30-4EB0-80D5-E8B5F3D01449}
11021144
EndGlobalSection
11031145
GlobalSection(ExtensibilityGlobals) = postSolution
11041146
SolutionGuid = {48EDBBBE-C8EE-4E3C-8B19-97184A487B37}

src/Compiler/FSharp.Compiler.Service.fsproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@
8484
<InternalsVisibleTo Include="HistoricalBenchmark" />
8585
<InternalsVisibleTo Include="FSharp.Test.Utilities" />
8686
<InternalsVisibleTo Include="FSharp.Editor" />
87+
<InternalsVisibleTo Include="FSharp.Compiler.LanguageServer" />
8788
</ItemGroup>
8889

8990
<ItemGroup>

src/Compiler/Facilities/Hashing.fs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,11 @@ module internal Md5Hasher =
4646
let private md5 =
4747
new ThreadLocal<_>(fun () -> System.Security.Cryptography.MD5.Create())
4848

49-
let computeHash (bytes: byte array) = md5.Value.ComputeHash(bytes)
49+
let computeHash (bytes: byte array) =
50+
// md5.Value.ComputeHash(bytes) TODO: the threadlocal is not working in new VS extension
51+
ignore md5
52+
let md5 = System.Security.Cryptography.MD5.Create()
53+
md5.ComputeHash(bytes)
5054

5155
let empty = Array.empty
5256

src/Compiler/Service/FSharpProjectSnapshot.fs

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -676,6 +676,63 @@ and [<Experimental("This FCS API is experimental and subject to change.")>] FSha
676676

677677
FSharpProjectSnapshot.FromOptions(options, getFileSnapshot)
678678

679+
static member FromResponseFile(responseFile: FileInfo, projectFileName) =
680+
if not responseFile.Exists then
681+
failwith $"%s{responseFile.FullName} does not exist"
682+
683+
let compilerArgs = File.ReadAllLines responseFile.FullName
684+
685+
FSharpProjectSnapshot.FromCommandLineArgs(compilerArgs, responseFile.DirectoryName, projectFileName)
686+
687+
static member FromCommandLineArgs(compilerArgs: string array, directoryPath: string, projectFileName) =
688+
let fsharpFileExtensions = set [| ".fs"; ".fsi"; ".fsx" |]
689+
690+
let isFSharpFile (file: string) =
691+
Set.exists (fun (ext: string) -> file.EndsWith(ext, StringComparison.Ordinal)) fsharpFileExtensions
692+
693+
let isReference: string -> bool = _.StartsWith("-r:")
694+
695+
let fsharpFiles =
696+
compilerArgs
697+
|> Array.choose (fun (line: string) ->
698+
if not (isFSharpFile line) then
699+
None
700+
else
701+
702+
let fullPath = Path.Combine(directoryPath, line)
703+
if not (File.Exists fullPath) then None else Some fullPath)
704+
|> Array.toList
705+
706+
let referencesOnDisk =
707+
compilerArgs |> Seq.filter isReference |> Seq.map _.Substring(3) |> Seq.toList
708+
709+
let otherOptions =
710+
compilerArgs
711+
|> Seq.filter (not << isReference)
712+
|> Seq.filter (not << isFSharpFile)
713+
|> Seq.toList
714+
715+
FSharpProjectSnapshot.Create(
716+
projectFileName = projectFileName,
717+
projectId = None,
718+
sourceFiles = (fsharpFiles |> List.map FSharpFileSnapshot.CreateFromFileSystem),
719+
referencesOnDisk =
720+
(referencesOnDisk
721+
|> List.map (fun x ->
722+
{
723+
Path = x
724+
LastModified = FileSystem.GetLastWriteTimeShim(x)
725+
})),
726+
otherOptions = otherOptions,
727+
referencedProjects = [],
728+
isIncompleteTypeCheckEnvironment = false,
729+
useScriptResolutionRules = false,
730+
loadTime = DateTime.Now,
731+
unresolvedReferences = None,
732+
originalLoadReferences = [],
733+
stamp = None
734+
)
735+
679736
let rec internal snapshotToOptions (projectSnapshot: ProjectSnapshotBase<_>) =
680737
{
681738
ProjectFileName = projectSnapshot.ProjectFileName
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
namespace FSharp.Compiler.LanguageServer.Common
2+
3+
open Microsoft.VisualStudio.LanguageServer.Protocol
4+
open Microsoft.CommonLanguageServerProtocol.Framework
5+
6+
type IServerCapabilitiesOverride =
7+
abstract member OverrideServerCapabilities: ServerCapabilities -> ServerCapabilities
8+
9+
type CapabilitiesManager(scOverrides: IServerCapabilitiesOverride seq) =
10+
11+
let mutable initializeParams = None
12+
13+
let defaultCapabilities =
14+
ServerCapabilities(
15+
TextDocumentSync = TextDocumentSyncOptions(OpenClose = true, Change = TextDocumentSyncKind.Full),
16+
DiagnosticOptions =
17+
DiagnosticOptions(WorkDoneProgress = true, InterFileDependencies = true, Identifier = "potato", WorkspaceDiagnostics = true),
18+
CompletionProvider =
19+
CompletionOptions(TriggerCharacters=[|"."; " "|], ResolveProvider=true, WorkDoneProgress=true),
20+
HoverProvider = SumType<bool, HoverOptions>(HoverOptions(WorkDoneProgress = true))
21+
)
22+
23+
interface IInitializeManager<InitializeParams, InitializeResult> with
24+
member this.SetInitializeParams(request) = initializeParams <- Some request
25+
26+
member this.GetInitializeResult() =
27+
let serverCapabilities =
28+
(defaultCapabilities, scOverrides)
29+
||> Seq.fold (fun acc (x: IServerCapabilitiesOverride) -> x.OverrideServerCapabilities acc)
30+
31+
InitializeResult(Capabilities = serverCapabilities)
32+
33+
member this.GetInitializeParams() =
34+
match initializeParams with
35+
| Some params' -> params'
36+
| None -> failwith "InitializeParams is null"
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
namespace FSharp.Compiler.LanguageServer.Common
2+
3+
open Microsoft.CommonLanguageServerProtocol.Framework
4+
open FSharp.Compiler.CodeAnalysis
5+
open System
6+
open System.Threading
7+
open System.Threading.Tasks
8+
9+
#nowarn "57"
10+
11+
type FSharpRequestContext(lspServices: ILspServices, logger: ILspLogger, workspace: FSharpWorkspace, checker: FSharpChecker) =
12+
member _.LspServices = lspServices
13+
member _.Logger = logger
14+
member _.Workspace = workspace
15+
member _.Checker = checker
16+
17+
// TODO: split to parse and check diagnostics
18+
member _.GetDiagnosticsForFile(file: Uri) =
19+
20+
workspace.GetSnapshotForFile file
21+
|> Option.map (fun snapshot ->
22+
async {
23+
let! parseResult, checkFileAnswer = checker.ParseAndCheckFileInProject(file.LocalPath, snapshot, "LSP Get diagnostics")
24+
25+
return
26+
match checkFileAnswer with
27+
| FSharpCheckFileAnswer.Succeeded result -> result.Diagnostics
28+
| FSharpCheckFileAnswer.Aborted -> parseResult.Diagnostics
29+
})
30+
|> Option.defaultValue (async.Return [||])
31+
32+
type ContextHolder(intialWorkspace, lspServices: ILspServices) =
33+
34+
let logger = lspServices.GetRequiredService<ILspLogger>()
35+
36+
// TODO: We need to get configuration for this somehow. Also make it replaceable when configuration changes.
37+
let checker =
38+
FSharpChecker.Create(
39+
keepAllBackgroundResolutions = true,
40+
keepAllBackgroundSymbolUses = true,
41+
enableBackgroundItemKeyStoreAndSemanticClassification = true,
42+
enablePartialTypeChecking = true,
43+
parallelReferenceResolution = true,
44+
captureIdentifiersWhenParsing = true,
45+
useSyntaxTreeCache = true,
46+
useTransparentCompiler = true
47+
)
48+
49+
let mutable context =
50+
FSharpRequestContext(lspServices, logger, intialWorkspace, checker)
51+
52+
member _.GetContext() = context
53+
54+
member _.UpdateWorkspace(f) =
55+
context <- FSharpRequestContext(lspServices, logger, f context.Workspace, checker)
56+
57+
type FShapRequestContextFactory(lspServices: ILspServices) =
58+
59+
interface IRequestContextFactory<FSharpRequestContext> with
60+
61+
member _.CreateRequestContextAsync<'TRequestParam>
62+
(
63+
queueItem: IQueueItem<FSharpRequestContext>,
64+
requestParam: 'TRequestParam,
65+
cancellationToken: CancellationToken
66+
) =
67+
lspServices.GetRequiredService<ContextHolder>()
68+
|> _.GetContext()
69+
|> Task.FromResult
70+

0 commit comments

Comments
 (0)