@@ -149,7 +149,7 @@ type internal FSharpProjectOptionsManager
149149 this.AddOrUpdateProject( projectId, ( fun isRefresh ->
150150let extraProjectInfo = Some( box workspace)
151151let tryGetOptionsForReferencedProject f = f|> tryGetOrCreateProjectId|> Option.bind this.TryGetOptionsForProject
152- let referencedProjects , options = ProjectSitesAndFiles.GetProjectOptionsForProjectSite( Settings.LanguageServicePerformance.EnableInMemoryCrossProjectReferences, tryGetOptionsForReferencedProject, site, site.ProjectFileName() , extraProjectInfo, serviceProvider, true )
152+ let referencedProjects , options = ProjectSitesAndFiles.GetProjectOptionsForProjectSite( Settings.LanguageServicePerformance.EnableInMemoryCrossProjectReferences, tryGetOptionsForReferencedProject, site, site.ProjectFileName, extraProjectInfo, serviceProvider, true )
153153let referencedProjectIds = referencedProjects|> Array.choose tryGetOrCreateProjectId
154154 checkerProvider.Checker.InvalidateConfiguration( options, startBackgroundCompileIfAlreadySeen= not isRefresh, userOpName= userOpName+ " .UpdateProjectInfo" )
155155 referencedProjectIds, options))
352352while true do
353353let! siteProvider = inbox.Receive()
354354do ! Async.SwitchToContext ctx
355- this.SetupProjectFile( siteProvider, this.Workspace, " SetupProjectsAfterSolutionOpen" ) }
355+ this.SetupProjectFile( siteProvider, this.Workspace, " SetupProjectsAfterSolutionOpen" )
356+ do ! Async.SwitchToThreadPool()
357+ }
356358
357359use _= Events.SolutionEvents.OnAfterOpenProject|> Observable.subscribe( fun args ->
358360match args.Hierarchywith
@@ -367,41 +369,47 @@ and
367369let theme = package.ComponentModel.DefaultExportProvider.GetExport< ISetThemeColors>() .Value
368370 theme.SetColors()
369371
370- /// Sync the information for the project
371- member this.SyncProject ( project : AbstractProject , projectContext : IWorkspaceProjectContext , site : IProjectSite , workspace , forceUpdate , userOpName ) =
372+ /// Sync the Roslyn information for the project held in 'projectContext' to match the information given by 'site'.
373+ /// Also sync the info in ProjectInfoManager if necessary.
374+ member this.SyncProject ( project : AbstractProject , projectContext : IWorkspaceProjectContext , site : IProjectSite , workspace , userOpName ) =
372375let wellFormedFilePathSetIgnoreCase ( paths : seq < string >) =
373- HashSet( paths|> Seq.filter isPathWellFormed|> Seq.map( fun s -> try System.IO. Path.GetFullPath( s) with _ -> s), StringComparer.OrdinalIgnoreCase)
376+ HashSet( paths|> Seq.filter isPathWellFormed|> Seq.map( fun s -> try Path.GetFullPath( s) with _ -> s), StringComparer.OrdinalIgnoreCase)
374377
375- let updatedFiles = site.SourceFilesOnDisk() |> wellFormedFilePathSetIgnoreCase
378+ // Sync the source files in projectContext. Note that these source files are __not__ maintained in order in projectContext
379+ // as edits are made. It seems this is ok because the source file list is only used to drive roslyn per-file checking.
380+ let updatedFiles = site.CompilationSourceFiles|> wellFormedFilePathSetIgnoreCase
376381let originalFiles = project.GetCurrentDocuments() |> Seq.map( fun file -> file.FilePath) |> wellFormedFilePathSetIgnoreCase
377382
378- let mutable updated = forceUpdate
379-
380383for filein updatedFilesdo
381384if not ( originalFiles.Contains( file)) then
382385 projectContext.AddSourceFile( file)
383- updated<- true
384386
385387for filein originalFilesdo
386388if not ( updatedFiles.Contains( file)) then
387389 projectContext.RemoveSourceFile( file)
388- updated<- true
389390
390- let updatedRefs = site.AssemblyReferences() |> wellFormedFilePathSetIgnoreCase
391+ // Update the output assembly path projectContext.
392+ let updatedBinOutputPath = site.CompilationBinOutputPath|> Option.toObj
393+ let originalBinOutputPath = projectContext.BinOutputPath
394+ if updatedBinOutputPath<> originalBinOutputPaththen
395+ projectContext.BinOutputPath<- updatedBinOutputPath
396+
397+ // Update the metadata/project references in projectContext. Note that AbstractProject.cs converts metadata references
398+ // to project references automagically by consulting the project tracker.
399+ let updatedRefs = site.CompilationReferences|> wellFormedFilePathSetIgnoreCase
391400let originalRefs = project.GetCurrentMetadataReferences() |> Seq.map( fun ref -> ref.FilePath) |> wellFormedFilePathSetIgnoreCase
392401
393402for refin updatedRefsdo
394403if not ( originalRefs.Contains( ref)) then
395404 projectContext.AddMetadataReference( ref, MetadataReferenceProperties.Assembly)
396- updated<- true
397405
398406for refin originalRefsdo
399407if not ( updatedRefs.Contains( ref)) then
400408 projectContext.RemoveMetadataReference( ref)
401- updated<- true
402409
410+ // Update the project options association
403411let ok , originalOptions = optionsAssociation.TryGetValue( projectContext)
404- let updatedOptions = site.CompilerFlags ()
412+ let updatedOptions = site.CompilationOptions
405413if not ok|| originalOptions<> updatedOptionsthen
406414
407415// OK, project options have changed, try to fake out Roslyn to convince it to reparse things.
@@ -417,23 +425,19 @@ and
417425if okthen optionsAssociation.Remove( projectContext) |> ignore
418426 optionsAssociation.Add( projectContext, updatedOptions)
419427
420- updated<- true
421-
422428// update the cached options
423- if updatedthen
424- projectInfoManager.UpdateProjectInfo( tryGetOrCreateProjectId workspace, project.Id, site, project.Workspace, userOpName+ " .SyncProject" )
429+ projectInfoManager.UpdateProjectInfo( tryGetOrCreateProjectId workspace, project.Id, site, project.Workspace, userOpName+ " .SyncProject" )
425430
426431member this.SetupProjectFile ( siteProvider : IProvideProjectSite , workspace : VisualStudioWorkspaceImpl , userOpName ) =
427432let userOpName = userOpName+ " .SetupProjectFile"
428433let rec setup ( site : IProjectSite ) =
429434let projectGuid = Guid( site.ProjectGuid)
430- let projectFileName = site.ProjectFileName()
435+ let projectFileName = site.ProjectFileName
431436let projectDisplayName = projectDisplayNameOf projectFileName
432437
433438let projectId = workspace.ProjectTracker.GetOrCreateProjectIdForPath( projectFileName, projectDisplayName)
434439
435440if isNull( workspace.ProjectTracker.GetProject projectId) then
436- projectInfoManager.UpdateProjectInfo( tryGetOrCreateProjectId workspace, projectId, site, workspace, userOpName)
437441let projectContextFactory = package.ComponentModel.GetService< IWorkspaceProjectContextFactory>();
438442let errorReporter = ProjectExternalErrorReporter( projectId, " FS" , this.SystemServiceProvider)
439443
@@ -449,16 +453,22 @@ and
449453
450454let projectContext =
451455 projectContextFactory.CreateProjectContext(
452- FSharpConstants.FSharpLanguageName, projectDisplayName, projectFileName, projectGuid, hierarchy, null , errorReporter)
456+ FSharpConstants.FSharpLanguageName,
457+ projectDisplayName,
458+ projectFileName,
459+ projectGuid,
460+ hierarchy,
461+ Option.toObj site.CompilationBinOutputPath,
462+ errorReporter)
453463
454464let project = projectContext:?> AbstractProject
455465
456- this.SyncProject( project, projectContext, site, workspace, forceUpdate = false , userOpName= userOpName)
466+ this.SyncProject( project, projectContext, site, workspace, userOpName= userOpName)
457467
458468 site.BuildErrorReporter<- Some( errorReporter:> Microsoft.VisualStudio.Shell.Interop.IVsLanguageServiceBuildErrorReporter2)
459469
460470 site.AdviseProjectSiteChanges( FSharpConstants.FSharpLanguageServiceCallbackName,
461- AdviseProjectSiteChanges( fun () -> this.SyncProject( project, projectContext, site, workspace, forceUpdate = true , userOpName= " AdviseProjectSiteChanges." + userOpName)))
471+ AdviseProjectSiteChanges( fun () -> this.SyncProject( project, projectContext, site, workspace, userOpName= " AdviseProjectSiteChanges." + userOpName)))
462472 site.AdviseProjectSiteClosed( FSharpConstants.FSharpLanguageServiceCallbackName,
463473 AdviseProjectSiteChanges( fun () ->
464474 projectInfoManager.ClearInfoForProject( project.Id)