@@ -24,58 +24,30 @@ open Microsoft.CodeAnalysis.ExternalAccess.FSharp.LanguageServices
2424[<AutoOpen>]
2525module private FSharpProjectOptionsHelpers =
2626
27- let mapCpsProjectToSite ( workspace : VisualStudioWorkspace , project : Project , serviceProvider : System.IServiceProvider , cpsCommandLineOptions : IDictionary < ProjectId , string [] * string []>) =
28- let hier = workspace.GetHierarchy( project.Id)
27+ let mapCpsProjectToSite ( project : Project , cpsCommandLineOptions : IDictionary < ProjectId , string [] * string []>) =
2928 let sourcePaths , referencePaths , options =
3029 match cpsCommandLineOptions.TryGetValue( project.Id) with
3130 | true , ( sourcePaths, options) -> sourcePaths, [||], options
3231 | false , _ -> [||], [||], [||]
32+ let mutable errorReporter = Unchecked.defaultof<_>
3333 {
34- new IProvideProjectSite with
35- member x.GetProjectSite () =
36- let mutable errorReporter =
37- let reporter = ProjectExternalErrorReporter( project.Id, " FS" , serviceProvider)
38- Some( reporter:> IVsLanguageServiceBuildErrorReporter2 )
39-
40- {
41- new IProjectSite with
42- member __.Description = project.Name
43- member __.CompilationSourceFiles = sourcePaths
44- member __.CompilationOptions =
45- Array.concat [ options; referencePaths |> Array.map( fun r -> " -r:" + r)]
46- member __.CompilationReferences = referencePaths
47- member site.CompilationBinOutputPath = site.CompilationOptions |> Array.tryPick ( fun s -> if s.StartsWith( " -o:" ) then Some s.[ 3 ..] else None)
48- member __.ProjectFileName = project.FilePath
49- member __.AdviseProjectSiteChanges ( _ , _ ) = ()
50- member __.AdviseProjectSiteCleaned ( _ , _ ) = ()
51- member __.AdviseProjectSiteClosed ( _ , _ ) = ()
52- member __.IsIncompleteTypeCheckEnvironment = false
53- member __.TargetFrameworkMoniker = " "
54- member __.ProjectGuid = project.Id.Id.ToString()
55- member __.LoadTime = System.DateTime.Now
56- member __.ProjectProvider = Some ( x)
57- member __.BuildErrorReporter with get () = errorReporter and set ( v ) = errorReporter <- v
58- }
59- interface IVsHierarchy with
60- member __.SetSite ( psp ) = hier.SetSite( psp)
61- member __.GetSite ( psp ) = hier.GetSite( ref psp)
62- member __.QueryClose ( pfCanClose )= hier.QueryClose( ref pfCanClose)
63- member __.Close () = hier.Close()
64- member __.GetGuidProperty ( itemid , propid , pguid ) = hier.GetGuidProperty( itemid, propid, ref pguid)
65- member __.SetGuidProperty ( itemid , propid , rguid ) = hier.SetGuidProperty( itemid, propid, ref rguid)
66- member __.GetProperty ( itemid , propid , pvar ) = hier.GetProperty( itemid, propid, ref pvar)
67- member __.SetProperty ( itemid , propid , var ) = hier.SetProperty( itemid, propid, var)
68- member __.GetNestedHierarchy ( itemid , iidHierarchyNested , ppHierarchyNested , pitemidNested ) =
69- hier.GetNestedHierarchy( itemid, ref iidHierarchyNested, ref ppHierarchyNested, ref pitemidNested)
70- member __.GetCanonicalName ( itemid , pbstrName ) = hier.GetCanonicalName( itemid, ref pbstrName)
71- member __.ParseCanonicalName ( pszName , pitemid ) = hier.ParseCanonicalName( pszName, ref pitemid)
72- member __.Unused0 () = hier.Unused0()
73- member __.AdviseHierarchyEvents ( pEventSink , pdwCookie ) = hier.AdviseHierarchyEvents( pEventSink, ref pdwCookie)
74- member __.UnadviseHierarchyEvents ( dwCookie ) = hier.UnadviseHierarchyEvents( dwCookie)
75- member __.Unused1 () = hier.Unused1()
76- member __.Unused2 () = hier.Unused2()
77- member __.Unused3 () = hier.Unused3()
78- member __.Unused4 () = hier.Unused4()
34+ new IProjectSite with
35+ member __.Description = project.Name
36+ member __.CompilationSourceFiles = sourcePaths
37+ member __.CompilationOptions =
38+ Array.concat [ options; referencePaths |> Array.map( fun r -> " -r:" + r)]
39+ member __.CompilationReferences = referencePaths
40+ member site.CompilationBinOutputPath = site.CompilationOptions |> Array.tryPick ( fun s -> if s.StartsWith( " -o:" ) then Some s.[ 3 ..] else None)
41+ member __.ProjectFileName = project.FilePath
42+ member __.AdviseProjectSiteChanges ( _ , _ ) = ()
43+ member __.AdviseProjectSiteCleaned ( _ , _ ) = ()
44+ member __.AdviseProjectSiteClosed ( _ , _ ) = ()
45+ member __.IsIncompleteTypeCheckEnvironment = false
46+ member __.TargetFrameworkMoniker = " "
47+ member __.ProjectGuid = project.Id.Id.ToString()
48+ member __.LoadTime = System.DateTime.Now
49+ member __.ProjectProvider = None
50+ member __.BuildErrorReporter with get () = errorReporter and set ( v ) = errorReporter <- v
7951 }
8052
8153 let hasProjectVersionChanged ( oldProject : Project ) ( newProject : Project ) =
@@ -108,11 +80,13 @@ type private FSharpProjectOptionsMessage =
10880 | ClearSingleFileOptionsCache of DocumentId
10981
11082[<Sealed>]
111- type private FSharpProjectOptionsReactor ( workspace : VisualStudioWorkspace , settings : EditorOptions , serviceProvider , checkerProvider : FSharpCheckerProvider ) =
83+ type private FSharpProjectOptionsReactor ( _workspace : VisualStudioWorkspace , settings : EditorOptions , _serviceProvider , checkerProvider : FSharpCheckerProvider ) =
11284 let cancellationTokenSource = new CancellationTokenSource()
11385
11486 // Hack to store command line options from HandleCommandLineChanges
115- let cpsCommandLineOptions = new ConcurrentDictionary< ProjectId, string[] * string[]>()
87+ let cpsCommandLineOptions = ConcurrentDictionary< ProjectId, string[] * string[]>()
88+
89+ let legacyProjectSites = ConcurrentDictionary< ProjectId, IProjectSite>()
11690
11791 let cache = Dictionary< ProjectId, Project * FSharpParsingOptions * FSharpProjectOptions>()
11892 let singleFileCache = Dictionary< DocumentId, VersionStamp * FSharpParsingOptions * FSharpProjectOptions>()
@@ -158,6 +132,16 @@ type private FSharpProjectOptionsReactor (workspace: VisualStudioWorkspace, sett
158132 else
159133 return Some( parsingOptions, projectOptions)
160134 }
135+
136+ let tryGetProjectSite ( project : Project ) =
137+ // Cps
138+ if cpsCommandLineOptions.ContainsKey project.Id then
139+ Some ( mapCpsProjectToSite( project, cpsCommandLineOptions))
140+ else
141+ // Legacy
142+ match legacyProjectSites.TryGetValue project.Id with
143+ | true , site -> Some site
144+ | _ -> None
161145
162146 let rec tryComputeOptions ( project : Project ) =
163147 async {
@@ -183,15 +167,9 @@ type private FSharpProjectOptionsReactor (workspace: VisualStudioWorkspace, sett
183167 return None
184168 else
185169
186- let hier = workspace.GetHierarchy( projectId)
187- let projectSite =
188- match hier with
189- // Legacy
190- | (: ? IProvideProjectSite as provideSite ) -> provideSite .GetProjectSite ()
191- // Cps
192- | _ ->
193- let provideSite = mapCpsProjectToSite( workspace, project, serviceProvider, cpsCommandLineOptions)
194- provideSite.GetProjectSite()
170+ match tryGetProjectSite project with
171+ | None -> return None
172+ | Some projectSite ->
195173
196174 let otherOptions =
197175 project.ProjectReferences
@@ -283,6 +261,7 @@ type private FSharpProjectOptionsReactor (workspace: VisualStudioWorkspace, sett
283261
284262 | FSharpProjectOptionsMessage.ClearOptions( projectId) ->
285263 cache.Remove( projectId) |> ignore
264+ legacyProjectSites.TryRemove( projectId) |> ignore
286265 | FSharpProjectOptionsMessage.ClearSingleFileOptionsCache( documentId) ->
287266 singleFileCache.Remove( documentId) |> ignore
288267 }
@@ -304,6 +283,9 @@ type private FSharpProjectOptionsReactor (workspace: VisualStudioWorkspace, sett
304283 member __.SetCpsCommandLineOptions ( projectId , sourcePaths , options ) =
305284 cpsCommandLineOptions.[ projectId] <- ( sourcePaths, options)
306285
286+ member __.SetLegacyProjectSite ( projectId , projectSite ) =
287+ legacyProjectSites.[ projectId] <- projectSite
288+
307289 member __.TryGetCachedOptionsByProjectId ( projectId ) =
308290 match cache.TryGetValue( projectId) with
309291 | true , result -> Some( result)
@@ -344,6 +326,9 @@ type internal FSharpProjectOptionsManager
344326 | _ -> ()
345327 )
346328
329+ member __.SetLegacyProjectSite ( projectId , projectSite ) =
330+ reactor.SetLegacyProjectSite ( projectId, projectSite)
331+
347332 /// Clear a project from the project table
348333 member this.ClearInfoForProject ( projectId : ProjectId ) =
349334 reactor.ClearOptionsByProjectId( projectId)
0 commit comments