Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit15d9391

Browse files
jasonmalinowskiTIHan
authored andcommitted
Decouple the F# language service from AbstractProject (#5553)
The F# language service presumed that IWorkspaceProjectContextis implemented by an AbstractProject, which is an assumption that isn'tsafe going forward. This removes that presumption, and tweaks a fewother things that should allow F# to continue to function once wefurther refactor the project system work in Roslyn.
1 parente4012ad commit15d9391

File tree

1 file changed

+32
-25
lines changed

1 file changed

+32
-25
lines changed

‎vsintegration/src/FSharp.Editor/LanguageService/LanguageService.fs‎

Lines changed: 32 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -408,13 +408,13 @@ type internal FSharpLanguageService(package : FSharpPackage) =
408408
if String.IsNullOrWhiteSpace projectFileNamethen projectFileName
409409
else Path.GetFileNameWithoutExtension projectFileName
410410

411-
letsingleFileProjects= ConcurrentDictionary<_,AbstractProject>()
411+
letsingleFileProjects= ConcurrentDictionary<_,IWorkspaceProjectContext>()
412412

413413
lettryRemoveSingleFileProject projectId=
414414
match singleFileProjects.TryRemove(projectId)with
415415
|true, project->
416416
projectInfoManager.ClearInfoForSingleFileProject(projectId)
417-
project.Disconnect()
417+
project.Dispose()
418418
|_->()
419419

420420
letinvalidPathChars= set(Path.GetInvalidPathChars())
@@ -501,16 +501,18 @@ type internal FSharpLanguageService(package : FSharpPackage) =
501501

502502
/// Sync the Roslyn information for the project held in 'projectContext' to match the information given by 'site'.
503503
/// Also sync the info in ProjectInfoManager if necessary.
504-
memberthis.SyncProject(project:AbstractProject,projectContext:IWorkspaceProjectContext,site:IProjectSite,workspace,forceUpdate,userOpName)=
504+
memberthis.SyncProject(projectContext:IWorkspaceProjectContext,site:IProjectSite,workspace:VisualStudioWorkspaceImpl,forceUpdate,userOpName)=
505505
letwellFormedFilePathSetIgnoreCase(paths:seq<string>)=
506506
HashSet(paths|> Seq.filter isPathWellFormed|> Seq.map(fun s->try Path.GetFullPath(s)with_-> s), StringComparer.OrdinalIgnoreCase)
507507

508508
let mutableupdated= forceUpdate
509509

510+
letproject= workspace.CurrentSolution.Projects|> Seq.filter(fun p-> p.Name= projectContext.DisplayName)|> Seq.exactlyOne
511+
510512
// Sync the source files in projectContext. Note that these source files are __not__ maintained in order in projectContext
511513
// as edits are made. It seems this is ok because the source file list is only used to drive roslyn per-file checking.
512514
letupdatedFiles= site.CompilationSourceFiles|> wellFormedFilePathSetIgnoreCase
513-
letoriginalFiles= project.GetCurrentDocuments()|> Seq.map(fun file-> file.FilePath)|> wellFormedFilePathSetIgnoreCase
515+
letoriginalFiles= project.Documents|> Seq.map(fun file-> file.FilePath)|> wellFormedFilePathSetIgnoreCase
514516

515517
for filein updatedFilesdo
516518
ifnot(originalFiles.Contains(file))then
@@ -523,7 +525,7 @@ type internal FSharpLanguageService(package : FSharpPackage) =
523525
updated<-true
524526

525527
letupdatedRefs= site.CompilationReferences|> wellFormedFilePathSetIgnoreCase
526-
letoriginalRefs= project.GetCurrentMetadataReferences()|> Seq.map(fun ref-> ref.FilePath)|> wellFormedFilePathSetIgnoreCase
528+
letoriginalRefs= project.MetadataReferences|> Enumerable.OfType<PortableExecutableReference>|> Seq.map(fun ref-> ref.FilePath)|> wellFormedFilePathSetIgnoreCase
527529

528530
for refin updatedRefsdo
529531
ifnot(originalRefs.Contains(ref))then
@@ -566,11 +568,14 @@ type internal FSharpLanguageService(package : FSharpPackage) =
566568
letprojectFileName= site.ProjectFileName
567569
letprojectDisplayName= projectDisplayNameOf projectFileName
568570

569-
letprojectId= workspace.ProjectTracker.GetOrCreateProjectIdForPath(projectFileName, projectDisplayName)
571+
// This projectId is not guaranteed to be the same ProjectId that will actually be created once we call CreateProjectContext
572+
// in Roslyn versions once https://github.com/dotnet/roslyn/pull/26931 is merged. Roslyn will still guarantee that once
573+
// there is a project in the workspace with the same path, it'll return the ID of that. So this is sufficient to use
574+
// in that case as long as we only use it to call GetProject.
575+
letfakeProjectId= workspace.ProjectTracker.GetOrCreateProjectIdForPath(projectFileName, projectDisplayName)
570576

571-
if isNull(workspace.ProjectTracker.GetProjectprojectId)then
577+
if isNull(workspace.ProjectTracker.GetProjectfakeProjectId)then
572578
letprojectContextFactory= package.ComponentModel.GetService<IWorkspaceProjectContextFactory>();
573-
leterrorReporter= ProjectExternalErrorReporter(projectId,"FS", this.SystemServiceProvider)
574579

