@@ -164,7 +164,7 @@ type internal FSharpProjectOptionsManager
164164 this.AddOrUpdateProject( projectId, ( fun isRefresh ->
165165 let extraProjectInfo = Some( box workspace)
166166 let tryGetOptionsForReferencedProject f = f |> tryGetOrCreateProjectId |> Option.bind this.TryGetOptionsForProject
167- let referencedProjects , options = ProjectSitesAndFiles.GetProjectOptionsForProjectSite( Settings.LanguageServicePerformance.EnableInMemoryCrossProjectReferences, tryGetOptionsForReferencedProject, site, site.ProjectFileName() , extraProjectInfo, serviceProvider, true )
167+ let referencedProjects , options = ProjectSitesAndFiles.GetProjectOptionsForProjectSite( Settings.LanguageServicePerformance.EnableInMemoryCrossProjectReferences, tryGetOptionsForReferencedProject, site, site.ProjectFileName, extraProjectInfo, serviceProvider, true )
168168 let referencedProjectIds = referencedProjects |> Array.choose tryGetOrCreateProjectId
169169 checkerProvider.Checker.InvalidateConfiguration( options, startBackgroundCompileIfAlreadySeen = not isRefresh, userOpName= userOpName + " .UpdateProjectInfo" )
170170 referencedProjectIds, options))
@@ -231,21 +231,22 @@ type internal FSharpProjectOptionsManager
231231 Some( reporter:> Microsoft .VisualStudio .Shell .Interop .IVsLanguageServiceBuildErrorReporter2 )
232232
233233 { new Microsoft.VisualStudio.FSharp.LanguageService.IProjectSite with
234- member __.SourceFilesOnDisk () = this.GetProjectInfo( project.FilePath) |> fst
235- member __.DescriptionOfProject () = project.Name
236- member __.CompilerFlags () =
234+ member __.CompilationSourceFiles = this.GetProjectInfo( project.FilePath) |> fst
235+ member __.CompilationOptions =
237236 let _ , references , options = this.GetProjectInfo( project.FilePath)
238237 Array.concat [ options; references |> Array.map( fun r -> " -r:" + r)]
239- member __.ProjectFileName () = project.FilePath
238+ member __.CompilationReferences = this.GetProjectInfo( project.FilePath) |> thrd
239+ member site.CompilationBinOutputPath = site.CompilationOptions |> Array.tryPick ( fun s -> if s.StartsWith( " -o:" ) then Some s.[ 3 ..] else None)
240+ member __.Description = project.Name
241+ member __.ProjectFileName = project.FilePath
240242 member __.AdviseProjectSiteChanges ( _ , _ ) = ()
241243 member __.AdviseProjectSiteCleaned ( _ , _ ) = ()
242244 member __.AdviseProjectSiteClosed ( _ , _ ) = ()
243245 member __.IsIncompleteTypeCheckEnvironment = false
244246 member __.TargetFrameworkMoniker = " "
245- member __.ProjectGuid = project.Id.Id.ToString()
247+ member __.ProjectGuid = project.Id.Id.ToString()
246248 member __.LoadTime = System.DateTime.Now
247249 member __.ProjectProvider = Some iProvideProjectSite
248- member __.AssemblyReferences () = this.GetProjectInfo( project.FilePath) |> thrd
249250 member __.BuildErrorReporter with get () = errorReporter and
250251 set ( v ) = errorReporter <- v
251252 }
@@ -459,17 +460,20 @@ type
459460
460461 let theme = package.ComponentModel.DefaultExportProvider.GetExport< ISetThemeColors>() .Value
461462 theme.SetColors()
462-
463- /// Sync the information for the project
464- member __.SyncProject ( project : AbstractProject , projectContext : IWorkspaceProjectContext , site : IProjectSite , workspace , forceUpdate , userOpName ) =
463+
464+ /// Sync the Roslyn information for the project held in 'projectContext' to match the information given by 'site'.
465+ /// Also sync the info in ProjectInfoManager if necessary.
466+ member this.SyncProject ( project : AbstractProject , projectContext : IWorkspaceProjectContext , site : IProjectSite , workspace , forceUpdate , userOpName ) =
465467 let wellFormedFilePathSetIgnoreCase ( paths : seq < string >) =
466- HashSet( paths |> Seq.filter isPathWellFormed |> Seq.map ( fun s -> try System.IO.Path.GetFullPath( s) with _ -> s), StringComparer.OrdinalIgnoreCase)
467-
468- let updatedFiles = site.SourceFilesOnDisk() |> wellFormedFilePathSetIgnoreCase
469- let originalFiles = project.GetCurrentDocuments() |> Seq.map ( fun file -> file.FilePath) |> wellFormedFilePathSetIgnoreCase
468+ HashSet( paths |> Seq.filter isPathWellFormed |> Seq.map ( fun s -> try Path.GetFullPath( s) with _ -> s), StringComparer.OrdinalIgnoreCase)
470469
471470 let mutable updated = forceUpdate
472471
472+ // Sync the source files in projectContext. Note that these source files are __not__ maintained in order in projectContext
473+ // as edits are made. It seems this is ok because the source file list is only used to drive roslyn per-file checking.
474+ let updatedFiles = site.CompilationSourceFiles |> wellFormedFilePathSetIgnoreCase
475+ let originalFiles = project.GetCurrentDocuments() |> Seq.map ( fun file -> file.FilePath) |> wellFormedFilePathSetIgnoreCase
476+
473477 for file in updatedFiles do
474478 if not ( originalFiles.Contains( file)) then
475479 projectContext.AddSourceFile( file)
480484 projectContext.RemoveSourceFile( file)
481485 updated <- true
482486
483- let updatedRefs = site.AssemblyReferences () |> wellFormedFilePathSetIgnoreCase
487+ let updatedRefs = site.CompilationReferences |> wellFormedFilePathSetIgnoreCase
484488 let originalRefs = project.GetCurrentMetadataReferences() |> Seq.map ( fun ref -> ref.FilePath) |> wellFormedFilePathSetIgnoreCase
485489
486490 for ref in updatedRefs do
493497 projectContext.RemoveMetadataReference( ref)
494498 updated <- true
495499
500+ // Update the project options association
496501 let ok , originalOptions = optionsAssociation.TryGetValue( projectContext)
497- let updatedOptions = site.CompilerFlags ()
502+ let updatedOptions = site.CompilationOptions
498503 if not ok || originalOptions <> updatedOptions then
499504
500505 // OK, project options have changed, try to fake out Roslyn to convince it to reparse things.
@@ -520,13 +525,12 @@ type
520525 let userOpName = userOpName + " .SetupProjectFile"
521526 let rec setup ( site : IProjectSite ) =
522527 let projectGuid = Guid( site.ProjectGuid)
523- let projectFileName = site.ProjectFileName()
528+ let projectFileName = site.ProjectFileName
524529 let projectDisplayName = projectDisplayNameOf projectFileName
525530
526531 let projectId = workspace.ProjectTracker.GetOrCreateProjectIdForPath( projectFileName, projectDisplayName)
527532
528533 if isNull ( workspace.ProjectTracker.GetProject projectId) then
529- projectInfoManager.UpdateProjectInfo( tryGetOrCreateProjectId workspace, projectId, site, userOpName)
530534 let projectContextFactory = package.ComponentModel.GetService< IWorkspaceProjectContextFactory>();
531535 let errorReporter = ProjectExternalErrorReporter( projectId, " FS" , this.SystemServiceProvider)
532536
@@ -542,27 +546,35 @@ type
542546
543547 let projectContext =
544548 projectContextFactory.CreateProjectContext(
545- FSharpConstants.FSharpLanguageName, projectDisplayName, projectFileName, projectGuid, hierarchy, null , errorReporter)
549+ FSharpConstants.FSharpLanguageName,
550+ projectDisplayName,
551+ projectFileName,
552+ projectGuid,
553+ hierarchy,
554+ Option.toObj site.CompilationBinOutputPath,
555+ errorReporter)
546556
547557 let project = projectContext :?> AbstractProject
548558
549- this.SyncProject( project, projectContext, site, workspace, forceUpdate= false , userOpName= userOpName)
559+ // Sync IProjectSite --> projectContext, and IProjectSite --> ProjectInfoManage
560+ this.SyncProject( project, projectContext, site, workspace, forceUpdate= true , userOpName= userOpName)
550561
551562 site.BuildErrorReporter <- Some ( errorReporter :> Microsoft.VisualStudio.Shell.Interop.IVsLanguageServiceBuildErrorReporter2)
552563
564+ // TODO: consider forceUpdate = false here. forceUpdate=true may be causing repeated computation?
553565 site.AdviseProjectSiteChanges( FSharpConstants.FSharpLanguageServiceCallbackName,
554566 AdviseProjectSiteChanges( fun () -> this.SyncProject( project, projectContext, site, workspace, forceUpdate= true , userOpName= " AdviseProjectSiteChanges." + userOpName)))
567+
555568 site.AdviseProjectSiteClosed( FSharpConstants.FSharpLanguageServiceCallbackName,
556569 AdviseProjectSiteChanges( fun () ->
557570 projectInfoManager.ClearInfoForProject( project.Id)
558571 optionsAssociation.Remove( projectContext) |> ignore
559572 project.Disconnect()))
573+
560574 for referencedSite in ProjectSitesAndFiles.GetReferencedProjectSites ( site, this.SystemServiceProvider) do
561- let referencedProjectId = setup referencedSite
562- project.AddProjectReference( ProjectReference referencedProjectId)
575+ setup referencedSite
563576
564- projectId
565- setup ( siteProvider.GetProjectSite()) |> ignore
577+ setup ( siteProvider.GetProjectSite())
566578
567579 member this.SetupStandAloneFile ( fileName : string , fileContents : string , workspace : VisualStudioWorkspaceImpl , hier : IVsHierarchy ) =
568580 let loadTime = DateTime.Now
0 commit comments