Skip to content

Commit

Permalink
Stopped querying for projectId based on path; instead, passing projec…
Browse files Browse the repository at this point in the history
…tId itself. This isolates us from roslyn stuff (#5284)
  • Loading branch information
TIHan authored and KevinRansom committed Jul 3, 2018
1 parent 9880cc7 commit 21f9ee4
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,6 @@ type internal FSharpProjectOptionsManager
member this.ComputeSingleFileOptions (tryGetOrCreateProjectId, fileName, loadTime, fileContents) =
async {
let extraProjectInfo = Some(box workspace)
let tryGetOptionsForReferencedProject f = f |> tryGetOrCreateProjectId |> Option.bind this.TryGetOptionsForProject |> Option.map(fun (_, _, projectOptions) -> projectOptions)
if SourceFile.MustBeSingleFileProject(fileName) then
// NOTE: we don't use a unique stamp for single files, instead comparing options structurally.
// This is because we repeatedly recompute the options.
Expand All @@ -159,12 +158,12 @@ type internal FSharpProjectOptionsManager
// compiled and #r will refer to files on disk
let referencedProjectFileNames = [| |]
let site = ProjectSitesAndFiles.CreateProjectSiteForScript(fileName, referencedProjectFileNames, options)
let deps, projectOptions = ProjectSitesAndFiles.GetProjectOptionsForProjectSite(Settings.LanguageServicePerformance.EnableInMemoryCrossProjectReferences, tryGetOptionsForReferencedProject, site, serviceProvider, (tryGetOrCreateProjectId fileName), fileName, options.ExtraProjectInfo, Some projectOptionsTable)
let deps, projectOptions = ProjectSitesAndFiles.GetProjectOptionsForProjectSite(Settings.LanguageServicePerformance.EnableInMemoryCrossProjectReferences, site, serviceProvider, (tryGetOrCreateProjectId fileName), fileName, options.ExtraProjectInfo, Some projectOptionsTable)
let parsingOptions, _ = checkerProvider.Checker.GetParsingOptionsFromProjectOptions(projectOptions)
return (deps, parsingOptions, projectOptions)
else
let site = ProjectSitesAndFiles.ProjectSiteOfSingleFile(fileName)
let deps, projectOptions = ProjectSitesAndFiles.GetProjectOptionsForProjectSite(Settings.LanguageServicePerformance.EnableInMemoryCrossProjectReferences, tryGetOptionsForReferencedProject, site, serviceProvider, (tryGetOrCreateProjectId fileName), fileName, extraProjectInfo, Some projectOptionsTable)
let deps, projectOptions = ProjectSitesAndFiles.GetProjectOptionsForProjectSite(Settings.LanguageServicePerformance.EnableInMemoryCrossProjectReferences, site, serviceProvider, (tryGetOrCreateProjectId fileName), fileName, extraProjectInfo, Some projectOptionsTable)
let parsingOptions, _ = checkerProvider.Checker.GetParsingOptionsFromProjectOptions(projectOptions)
return (deps, parsingOptions, projectOptions)
}
Expand All @@ -174,8 +173,7 @@ type internal FSharpProjectOptionsManager
Logger.Log LogEditorFunctionId.LanguageService_UpdateProjectInfo
projectOptionsTable.AddOrUpdateProject(projectId, (fun isRefresh ->
let extraProjectInfo = Some(box workspace)
let tryGetOptionsForReferencedProject f = f |> tryGetOrCreateProjectId |> Option.bind this.TryGetOptionsForProject |> Option.map(fun (_, _, projectOptions) -> projectOptions)
let referencedProjects, projectOptions = ProjectSitesAndFiles.GetProjectOptionsForProjectSite(Settings.LanguageServicePerformance.EnableInMemoryCrossProjectReferences, tryGetOptionsForReferencedProject, site, serviceProvider, Some(projectId), site.ProjectFileName, extraProjectInfo, Some projectOptionsTable)
let referencedProjects, projectOptions = ProjectSitesAndFiles.GetProjectOptionsForProjectSite(Settings.LanguageServicePerformance.EnableInMemoryCrossProjectReferences, site, serviceProvider, Some(projectId), site.ProjectFileName, extraProjectInfo, Some projectOptionsTable)
if invalidateConfig then checkerProvider.Checker.InvalidateConfiguration(projectOptions, startBackgroundCompileIfAlreadySeen = not isRefresh, userOpName = userOpName + ".UpdateProjectInfo")
let referencedProjectIds = referencedProjects |> Array.choose tryGetOrCreateProjectId
let parsingOptions, _ = checkerProvider.Checker.GetParsingOptionsFromProjectOptions(projectOptions)
Expand Down Expand Up @@ -610,7 +608,7 @@ type internal FSharpLanguageService(package : FSharpPackage) =
optionsAssociation.Remove(projectContext) |> ignore
project.Disconnect()))

for referencedSite in ProjectSitesAndFiles.GetReferencedProjectSites(site, this.SystemServiceProvider, Some (this.Workspace :>obj), Some projectInfoManager.FSharpOptions ) do
for referencedSite in ProjectSitesAndFiles.GetReferencedProjectSites(Some projectId, site, this.SystemServiceProvider, Some (this.Workspace :>obj), Some projectInfoManager.FSharpOptions ) do
setup referencedSite

setup (siteProvider.GetProjectSite())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -221,23 +221,25 @@ type internal ProjectSitesAndFiles() =
| _ -> None
| Some _ -> None

static let rec referencedProvideProjectSites(projectSite:IProjectSite, serviceProvider:System.IServiceProvider, extraProjectInfo:obj option, projectOptionsTable:FSharpProjectOptionsTable option) =
static let rec referencedProvideProjectSites(projectIdOpt: ProjectId option, projectSite:IProjectSite, serviceProvider:System.IServiceProvider, extraProjectInfo:obj option, projectOptionsTable:FSharpProjectOptionsTable option) =
let getReferencesForSolutionService (solutionService:IVsSolution) =
[|
match referencedProjects projectSite, extraProjectInfo with
| None, Some (:? VisualStudioWorkspaceImpl as workspace) when not (isNull workspace.CurrentSolution)->
let path = projectSite.ProjectFileName
if not (String.IsNullOrWhiteSpace(path)) then
let projectId = workspace.ProjectTracker.GetOrCreateProjectIdForPath(path, projectDisplayNameOf path)
let project = workspace.CurrentSolution.GetProject(projectId)
if not (isNull project) then
for reference in project.ProjectReferences do
let project = workspace.CurrentSolution.GetProject(reference.ProjectId)
if not (isNull project) && project.Language = FSharpConstants.FSharpLanguageName then
let siteProvider = provideProjectSiteProvider (workspace, project, serviceProvider, projectOptionsTable)
let referenceProject = workspace.ProjectTracker.GetProject(reference.ProjectId)
let outputPath = referenceProject.BinOutputPath
yield Some projectId, project.FilePath, outputPath, siteProvider
match projectIdOpt with
| Some(projectId) ->
let project = workspace.CurrentSolution.GetProject(projectId)
if not (isNull project) then
for reference in project.ProjectReferences do
let project = workspace.CurrentSolution.GetProject(reference.ProjectId)
if not (isNull project) && project.Language = FSharpConstants.FSharpLanguageName then
let siteProvider = provideProjectSiteProvider (workspace, project, serviceProvider, projectOptionsTable)
let referenceProject = workspace.ProjectTracker.GetProject(reference.ProjectId)
let outputPath = referenceProject.BinOutputPath
yield Some project.Id, project.FilePath, outputPath, siteProvider
| _ -> ()

| (Some references), _ ->
for p in references do
Expand All @@ -255,26 +257,33 @@ type internal ProjectSitesAndFiles() =
| None -> ()
}

static let rec referencedProjectsOf(enableInMemoryCrossProjectReferences, tryGetOptionsForReferencedProject, projectSite, serviceProvider, extraProjectInfo, projectOptionsTable) =
[| for (projectId, projectFileName, outputPath, projectSiteProvider) in referencedProvideProjectSites (projectSite, serviceProvider, extraProjectInfo, projectOptionsTable) do
let referencedProjectOptions =
// Lookup may not succeed if the project has not been established yet
// In this case we go and compute the options recursively.
match tryGetOptionsForReferencedProject projectFileName with
| None -> getProjectOptionsForProjectSite (enableInMemoryCrossProjectReferences, tryGetOptionsForReferencedProject, projectSiteProvider.GetProjectSite(), serviceProvider, projectId, projectFileName, extraProjectInfo, projectOptionsTable) |> snd
| Some options -> options
yield projectFileName, (outputPath, referencedProjectOptions) |]

and getProjectOptionsForProjectSite(enableInMemoryCrossProjectReferences, tryGetOptionsForReferencedProject, projectSite, serviceProvider, projectId, fileName, extraProjectInfo, projectOptionsTable) =
static let rec referencedProjectsOf(projectIdOpt, projectSite, serviceProvider, extraProjectInfo, projectOptionsTable) =
[| for (projectIdOpt, projectFileName, outputPath, _projectSiteProvider) in referencedProvideProjectSites (projectIdOpt, projectSite, serviceProvider, extraProjectInfo, projectOptionsTable) do
let referencedProjectOptionsOpt =
projectOptionsTable
|> Option.bind (fun x ->
match projectIdOpt with
| Some(projectId) -> x.TryGetOptionsForProject(projectId)
| _ -> None
)
|> Option.map (fun (_, _, options) -> options)

match referencedProjectOptionsOpt with
| Some(referencedProjectOptions) ->
yield projectFileName, (outputPath, referencedProjectOptions)
| _ -> ()
|]

and getProjectOptionsForProjectSite(enableInMemoryCrossProjectReferences, projectSite, serviceProvider, projectIdOpt, fileName, extraProjectInfo, projectOptionsTable) =
let referencedProjectFileNames, referencedProjectOptions =
if enableInMemoryCrossProjectReferences then
referencedProjectsOf(enableInMemoryCrossProjectReferences, tryGetOptionsForReferencedProject, projectSite, serviceProvider, extraProjectInfo, projectOptionsTable)
referencedProjectsOf(projectIdOpt, projectSite, serviceProvider, extraProjectInfo, projectOptionsTable)
|> Array.unzip
else [| |], [| |]
let option =
let newOption () = {
ProjectFileName = projectSite.ProjectFileName
ProjectId = projectId |> Option.map (fun x -> x.ToFSharpProjectIdString())
ProjectId = projectIdOpt |> Option.map (fun x -> x.ToFSharpProjectIdString())
SourceFiles = projectSite.CompilationSourceFiles
OtherOptions = projectSite.CompilationOptions
ReferencedProjects = referencedProjectOptions
Expand All @@ -286,7 +295,7 @@ type internal ProjectSitesAndFiles() =
ExtraProjectInfo=extraProjectInfo
Stamp = (stamp <- stamp + 1L; Some stamp)
}
match projectId, projectOptionsTable with
match projectIdOpt, projectOptionsTable with
| Some id, Some optionsTable ->
// Get options from cache
match optionsTable.TryGetOptionsForProject(id) with
Expand All @@ -308,16 +317,16 @@ type internal ProjectSitesAndFiles() =
failwith ".fsx or .fsscript should have been treated as implicit project"
new ProjectSiteOfSingleFile(filename) :> IProjectSite

static member GetReferencedProjectSites(projectSite:IProjectSite, serviceProvider:System.IServiceProvider, extraProjectInfo, projectOptions) =
referencedProvideProjectSites (projectSite, serviceProvider, extraProjectInfo, projectOptions)
static member GetReferencedProjectSites(projectIdOpt, projectSite:IProjectSite, serviceProvider:System.IServiceProvider, extraProjectInfo, projectOptions) =
referencedProvideProjectSites (projectIdOpt, projectSite, serviceProvider, extraProjectInfo, projectOptions)
|> Seq.map (fun (_, _, _, ps) -> ps.GetProjectSite())
|> Seq.toArray

/// Create project options for this project site.
static member GetProjectOptionsForProjectSite(enableInMemoryCrossProjectReferences, tryGetOptionsForReferencedProject, projectSite:IProjectSite, serviceProvider, projectId, filename, extraProjectInfo, projectOptionsTable) =
static member GetProjectOptionsForProjectSite(enableInMemoryCrossProjectReferences, projectSite:IProjectSite, serviceProvider, projectId, filename, extraProjectInfo, projectOptionsTable) =
match projectSite with
| :? IHaveCheckOptions as hco -> hco.OriginalCheckOptions()
| _ -> getProjectOptionsForProjectSite(enableInMemoryCrossProjectReferences, tryGetOptionsForReferencedProject, projectSite, serviceProvider, projectId, filename, extraProjectInfo, projectOptionsTable)
| _ -> getProjectOptionsForProjectSite(enableInMemoryCrossProjectReferences, projectSite, serviceProvider, projectId, filename, extraProjectInfo, projectOptionsTable)

/// Create project site for these project options
static member CreateProjectSiteForScript (filename, referencedProjectFileNames, checkOptions) =
Expand Down

0 comments on commit 21f9ee4

Please sign in to comment.