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

Commit95ea82e

Browse files
dungpaKevinRansom
authored andcommitted
Rudimentary support for multi F# projects (dotnet#1990)
* Rudimentary support for multi F# projects* Refactoring* FIx unit tests* Populate Roslyn project references
1 parent389f04f commit95ea82e

File tree

7 files changed

+127
-56
lines changed

7 files changed

+127
-56
lines changed

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

Lines changed: 41 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,8 @@ type internal FSharpCheckerProvider
7676
typeinternalProjectInfoManager
7777
[<ImportingConstructor>]
7878
(
79-
checkerProvider: FSharpCheckerProvider
79+
checkerProvider: FSharpCheckerProvider,
80+
[<Import(typeof<SVsServiceProvider>)>] serviceProvider: System.IServiceProvider
8081
)=
8182
// A table of information about projects, excluding single-file projects.
8283
letprojectTable= ConcurrentDictionary<ProjectId, FSharpProjectOptions>()
@@ -101,16 +102,16 @@ type internal ProjectInfoManager
101102
if SourceFile.MustBeSingleFileProject(fileName)then
102103
let!options= checkerProvider.Checker.GetProjectOptionsFromScript(fileName, fileContents, loadTime,[||], ?extraProjectInfo=extraProjectInfo)
103104
letsite= ProjectSitesAndFiles.CreateProjectSiteForScript(fileName, options)
104-
return ProjectSitesAndFiles.GetProjectOptionsForProjectSite(site,fileName,options.ExtraProjectInfo)
105+
return ProjectSitesAndFiles.GetProjectOptionsForProjectSite(site,fileName,options.ExtraProjectInfo,serviceProvider)
105106
else
106107
letsite= ProjectSitesAndFiles.ProjectSiteOfSingleFile(fileName)
107-
return ProjectSitesAndFiles.GetProjectOptionsForProjectSite(site,fileName,extraProjectInfo)
108+
return ProjectSitesAndFiles.GetProjectOptionsForProjectSite(site,fileName,extraProjectInfo,serviceProvider)
108109
}
109110

110111
/// Update the info for a project in the project table
111112
memberthis.UpdateProjectInfo(projectId:ProjectId,site:IProjectSite,workspace:Workspace)=
112113
letextraProjectInfo= Some(box workspace)
113-
letoptions= ProjectSitesAndFiles.GetProjectOptionsForProjectSite(site, site.ProjectFileName(), extraProjectInfo)
114+
letoptions= ProjectSitesAndFiles.GetProjectOptionsForProjectSite(site, site.ProjectFileName(), extraProjectInfo, serviceProvider)
114115
checkerProvider.Checker.InvalidateConfiguration(options)
115116
projectTable.[projectId]<- options
116117

@@ -230,35 +231,42 @@ type internal FSharpLanguageService(package : FSharpPackage) as this =
230231
projectInfoManager.UpdateProjectInfo(project.Id, site, project.Workspace)
231232