575580
lethierarchy=
576581
site.ProjectProvider
@@ -589,27 +594,27 @@ type internal FSharpLanguageService(package : FSharpPackage) =
589594
projectFileName,
590595
projectGuid,
591596
hierarchy,
592-
Option.toObj site.CompilationBinOutputPath,
593-
errorReporter)
594-
595-
letproject=projectContext:?> AbstractProject
597+
Option.toObj site.CompilationBinOutputPath)
598+
599+
// The real project ID that was actually added. See comments for fakeProjectId why this one is actually good.
600+
letrealProjectId=workspace.ProjectTracker.GetOrCreateProjectIdForPath(projectFileName, projectDisplayName)
596601

597602
// Sync IProjectSite --> projectContext, and IProjectSite --> ProjectInfoManage
598-
this.SyncProject(project,projectContext, site, workspace, forceUpdate=true, userOpName=userOpName)
603+
this.SyncProject(projectContext, site, workspace, forceUpdate=true, userOpName=userOpName)
599604

600-
site.BuildErrorReporter<- Some(errorReporter:> Microsoft.VisualStudio.Shell.Interop.IVsLanguageServiceBuildErrorReporter2)
605+
site.BuildErrorReporter<- Some(projectContext:?> Microsoft.VisualStudio.Shell.Interop.IVsLanguageServiceBuildErrorReporter2)
601606

602607
// TODO: consider forceUpdate = false here. forceUpdate=true may be causing repeated computation?
603608
site.AdviseProjectSiteChanges(FSharpConstants.FSharpLanguageServiceCallbackName,
604-
AdviseProjectSiteChanges(fun()-> this.SyncProject(project,projectContext, site, workspace, forceUpdate=true, userOpName="AdviseProjectSiteChanges."+userOpName)))
609+
AdviseProjectSiteChanges(fun()-> this.SyncProject(projectContext, site, workspace, forceUpdate=true, userOpName="AdviseProjectSiteChanges."+userOpName)))
605610

606611
site.AdviseProjectSiteClosed(FSharpConstants.FSharpLanguageServiceCallbackName,
607612
AdviseProjectSiteChanges(fun()->
608-
projectInfoManager.ClearInfoForProject(project.Id)
613+
projectInfoManager.ClearInfoForProject(realProjectId)
609614
optionsAssociation.Remove(projectContext)|> ignore
610-
project.Disconnect()))
615+
projectContext.Dispose()))
611616

612-
for referencedSitein ProjectSitesAndFiles.GetReferencedProjectSites(SomeprojectId, site, this.SystemServiceProvider, Some(this.Workspace:>obj), Some projectInfoManager.FSharpOptions)do
617+
for referencedSitein ProjectSitesAndFiles.GetReferencedProjectSites(SomerealProjectId, site, this.SystemServiceProvider, Some(this.Workspace:>obj), Some projectInfoManager.FSharpOptions)do
613618
setup referencedSite
614619

615620
setup(siteProvider.GetProjectSite())
@@ -619,19 +624,21 @@ type internal FSharpLanguageService(package : FSharpPackage) =
619624
letprojectFileName= fileName
620625
letprojectDisplayName= projectDisplayNameOf projectFileName
621626

622-
letprojectId= workspace.ProjectTracker.GetOrCreateProjectIdForPath(projectFileName, projectDisplayName)
623-
let_referencedProjectFileNames,parsingOptions,projectOptions= projectInfoManager.ComputeSingleFileOptions(tryGetOrCreateProjectId workspace, fileName, loadTime, fileContents)|> Async.RunSynchronously
624-
projectInfoManager.AddOrUpdateSingleFileProject(projectId,(loadTime, parsingOptions, projectOptions))
627+
let mutableprojectId= workspace.ProjectTracker.GetOrCreateProjectIdForPath(projectFileName, projectDisplayName)
625628

626629
if isNull(workspace.ProjectTracker.GetProject projectId)then
627630
letprojectContextFactory= package.ComponentModel.GetService<IWorkspaceProjectContextFactory>();
628-
leterrorReporter= ProjectExternalErrorReporter(projectId,"FS", this.SystemServiceProvider)
629631

630-
letprojectContext= projectContextFactory.CreateProjectContext(FSharpConstants.FSharpLanguageName, projectDisplayName, projectFileName, projectId.Id, hier,null, errorReporter)
632+
letprojectContext= projectContextFactory.CreateProjectContext(FSharpConstants.FSharpLanguageName, projectDisplayName, projectFileName, projectId.Id, hier,null)
633+
634+
projectId<- workspace.ProjectTracker.GetOrCreateProjectIdForPath(projectFileName, projectDisplayName)
635+
631636
projectContext.AddSourceFile(fileName)
632637

633-
letproject= projectContext:?> AbstractProject
634-
singleFileProjects.[projectId]<- project
638+
singleFileProjects.[projectId]<- projectContext
639+
640+
let_referencedProjectFileNames,parsingOptions,projectOptions= projectInfoManager.ComputeSingleFileOptions(tryGetOrCreateProjectId workspace, fileName, loadTime, fileContents)|> Async.RunSynchronously
641+
projectInfoManager.AddOrUpdateSingleFileProject(projectId,(loadTime, parsingOptions, projectOptions))
635642

636643
overridethis.ContentTypeName= FSharpConstants.FSharpContentTypeName
637644
overridethis.LanguageName= FSharpConstants.FSharpLanguageName

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp