@@ -43,7 +43,6 @@ type ProjectController(toolsPath: ToolsPath, workspaceLoaderFactory: ToolsPath -
4343 let workspaceReady = Event< unit>()
4444 let notify = Event< ProjectResponse>()
4545
46-
4746 let deduplicateBy keySelector ( obs : IObservable < 'a >) =
4847 obs
4948 |> Observable.synchronize // deals with concurrency issues
@@ -61,37 +60,35 @@ type ProjectController(toolsPath: ToolsPath, workspaceLoaderFactory: ToolsPath -
6160 projs |> List.iter ( fun ( fileName , _ ) -> fileName |> ProjectResponse.ProjectChanged |> notify.Trigger)
6261
6362 for ( key, group) in projectGroups do
64- x.LoadWorkspace( group, key)
63+ x.LoadWorkspace( group, key) |> ignore
6564
6665 projectsChanged |> deduplicateBy fst |> Observable.subscribe loadProjects
6766
6867
6968 let updateState ( response : ProjectCrackerCache ) =
7069 let normalizeOptions ( opts : FSharpProjectOptions ) =
7170 { opts with
72- SourceFiles =
71+ SourceFiles =
7372 opts.SourceFiles
7473 |> Array.filter ( FscArguments.isCompileFile)
7574 |> Array.map ( Path.GetFullPath)
7675 |> Array.map ( fun p -> ( p.Chars 0 ). ToString() .ToLower() + p.Substring( 1 ))
77- OtherOptions =
78- opts.OtherOptions
79- |> Array.map
80- ( fun n ->
81- if FscArguments.isCompileFile ( n) then
82- Path.GetFullPath n
83- else
84- n) }
76+ OtherOptions =
77+ opts.OtherOptions
78+ |> Array.map ( fun n ->
79+ if FscArguments.isCompileFile ( n) then
80+ Path.GetFullPath n
81+ else
82+ n) }
8583
8684 for file in
8785 response.Items
88- |> List.choose
89- ( function
86+ |> List.choose ( function
9087 | ProjectViewerItem.Compile ( p, _) -> Some p) do
9188 fileCheckOptions.[ file] <- normalizeOptions response.Options
9289
9390
94- member private x. loadProjects ( files : string list ) ( binaryLogs : BinaryLogGeneration ) =
91+ let loadProjects ( files : string list ) ( binaryLogs : BinaryLogGeneration ) =
9592 async {
9693 let onChange fn = projectsChanged.OnNext( fn, binaryLogs)
9794
@@ -117,8 +114,7 @@ type ProjectController(toolsPath: ToolsPath, workspaceLoaderFactory: ToolsPath -
117114
118115 let responseFiles =
119116 response.Items
120- |> List.choose
121- ( function
117+ |> List.choose ( function
122118 | ProjectViewerItem.Compile ( p, _) -> Some p)
123119
124120 let projInfo : ProjectResult =
@@ -134,8 +130,7 @@ type ProjectController(toolsPath: ToolsPath, workspaceLoaderFactory: ToolsPath -
134130 | ProjectSystemState.LoadedOther ( extraInfo, projectFiles, fromDpiCache) ->
135131 let responseFiles =
136132 projectFiles
137- |> List.choose
138- ( function
133+ |> List.choose ( function
139134 | ProjectViewerItem.Compile ( p, _) -> Some p)
140135
141136 let projInfo : ProjectResult =
@@ -177,75 +172,77 @@ type ProjectController(toolsPath: ToolsPath, workspaceLoaderFactory: ToolsPath -
177172 return true
178173 }
179174
180- member private x.LoaderLoop =
181- MailboxProcessor.Start
182- ( fun agent -> //If couldn't recive new event in 50 ms then just load previous one
183- let rec loop ( previousStatus : ( string list * BinaryLogGeneration ) option ) =
184- async {
185- match previousStatus with
186-
187- | Some ( fn, gb) ->
188- match ! agent.TryReceive( 50 ) with
189- | None -> //If couldn't recive new event in 50 ms then just load previous one
190- let! _ = x.loadProjects fn gb
191- return ! loop None
192- | Some ( fn2, gb2) when fn2 = fn -> //If recived same load request then wait again (in practice shouldn't happen more than 2 times)
193- return ! loop previousStatus
194- | Some ( fn2, gb2) -> //If recived some other project load previous one, and then wait with the new one
195- let! _ = x.loadProjects fn gb
196- return ! loop ( Some( fn2, gb2))
197- | None ->
198- let! ( fn , gb ) = agent.Receive()
199- return ! loop ( Some( fn, gb))
200- }
201-
202- loop None)
175+ let loaderLoop =
176+ MailboxProcessor.Start ( fun agent -> //If couldn't recive new event in 50 ms then just load previous one
177+ let rec loop ( previousStatus : ( AsyncReplyChannel < bool > * string list * BinaryLogGeneration ) option ) =
178+ async {
179+ match previousStatus with
180+
181+ | Some ( chan, fn, gb) ->
182+ match ! agent.TryReceive( 50 ) with
183+ | None -> //If couldn't recive new event in 50 ms then just load previous one
184+ let! res = loadProjects fn gb
185+ chan.Reply res
186+ return ! loop None
187+ | Some ( chan2, fn2, gb2) when fn2 = fn -> //If recived same load request then wait again (in practice shouldn't happen more than 2 times)
188+ return ! loop previousStatus
189+ | Some ( chan2, fn2, gb2) -> //If recived some other project load previous one, and then wait with the new one
190+ let! res = loadProjects fn gb
191+ chan.Reply res
192+ return ! loop ( Some( chan2, fn2, gb2))
193+ | None ->
194+ let! ( chan , fn , gb ) = agent.Receive()
195+ return ! loop ( Some( chan, fn, gb))
196+ }
197+
198+ loop None)
203199
204200 ///Event notifies that whole workspace has been loaded
205- member __ .WorkspaceReady = workspaceReady.Publish
201+ member _ .WorkspaceReady = workspaceReady.Publish
206202
207203 ///Event notifies about any loading events
208- member __ .Notifications = notify.Publish
204+ member _ .Notifications = notify.Publish
209205
210- member __ .IsWorkspaceReady = isWorkspaceReady
206+ member _ .IsWorkspaceReady = isWorkspaceReady
211207
212208 ///Try to get instance of `FSharpProjectOptions` for given `.fs` file
213- member __ .GetProjectOptions( file : string ) : FSharpProjectOptions option =
209+ member _ .GetProjectOptions( file : string ) : FSharpProjectOptions option =
214210 let file = Utils.normalizePath file
215211 fileCheckOptions.TryFind file
216212
217- member __ .SetProjectOptions( file : string , opts : FSharpProjectOptions ) =
213+ member _ .SetProjectOptions( file : string , opts : FSharpProjectOptions ) =
218214 let file = Utils.normalizePath file
219215 fileCheckOptions.AddOrUpdate( file, ( fun _ -> opts), ( fun _ _ -> opts)) |> ignore
220216
221- member __ .RemoveProjectOptions( file ) =
217+ member _ .RemoveProjectOptions( file ) =
222218 let file = Utils.normalizePath file
223219 fileCheckOptions.TryRemove file |> ignore
224220
225221 ///Try to get instance of `FSharpProjectOptions` for given `.fsproj` file
226- member __ .GetProjectOptionsForFsproj( fsprojPath : string ) : FSharpProjectOptions option =
222+ member _ .GetProjectOptionsForFsproj( fsprojPath : string ) : FSharpProjectOptions option =
227223 fileCheckOptions.Values |> Seq.tryFind ( fun n -> n.ProjectFileName = fsprojPath)
228224
229225 ///Returns a sequance of all known path-to-`.fs` * `FSharpProjectOptions` pairs
230- member __ .ProjectOptions = fileCheckOptions |> Seq.map (| KeyValue|)
226+ member _ .ProjectOptions = fileCheckOptions |> Seq.map (| KeyValue|)
231227
232228 ///Loads a single project file
233229 member x.LoadProject ( projectFileName : string , binaryLogs : BinaryLogGeneration ) =
234- x.LoaderLoop.Post ( [ projectFileName ], binaryLogs)
230+ loaderLoop.PostAndAsyncReply (( fun chan -> chan , [ projectFileName ], binaryLogs) )
235231
236232 ///Loads a single project file
237233 member x.LoadProject ( projectFileName : string ) =
238234 x.LoadProject( projectFileName, BinaryLogGeneration.Off)
239235
240236 ///Loads a set of project files
241- member x.LoadWorkspace ( files : string list , binaryLogs : BinaryLogGeneration ) = x.LoaderLoop.Post( files, binaryLogs)
237+ member x.LoadWorkspace ( files : string list , binaryLogs : BinaryLogGeneration ) =
238+ loaderLoop.PostAndAsyncReply(( fun chan -> chan, files, binaryLogs))
242239
243240 ///Loads a set of project files
244241 member x.LoadWorkspace ( files : string list ) =
245242 x.LoadWorkspace( files, BinaryLogGeneration.Off)
246243
247244 ///Finds a list of potential workspaces (solution files/lists of projects) in given dir
248- member __ .PeekWorkspace( dir : string , deep : int , excludedDirs : string list ) =
245+ member _ .PeekWorkspace( dir : string , deep : int , excludedDirs : string list ) =
249246 WorkspacePeek.peek dir deep excludedDirs
250247
251248 interface IDisposable with
0 commit comments