232233
memberthis.SetupProjectFile(siteProvider:IProvideProjectSite,workspace:VisualStudioWorkspaceImpl)=
233-
letsite= siteProvider.GetProjectSite()
234-
letprojectGuid= Guid(site.ProjectGuid)
235-
letprojectFileName= site.ProjectFileName()
236-
237-
letprojectDisplayName=
238-
if String.IsNullOrWhiteSpace projectFileNamethen projectFileName
239-
else Path.GetFileNameWithoutExtension projectFileName
240-
241-
letprojectId= workspace.ProjectTracker.GetOrCreateProjectIdForPath(projectFileName, projectDisplayName)
242-
243-
projectInfoManager.UpdateProjectInfo(projectId, site, workspace)
244-
245-
match workspace.ProjectTracker.GetProject(projectId)with
246-
|null->
247-
letprojectContextFactory= this.Package.ComponentModel.GetService<IWorkspaceProjectContextFactory>();
248-
leterrorReporter= ProjectExternalErrorReporter(projectId,"FS", this.SystemServiceProvider)
249-
250-
251-
252-
letprojectContext=
253-
projectContextFactory.CreateProjectContext(
254-
FSharpCommonConstants.FSharpLanguageName, projectDisplayName, projectFileName, projectGuid, siteProvider,null, errorReporter)
255-
256-
letproject= projectContext:?> AbstractProject
257-
258-
this.SyncProject(project, projectContext, site, forceUpdate=false)
259-
site.AdviseProjectSiteChanges(FSharpCommonConstants.FSharpLanguageServiceCallbackName, AdviseProjectSiteChanges(fun()-> this.SyncProject(project, projectContext, site, forceUpdate=true)))
260-
site.AdviseProjectSiteClosed(FSharpCommonConstants.FSharpLanguageServiceCallbackName, AdviseProjectSiteChanges(fun()-> projectInfoManager.ClearProjectInfo(project.Id); project.Disconnect()))
261-
|_->()
234+
let recsetup(site:IProjectSite)=
235+
letprojectGuid= Guid(site.ProjectGuid)
236+
letprojectFileName= site.ProjectFileName()
237+
238+
letprojectDisplayName=
239+
if String.IsNullOrWhiteSpace projectFileNamethen projectFileName
240+
else Path.GetFileNameWithoutExtension projectFileName
241+
242+
letprojectId= workspace.ProjectTracker.GetOrCreateProjectIdForPath(projectFileName, projectDisplayName)
243+
244+
projectInfoManager.UpdateProjectInfo(projectId, site, workspace)
245+
246+
match workspace.ProjectTracker.GetProject(projectId)with
247+
|null->
248+
letprojectContextFactory= this.Package.ComponentModel.GetService<IWorkspaceProjectContextFactory>();
249+
leterrorReporter= ProjectExternalErrorReporter(projectId,"FS", this.SystemServiceProvider)
250+
251+
letprojectContext=
252+
projectContextFactory.CreateProjectContext(
253+
FSharpCommonConstants.FSharpLanguageName, projectDisplayName, projectFileName, projectGuid, siteProvider,null, errorReporter)
254+
255+
letproject= projectContext:?> AbstractProject
256+
257+
this.SyncProject(project, projectContext, site, forceUpdate=false)
258+
site.AdviseProjectSiteChanges(FSharpCommonConstants.FSharpLanguageServiceCallbackName,
259+
AdviseProjectSiteChanges(fun()-> this.SyncProject(project, projectContext, site, forceUpdate=true)))
260+
site.AdviseProjectSiteClosed(FSharpCommonConstants.FSharpLanguageServiceCallbackName,
261+
AdviseProjectSiteChanges(fun()->
262+
projectInfoManager.ClearProjectInfo(project.Id)
263+
project.Disconnect()))
264+
for referencedSitein ProjectSitesAndFiles.GetReferencedProjectSites(site, this.SystemServiceProvider)do
265+
letreferencedProjectId= setup referencedSite
266+
project.AddProjectReference(ProjectReference referencedProjectId)
267+
|_->()
268+
projectId
269+
setup(siteProvider.GetProjectSite())|> ignore
262270

263271
memberthis.SetupStandAloneFile(fileName:string,fileContents:string,workspace:VisualStudioWorkspaceImpl,hier:IVsHierarchy)=
264272

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ type internal FSharpLanguageServiceBackgroundRequests
8484
// This portion is executed on the UI thread.
8585
letrdt= getServiceProvider().RunningDocumentTable
8686
letprojectSite= getProjectSitesAndFiles().FindOwningProject(rdt,fileName)
87-
letcheckOptions= ProjectSitesAndFiles.GetProjectOptionsForProjectSite(projectSite, fileName, None)
87+
letcheckOptions= ProjectSitesAndFiles.GetProjectOptionsForProjectSite(projectSite, fileName, None, getServiceProvider())
8888
letprojectFileName= projectSite.ProjectFileName()
8989
letdata=
9090
{ ProjectSite= projectSite

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

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,18 @@
33

44
namespaceMicrosoft.VisualStudio.FSharp.LanguageService
55

6+
openSystem
7+
openSystem.Runtime.InteropServices
8+
69
/// Narrow abstraction over the project system.
710
typeinternalAdviseProjectSiteChanges=delegateofunit->unit
811

12+
[<ComImport; InterfaceType(ComInterfaceType.InterfaceIsIUnknown); Guid("ad98f020-bad0-0000-0000-abc037459871")>]
13+
typeinternalIProvideProjectSite=
14+
abstractGetProjectSite :unit->IProjectSite
15+
916
/// Represents known F#-specific information about a project.
10-
typeinternalIProjectSite=
17+
andinternalIProjectSite=
1118

1219
/// List of files in the project. In the correct order.
1320
abstractSourceFilesOnDisk :unit->string[]
@@ -49,3 +56,4 @@ type internal IProjectSite =
4956
/// timestamp the site was last loaded
5057
abstractLoadTime :System.DateTime
5158

59+
abstractProjectProvider :IProvideProjectSiteoption

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

Lines changed: 69 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,6 @@ open Microsoft.FSharp.Compiler.SourceCodeServices
1616
/// already available, so we don't have to recreate it
1717
typeprivateIHaveCheckOptions=
1818
abstractOriginalCheckOptions :unit->FSharpProjectOptions
19-
20-
[<ComImport; InterfaceType(ComInterfaceType.InterfaceIsIUnknown); Guid("ad98f020-bad0-0000-0000-abc037459871")>]
21-
typeinternalIProvideProjectSite=
22-
abstractGetProjectSite :unit->IProjectSite
2319

2420
/// Convert from FSharpProjectOptions into IProjectSite.
2521
typeprivateProjectSiteOfScriptFile(filename:string,checkOptions: FSharpProjectOptions)=
@@ -37,6 +33,7 @@ type private ProjectSiteOfScriptFile(filename:string, checkOptions : FSharpProje
3733
overridethis.TargetFrameworkMoniker=""
3834
overridethis.ProjectGuid=""
3935
overridethis.LoadTime= checkOptions.LoadTime
36+
overridethis.ProjectProvider= None
4037

4138
interface IHaveCheckOptionswith
4239
overridethis.OriginalCheckOptions()= checkOptions
@@ -70,6 +67,7 @@ type private ProjectSiteOfSingleFile(sourceFile) =
7067
overridethis.TargetFrameworkMoniker=""
7168
overridethis.ProjectGuid=""
7269
overridethis.LoadTime=new DateTime(2000,1,1)// any constant time is fine, orphan files do not interact with reloading based on update time
70+
overridethis.ProjectProvider= None
7371

7472
/// Information about projects, open files and other active artifacts in visual studio.
7573
/// Keeps track of the relationship between IVsTextLines buffers, IFSharpSource objects, IProjectSite objects and FSharpProjectOptions
@@ -83,6 +81,64 @@ type internal ProjectSitesAndFiles() =
8381
Some(siteFactory.GetProjectSite())
8482
|_-> None
8583

84+
static letfullOutputAssemblyPath(p:EnvDTE.Project)=
85+
letgetProperty tag=
86+
try Some(p.Properties.[tag].Value.ToString())with_-> None
87+
getProperty"FullPath"
88+
|> Option.bind(fun fullPath->
89+
(try Some(p.ConfigurationManager.ActiveConfiguration.Properties.["OutputPath"].Value.ToString())with_-> None)
90+
|> Option.bind(fun outputPath->
91+
getProperty"OutputFileName"
92+
|> Option.map(fun outputFileName-> Path.Combine(fullPath, outputPath, outputFileName))))
93+
|> Option.bind(fun path->try Some(Path.GetFullPath path)with_-> None)
94+
95+
static letreferencedProjects(projectSite:IProjectSite)=
96+
match projectSite.ProjectProviderwith
97+
| None-> Seq.empty
98+
| Some(:? IVsHierarchyas hier)->
99+
match hier.GetProperty(VSConstants.VSITEMID_ROOT, int__VSHPROPID.VSHPROPID_ExtObject)with
100+
| VSConstants.S_OK,(:? EnvDTE.Projectas p)->
101+
(p.Object:?> VSLangProj.VSProject).References
102+
|> Seq.cast<VSLangProj.Reference>
103+
|> Seq.choose(fun r->
104+
Option.ofObj r
105+
|> Option.bind(fun r->try Option.ofObj r.SourceProjectwith_-> None))
106+
|_-> Seq.empty
107+
| Some_-> Seq.empty
108+
109+
static let recreferencedProvideProjectSites(projectSite:IProjectSite,serviceProvider:System.IServiceProvider)=
110+
letsolutionService=
111+
try Some(serviceProvider.GetService(typeof<SVsSolution>):?> IVsSolution)with_-> None
112+
match solutionServicewith
113+
| Some solutionService->
114+
referencedProjects projectSite
115+
|> Seq.choose(fun p->
116+
match solutionService.GetProjectOfUniqueName(p.UniqueName)with
117+
| VSConstants.S_OK,(:? IProvideProjectSiteas ps)->
118+
Some(p, ps)
119+
|_-> None)
120+
| None-> Seq.empty
121+
122+
static let recreferencedProjectsOf(projectSite:IProjectSite,fileName,extraProjectInfo,serviceProvider:System.IServiceProvider)=
123+
referencedProvideProjectSites(projectSite, serviceProvider)
124+
|> Seq.choose(fun(p,ps)->
125+
fullOutputAssemblyPath p
126+
|> Option.map(fun path->
127+
path, getProjectOptionsForProjectSite(ps.GetProjectSite(), fileName, extraProjectInfo, serviceProvider))
128+
)
129+
|> Seq.toArray
130+
131+
andgetProjectOptionsForProjectSite(projectSite:IProjectSite,fileName,extraProjectInfo,serviceProvider)=
132+
{ProjectFileName= projectSite.ProjectFileName()
133+
ProjectFileNames= projectSite.SourceFilesOnDisk()
134+
OtherOptions= projectSite.CompilerFlags()
135+
ReferencedProjects= referencedProjectsOf(projectSite, fileName, extraProjectInfo, serviceProvider)
136+
IsIncompleteTypeCheckEnvironment= projectSite.IsIncompleteTypeCheckEnvironment
137+
UseScriptResolutionRules= SourceFile.MustBeSingleFileProject fileName
138+
LoadTime= projectSite.LoadTime
139+
UnresolvedReferences= None
140+
ExtraProjectInfo=extraProjectInfo}
141+
86142
/// Construct a project site for a single file. May be a single file project (for scripts) or an orphan project site (for everything else).
87143
static memberProjectSiteOfSingleFile(filename:string):IProjectSite=
88144
if SourceFile.MustBeSingleFileProject(filename)then
@@ -158,23 +214,19 @@ type internal ProjectSitesAndFiles() =
158214
memberart.FindOwningProject(rdt:IVsRunningDocumentTable,filename)=
159215
match art.TryFindOwningProject(rdt, filename)with
160216
| Some site-> site
161-
| None-> ProjectSitesAndFiles.ProjectSiteOfSingleFile(filename)
217+
| None-> ProjectSitesAndFiles.ProjectSiteOfSingleFile(filename)
218+
219+
static memberGetReferencedProjectSites(projectSite:IProjectSite,serviceProvider:System.IServiceProvider)=
220+
referencedProvideProjectSites(projectSite, serviceProvider)
221+
|> Seq.map(fun(_,ps)-> ps.GetProjectSite())
222+
|> Seq.toArray
162223

163224
/// Create project options for this project site.
164-
static memberGetProjectOptionsForProjectSite(projectSite:IProjectSite,filename,extraProjectInfo)=
165-
225+
static memberGetProjectOptionsForProjectSite(projectSite:IProjectSite,filename,extraProjectInfo,serviceProvider:System.IServiceProvider)=
166226
match projectSitewith
167227
|:? IHaveCheckOptionsas hco-> hco.OriginalCheckOptions()
168-
|_->
169-
{ProjectFileName= projectSite.ProjectFileName()
170-
ProjectFileNames= projectSite.SourceFilesOnDisk()
171-
OtherOptions= projectSite.CompilerFlags()
172-
ReferencedProjects=[||]
173-
IsIncompleteTypeCheckEnvironment= projectSite.IsIncompleteTypeCheckEnvironment
174-
UseScriptResolutionRules= SourceFile.MustBeSingleFileProject(filename)
175-
LoadTime= projectSite.LoadTime
176-
UnresolvedReferences= None
177-
ExtraProjectInfo=extraProjectInfo}
228+
|_->
229+
getProjectOptionsForProjectSite(projectSite, filename, extraProjectInfo, serviceProvider)
178230

179231
/// Create project site for these project options
180232
static memberCreateProjectSiteForScript(filename,checkOptions)= ProjectSiteOfScriptFile(filename, checkOptions):> IProjectSite

‎vsintegration/src/FSharp.ProjectSystem.FSharp/Project.fs‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ namespace rec Microsoft.VisualStudio.FSharp.ProjectSystem
9999
memberips.ProjectGuid= inner.ProjectGuid
100100
memberips.IsIncompleteTypeCheckEnvironment=false
101101
memberips.LoadTime= inner.LoadTime
102-
102+
memberips.ProjectProvider= inner.ProjectProvider
103103

104104
typeinternalProjectSiteOptionLifetimeState=
105105
| Opening=1// The project has been opened, but has not yet called Compile() to compute sources/flags
@@ -1446,6 +1446,7 @@ namespace rec Microsoft.VisualStudio.FSharp.ProjectSystem
14461446
memberthis.TargetFrameworkMoniker= x.GetTargetFrameworkMoniker()
14471447
memberthis.ProjectGuid= x.GetProjectGuid()
14481448
memberthis.LoadTime= creationTime
1449+
memberthis.ProjectProvider= Some(x:> IProvideProjectSite)
14491450
}
14501451

14511452
// Snapshot-capture relevent values from "this", and returns an IProjectSite
@@ -1477,6 +1478,7 @@ namespace rec Microsoft.VisualStudio.FSharp.ProjectSystem
14771478
memberthis.TargetFrameworkMoniker= targetFrameworkMoniker
14781479
memberthis.ProjectGuid= x.GetProjectGuid()
14791480
memberthis.LoadTime= creationTime
1481+
memberthis.ProjectProvider= Some(x:> IProvideProjectSite)
14801482
}
14811483

14821484
// let the language service ask us questions

‎vsintegration/tests/Salsa/FSharpLanguageServiceTestable.fs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ type internal FSharpLanguageServiceTestable() as this =
126126

127127
/// Respond to project being cleaned/rebuilt (any live type providers in the project should be refreshed)
128128
memberthis.OnProjectCleaned(projectSite:IProjectSite)=
129-
letcheckOptions= ProjectSitesAndFiles.GetProjectOptionsForProjectSite(projectSite,"",None)
129+
letcheckOptions= ProjectSitesAndFiles.GetProjectOptionsForProjectSite(projectSite,"",None, serviceProvider.Value)
130130
this.FSharpChecker.NotifyProjectCleaned(checkOptions)
131131

132132
memberthis.OnActiveViewChanged(textView)=
@@ -168,7 +168,7 @@ type internal FSharpLanguageServiceTestable() as this =
168168
interface IDependencyFileChangeNotifywith
169169
memberthis.DependencyFileCreated projectSite=
170170
// Invalidate the configuration if we notice any add for any DependencyFiles
171-
letcheckOptions= ProjectSitesAndFiles.GetProjectOptionsForProjectSite(projectSite,"", None)
171+
letcheckOptions= ProjectSitesAndFiles.GetProjectOptionsForProjectSite(projectSite,"", None, this.ServiceProvider)
172172
this.FSharpChecker.InvalidateConfiguration(checkOptions)
173173

174174
memberthis.DependencyFileChanged(filename)=

‎vsintegration/tests/Salsa/salsa.fs‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,8 @@ module internal Salsa =
296296
memberthis.ProjectGuid=
297297
letprojectObj,projectObjFlags= MSBuild.CrackProject(projectfile, configurationFunc(), platformFunc())
298298
projectObj.GetProperty(ProjectFileConstants.ProjectGuid).EvaluatedValue
299-
299+
memberthis.ProjectProvider= None
300+
300301
// Attempt to treat as MSBuild project.
301302
letinternalNewMSBuildProjectSite(configurationFunc,platformFunc,msBuildProjectName)=
302303
letnewProjectSite=new MSBuildProjectSite(msBuildProjectName,configurationFunc,platformFunc)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp