未验证 提交 351d06b6 编写于 作者: P Phillip Carter 提交者: GitHub

Remove dependency on FSharp.LanguageService (#4108)

* Move ProjectSitesAndFiles to FSharp.Editor

* Remove commented out code

* Fix build that wasn't reported when running build.cmd

* Remove weird stuff and add the VSLang proj reference like it is in FSharp.LanguageService

* Remove dependency on FSharp.LanguageService

* remove commented out reference
上级 9333b068
......@@ -14,7 +14,6 @@ open Microsoft.FSharp.Compiler
open Microsoft.FSharp.Compiler.Layout
open Microsoft.FSharp.Compiler.SourceCodeServices
open Microsoft.FSharp.Compiler.Range
open Microsoft.VisualStudio.FSharp.LanguageService
[<RequireQualifiedAccess>]
module internal RoslynHelpers =
......
......@@ -3,16 +3,84 @@
namespace Microsoft.VisualStudio.FSharp.Editor
open System
open System.Runtime.InteropServices
open Microsoft.VisualStudio
open Microsoft.VisualStudio.Editor
open Microsoft.VisualStudio.Shell.Interop
open Microsoft.VisualStudio.TextManager.Interop
/// Helper methods for interoperating with COM
module internal Com =
let ThrowOnFailure0(hr) =
ErrorHandler.ThrowOnFailure(hr) |> ignore
let ThrowOnFailure1(hr,res) =
ErrorHandler.ThrowOnFailure(hr) |> ignore;
res
let ThrowOnFailure2(hr,res1,res2) =
ErrorHandler.ThrowOnFailure(hr) |> ignore;
res1,res2
let ThrowOnFailure3(hr,res1,res2,res3) =
ErrorHandler.ThrowOnFailure(hr) |> ignore;
res1,res2,res3
let ThrowOnFailure4(hr,res1,res2,res3,res4) =
ErrorHandler.ThrowOnFailure(hr) |> ignore;
res1,res2,res3,res4
let Succeeded hr =
// REVIEW: Not the correct check for succeeded
hr = VSConstants.S_OK
module internal VsUserData =
let vsBufferMoniker = Guid("978A8E17-4DF8-432A-9623-D530A26452BC")
// This is the file name of the buffer.
let GetBufferMonker(ud:IVsUserData) : string =
downcast Com.ThrowOnFailure1(ud.GetData(ref vsBufferMoniker))
module internal VsTextLines =
/// Get the length of the given line.
let LengthOfLine (buffer:IVsTextBuffer) (line:int) : int =
Com.ThrowOnFailure1(buffer.GetLengthOfLine(line))
/// Get the text for a particular line.
let LineText (buffer:IVsTextLines) line =
Com.ThrowOnFailure1(buffer.GetLineText(line, 0, line, LengthOfLine buffer line))
/// Get the color state
let TextColorState (buffer:IVsTextLines) : IVsTextColorState= unbox(box(buffer))
/// Get the filename of the given buffer (via IVsUserData). Not all buffers have a file. This will be an exception.
let GetFilename(buffer : IVsTextLines) =
let ud = (box buffer) :?> IVsUserData
VsUserData.GetBufferMonker(ud)
/// Get the string contents of a given buffer (the current snapshot).
let GetFileContents(buffer: IVsTextBuffer, editorAdaptersFactoryService: IVsEditorAdaptersFactoryService) =
let dataBuffer = editorAdaptersFactoryService.GetDataBuffer(buffer)
dataBuffer.CurrentSnapshot.GetText()
module internal VsRunningDocumentTable =
let FindDocumentWithoutLocking(rdt:IVsRunningDocumentTable, url:string) : (IVsHierarchy * IVsTextLines) option =
let (hr:int, hier:IVsHierarchy, _itemid:uint32, unkData:IntPtr, _cookie:uint32) = rdt.FindAndLockDocument(uint32 _VSRDTFLAGS.RDT_NoLock, url)
try
if Com.Succeeded(hr) then
let bufferObject =
if unkData=IntPtr.Zero then null
else Marshal.GetObjectForIUnknown(unkData)
let buffer =
match bufferObject with
| :? IVsTextLines as tl -> tl
| _ -> null
Some(hier, buffer)
else None
finally
if IntPtr.Zero <> unkData then Marshal.Release(unkData)|>ignore
[<AutoOpen>]
module internal ServiceProviderExtensions =
type internal System.IServiceProvider with
......
......@@ -32,8 +32,6 @@
<InternalsVisibleTo Include="FSharp.ProjectSystem.FSharp" />
<InternalsVisibleTo Include="VisualFSharp.UnitTests" />
<InternalsVisibleTo Include="VisualFSharp.Salsa" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="FSharp.Editor.resx">
<GenerateSource>true</GenerateSource>
<GeneratedModuleName>Microsoft.VisualStudio.FSharp.Editor.SR</GeneratedModuleName>
......@@ -42,11 +40,11 @@
<Compile Include="Common\Pervasive.fs" />
<Compile Include="Common\Extensions.fs" />
<Compile Include="Common\Constants.fs" />
<Compile Include="Common\Error.fs" />
<Compile Include="Common\Logging.fs" />
<Compile Include="Common\RoslynHelpers.fs" />
<Compile Include="Common\CodeAnalysisExtensions.fs" />
<Compile Include="Common\ContentType.fs" />
<Compile Include="Common\Error.fs" />
<Compile Include="Common\Vs.fs" />
<Compile Include="Options\SettingsPersistence.fs" />
<Compile Include="Options\UIHelpers.fs" />
......@@ -54,6 +52,8 @@
<Compile Include="LanguageService\Tokenizer.fs" />
<Compile Include="LanguageService\Symbols.fs" />
<Compile Include="LanguageService\FSharpCheckerExtensions.fs" />
<Compile Include="LanguageService\IProjectSite.fs" />
<Compile Include="LanguageService\ProjectSitesAndFiles.fs" />
<Compile Include="LanguageService\LanguageService.fs" />
<Compile Include="LanguageService\AssemblyContentProvider.fs" />
<Compile Include="LanguageService\SymbolHelpers.fs" />
......@@ -107,11 +107,6 @@
<Project>{DED3BBD7-53F4-428A-8C9F-27968E768605}</Project>
<Name>FSharp.Core</Name>
</ProjectReference>
<ProjectReference Include="$(FSharpSourcesRoot)\..\vsintegration\src\FSharp.LanguageService\FSharp.LanguageService.fsproj">
<Name>FSharp.LanguageService</Name>
<Project>{ee85aab7-cda0-4c4e-bda0-a64ccc413e3f}</Project>
<Private>True</Private>
</ProjectReference>
<ProjectReference Include="$(FSharpSourcesRoot)\..\vsintegration\src\FSharp.LanguageService.Base\FSharp.LanguageService.Base.csproj">
<Name>FSharp.LanguageService.Base</Name>
<Project>{1c5c163c-37ea-4a3c-8ccc-0d34b74bf8ef}</Project>
......@@ -132,8 +127,6 @@
<Project>{991dcf75-c2eb-42b6-9a0d-aa1d2409d519}</Project>
<Private>True</Private>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Reference Include="mscorlib" />
<Reference Include="PresentationFramework" />
<Reference Include="System.Windows.Forms" />
......@@ -146,8 +139,6 @@
<Reference Include="System" />
<Reference Include="PresentationCore" />
<Reference Include="System.ComponentModel.Composition" />
</ItemGroup>
<ItemGroup>
<Reference Include="EnvDTE">
<HintPath>$(FSharpSourcesRoot)\..\packages\EnvDTE.8.0.1\lib\net10\EnvDTE.dll</HintPath>
<Private>True</Private>
......@@ -156,6 +147,10 @@
<HintPath>$(FSharpSourcesRoot)\..\packages\EnvDTE80.8.0.1\lib\net10\EnvDTE80.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="VSLangProj">
<HintPath>$(FSharpSourcesRoot)\..\packages\VSSDK.VSLangProj.7.0.4\lib\net20\VSLangProj.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.VisualStudio.Threading">
<HintPath>$(FSharpSourcesRoot)\..\packages\Microsoft.VisualStudio.Threading.$(MicrosoftVisualStudioThreadingVersion)\lib\net45\Microsoft.VisualStudio.Threading.dll</HintPath>
</Reference>
......
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
namespace Microsoft.VisualStudio.FSharp.Editor
open System.Runtime.InteropServices
/// Narrow abstraction over the project system.
type internal AdviseProjectSiteChanges = delegate of unit -> unit
[<ComImport; InterfaceType(ComInterfaceType.InterfaceIsIUnknown); Guid("ad98f020-bad0-0000-0000-abc037459871")>]
type internal IProvideProjectSite =
abstract GetProjectSite : unit -> IProjectSite
/// Represents known F#-specific information about a project.
and internal IProjectSite =
/// List of files in the project. In the correct order.
abstract CompilationSourceFiles : string[]
/// Flags that the compiler would need to understand how to compile. Includes '-r'
/// options but not source files
abstract CompilationOptions : string[]
/// The normalized '-r:' assembly references, without the '-r:'
abstract CompilationReferences : string []
/// The '-o:' output bin path, without the '-o:'
abstract CompilationBinOutputPath : string option
/// The name of the project file.
abstract ProjectFileName : string
/// Register for notifications for when the above change
abstract AdviseProjectSiteChanges : callbackOwnerKey: string * AdviseProjectSiteChanges -> unit
/// Register for notifications when project is cleaned/rebuilt (and thus any live TypeProviders should be refreshed)
abstract AdviseProjectSiteCleaned : callbackOwnerKey: string * AdviseProjectSiteChanges -> unit
// Register for notifications when project is closed.
abstract AdviseProjectSiteClosed : callbackOwnerKey: string * AdviseProjectSiteChanges -> unit
/// A user-friendly description of the project. Used only for developer/DEBUG tooltips and such.
abstract Description : string
/// The error list task reporter
abstract BuildErrorReporter : Microsoft.VisualStudio.Shell.Interop.IVsLanguageServiceBuildErrorReporter2 option with get, set
/// False type resolution errors are invalid. This occurs with orphaned source files. The prior
/// type checking state is unknown. In this case we don't want to squiggle the type checking files.
abstract IsIncompleteTypeCheckEnvironment : bool
/// target framework moniker
abstract TargetFrameworkMoniker : string
/// Project Guid
abstract ProjectGuid : string
/// timestamp the site was last loaded
abstract LoadTime : System.DateTime
abstract ProjectProvider : IProvideProjectSite option
\ No newline at end of file
......@@ -23,8 +23,7 @@ open Microsoft.FSharp.Compiler.CompileOps
open Microsoft.FSharp.Compiler.SourceCodeServices
open Microsoft.VisualStudio
open Microsoft.VisualStudio.Editor
open Microsoft.VisualStudio.FSharp.LanguageService
open Microsoft.VisualStudio.FSharp.LanguageService.SiteProvider
open Microsoft.VisualStudio.FSharp.Editor.SiteProvider
open Microsoft.VisualStudio.TextManager.Interop
open Microsoft.VisualStudio.LanguageServices
open Microsoft.VisualStudio.LanguageServices.Implementation.LanguageService
......
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
module internal rec Microsoft.VisualStudio.FSharp.Editor.SiteProvider
open System
open System.IO
open System.Collections.Concurrent
open System.Diagnostics
open Microsoft.FSharp.Compiler.SourceCodeServices
open Microsoft.CodeAnalysis
open Microsoft.VisualStudio
open Microsoft.VisualStudio.LanguageServices
open Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem
open Microsoft.VisualStudio.LanguageServices.Implementation.TaskList
open Microsoft.VisualStudio.Shell.Interop
open Microsoft.VisualStudio.TextManager.Interop
open VSLangProj
/// An additional interface that an IProjectSite object can implement to indicate it has an FSharpProjectOptions
/// already available, so we don't have to recreate it
type private IHaveCheckOptions =
abstract OriginalCheckOptions : unit -> string[] * FSharpProjectOptions
let projectDisplayNameOf projectFileName =
if String.IsNullOrWhiteSpace projectFileName then projectFileName
else Path.GetFileNameWithoutExtension projectFileName
/// A value and a function to recompute/refresh the value. The function is passed a flag indicating if a refresh is happening.
type Refreshable<'T> = 'T * (bool -> 'T)
/// Convert from FSharpProjectOptions into IProjectSite.
type private ProjectSiteOfScriptFile(filename:string, referencedProjectFileNames, checkOptions: FSharpProjectOptions) =
interface IProjectSite with
override __.Description = sprintf "Script Closure at Root %s" filename
override __.CompilationSourceFiles = checkOptions.SourceFiles
override __.CompilationOptions = checkOptions.OtherOptions
override __.CompilationReferences =
checkOptions.OtherOptions
|> Array.choose (fun flag -> if flag.StartsWith("-r:") then Some flag.[3..] else None)
override __.CompilationBinOutputPath = None
override __.ProjectFileName = checkOptions.ProjectFileName
override __.BuildErrorReporter with get() = None and set _ = ()
override __.AdviseProjectSiteChanges(_,_) = ()
override __.AdviseProjectSiteCleaned(_,_) = ()
override __.AdviseProjectSiteClosed(_,_) = ()
override __.IsIncompleteTypeCheckEnvironment = checkOptions.IsIncompleteTypeCheckEnvironment
override __.TargetFrameworkMoniker = ""
override __.ProjectGuid = ""
override __.LoadTime = checkOptions.LoadTime
override __.ProjectProvider = None
interface IHaveCheckOptions with
override __.OriginalCheckOptions() = (referencedProjectFileNames, checkOptions)
override __.ToString() = sprintf "ProjectSiteOfScriptFile(%s)" filename
/// An orphan file project is a .fs, .ml, .fsi, .mli that is not associated with a .fsproj.
/// By design, these are never going to typecheck because there is no affiliated references.
/// We show many squiggles in this case because they're not particularly informational.
type private ProjectSiteOfSingleFile(sourceFile) =
// CompilerFlags() gets called a lot, so pre-compute what we can
static let compilerFlags =
let flags = ["--noframework";"--warn:3"]
let assumeDotNetFramework = true
let defaultReferences =
[ for r in CompilerEnvironment.DefaultReferencesForOrphanSources(assumeDotNetFramework) do
yield sprintf "-r:%s%s" r (if r.EndsWith(".dll",StringComparison.OrdinalIgnoreCase) then "" else ".dll") ]
(flags @ defaultReferences)
|> List.toArray
|> Array.choose (fun flag -> if flag.StartsWith("-r:") then Some flag.[3..] elif flag.StartsWith("--reference:") then Some flag.[12..] else None)
let projectFileName = sourceFile + ".orphan.fsproj"
interface IProjectSite with
override __.Description = projectFileName
override __.CompilationSourceFiles = [|sourceFile|]
override __.CompilationOptions = compilerFlags
override __.CompilationReferences = compilerFlags
override __.CompilationBinOutputPath = None
override __.ProjectFileName = projectFileName
override __.BuildErrorReporter with get() = None and set _v = ()
override __.AdviseProjectSiteChanges(_,_) = ()
override __.AdviseProjectSiteCleaned(_,_) = ()
override __.AdviseProjectSiteClosed(_,_) = ()
override __.IsIncompleteTypeCheckEnvironment = true
override __.TargetFrameworkMoniker = ""
override __.ProjectGuid = ""
override __.LoadTime = new DateTime(2000,1,1) // any constant time is fine, orphan files do not interact with reloading based on update time
override __.ProjectProvider = None
override __.ToString() = sprintf "ProjectSiteOfSingleFile(%s)" sourceFile
/// Manage Storage of FSharpProjectOptions the options for a project
type internal FSharpProjectOptionsTable () =
// A table of information about projects, excluding single-file projects.
let projectTable = ConcurrentDictionary<ProjectId, Refreshable<ProjectId[] * FSharpParsingOptions * IProjectSite option * FSharpProjectOptions>>()
let commandLineOptions = new ConcurrentDictionary<ProjectId, string[]*string[]*string[]>()
/// Re-fetch all of the options for everything that references projectId
let refreshInfoForProjectsThatReferenceThisProject (projectId:ProjectId) =
for KeyValue(otherProjectId, ((referencedProjectIds, _parsingOptions, _site, _options), refresh)) in projectTable.ToArray() do
for referencedProjectId in referencedProjectIds do
if referencedProjectId = projectId then
projectTable.[otherProjectId] <- (refresh true, refresh)
/// Add or update a project in the project table
member __.AddOrUpdateProject(projectId:ProjectId, refresh) =
projectTable.[projectId] <- (refresh false, refresh)
refreshInfoForProjectsThatReferenceThisProject(projectId)
/// Clear a project from the project table
member __.ClearInfoForProject(projectId:ProjectId) =
projectTable.TryRemove(projectId) |> ignore
refreshInfoForProjectsThatReferenceThisProject projectId
/// Get the options for a project
member __.TryGetOptionsForProject(projectId:ProjectId) =
match projectTable.TryGetValue(projectId) with
| true, ((_referencedProjects, parsingOptions, site, projectOptions), _) -> Some (parsingOptions, site, projectOptions)
| _ -> None
/// Given a projectId return the most recent set of command line options for it
member __.GetCommandLineOptionsWithProjectId(projectId:ProjectId) =
match commandLineOptions.TryGetValue projectId with
| true, (sources, references, options) -> sources, references, options
| _ -> [||], [||], [||]
/// Store the command line options for a projectId
member __.SetOptionsWithProjectId(projectId:ProjectId, sourcePaths:string[], referencePaths:string[], options:string[]) =
commandLineOptions.[projectId] <- (sourcePaths, referencePaths, options)
let internal provideProjectSiteProvider(workspace:VisualStudioWorkspaceImpl, project:Project, serviceProvider:System.IServiceProvider, projectOptionsTable:FSharpProjectOptionsTable option) =
let hier = workspace.GetHierarchy(project.Id)
let getCommandLineOptionsWithProjectId (projectId) =
match projectOptionsTable with
| Some (options) -> options.GetCommandLineOptionsWithProjectId(projectId)
| None -> [||], [||], [||]
{
new IProvideProjectSite with
member x.GetProjectSite() =
let fst (a, _, _) = a
let snd (_, b, _) = b
let mutable errorReporter =
let reporter = ProjectExternalErrorReporter(project.Id, "FS", serviceProvider)
Some(reporter:> IVsLanguageServiceBuildErrorReporter2)
{
new IProjectSite with
member __.Description = project.Name
member __.CompilationSourceFiles = getCommandLineOptionsWithProjectId(project.Id) |> fst
member __.CompilationOptions =
let _,references,options = getCommandLineOptionsWithProjectId(project.Id)
Array.concat [options; references |> Array.map(fun r -> "-r:" + r)]
member __.CompilationReferences = getCommandLineOptionsWithProjectId(project.Id) |> snd
member site.CompilationBinOutputPath = site.CompilationOptions |> Array.tryPick (fun s -> if s.StartsWith("-o:") then Some s.[3..] else None)
member __.ProjectFileName = project.FilePath
member __.AdviseProjectSiteChanges(_,_) = ()
member __.AdviseProjectSiteCleaned(_,_) = ()
member __.AdviseProjectSiteClosed(_,_) = ()
member __.IsIncompleteTypeCheckEnvironment = false
member __.TargetFrameworkMoniker = ""
member __.ProjectGuid = project.Id.Id.ToString()
member __.LoadTime = System.DateTime.Now
member __.ProjectProvider = Some (x)
member __.BuildErrorReporter with get () = errorReporter and set (v) = errorReporter <- v
}
interface IVsHierarchy with
member __.SetSite(psp) = hier.SetSite(psp)
member __.GetSite(psp) = hier.GetSite(ref psp)
member __.QueryClose(pfCanClose)= hier.QueryClose(ref pfCanClose)
member __.Close() = hier.Close()
member __.GetGuidProperty(itemid, propid, pguid) = hier.GetGuidProperty(itemid, propid, ref pguid)
member __.SetGuidProperty(itemid, propid, rguid) = hier.SetGuidProperty(itemid, propid, ref rguid)
member __.GetProperty(itemid, propid, pvar) = hier.GetProperty(itemid, propid, ref pvar)
member __.SetProperty(itemid, propid, var) = hier.SetProperty(itemid, propid, var)
member __.GetNestedHierarchy(itemid, iidHierarchyNested, ppHierarchyNested, pitemidNested) =
hier.GetNestedHierarchy(itemid, ref iidHierarchyNested, ref ppHierarchyNested, ref pitemidNested)
member __.GetCanonicalName(itemid, pbstrName) = hier.GetCanonicalName(itemid, ref pbstrName)
member __.ParseCanonicalName(pszName, pitemid) = hier.ParseCanonicalName(pszName, ref pitemid)
member __.Unused0() = hier.Unused0()
member __.AdviseHierarchyEvents(pEventSink, pdwCookie) = hier.AdviseHierarchyEvents(pEventSink, ref pdwCookie)
member __.UnadviseHierarchyEvents(dwCookie) = hier.UnadviseHierarchyEvents(dwCookie)
member __.Unused1() = hier.Unused1()
member __.Unused2() = hier.Unused2()
member __.Unused3() = hier.Unused3()
member __.Unused4() = hier.Unused4()
}
/// Information about projects, open files and other active artifacts in visual studio.
/// Keeps track of the relationship between IVsTextLines buffers, IFSharpSource_DEPRECATED objects, IProjectSite objects and FSharpProjectOptions
[<Sealed>]
type internal ProjectSitesAndFiles() =
static let mutable stamp = 0L
static let fullOutputAssemblyPath (p:EnvDTE.Project) =
let getProperty tag =
try Some (p.Properties.[tag].Value.ToString()) with _ -> None
getProperty "FullPath"
|> Option.bind (fun fullPath ->
(try Some (p.ConfigurationManager.ActiveConfiguration.Properties.["OutputPath"].Value.ToString()) with _ -> None)
|> Option.bind (fun outputPath ->
getProperty "OutputFileName"
|> Option.map (fun outputFileName -> Path.Combine(fullPath, outputPath, outputFileName))))
|> Option.bind (fun path -> try Some (Path.GetFullPath path) with _ -> None)
static let referencedProjects (projectSite:IProjectSite) =
match projectSite.ProjectProvider with
| None -> None
| Some (:? IVsHierarchy as hier) ->
match hier.GetProperty(VSConstants.VSITEMID_ROOT, int __VSHPROPID.VSHPROPID_ExtObject) with
| VSConstants.S_OK, (:? EnvDTE.Project as p) when not (isNull p) ->
Some ((p.Object :?> VSLangProj.VSProject).References
|> Seq.cast<VSLangProj.Reference>
|> Seq.choose (fun r ->
Option.ofObj r
|> Option.bind (fun r -> try Option.ofObj r.SourceProject with _ -> None)) )
| _ -> None
| Some _ -> None
static let rec referencedProvideProjectSites(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
| (Some references), _ ->
for p in references do
match solutionService.GetProjectOfUniqueName(p.UniqueName) with
| VSConstants.S_OK, (:? IProvideProjectSite as ps) ->
yield None, p.FileName, (fullOutputAssemblyPath p) |> Option.defaultValue "", ps
| _ -> ()
| None, _ -> ()
|]
let solutionService = try Some (serviceProvider.GetService(typeof<SVsSolution>) :?> IVsSolution) with _ -> None
seq { match solutionService with
| Some solutionService ->
for reference in getReferencesForSolutionService solutionService do
yield reference
| None -> ()
}
static let rec referencedProjectsOf(enableInMemoryCrossProjectReferences, tryGetOptionsForReferencedProject, projectSite, serviceProvider, extraProjectInfo, projectOptionsTable, useUniqueStamp) =
[| 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, useUniqueStamp) |> snd
| Some options -> options
yield projectFileName, (outputPath, referencedProjectOptions) |]
and getProjectOptionsForProjectSite(enableInMemoryCrossProjectReferences, tryGetOptionsForReferencedProject, projectSite, serviceProvider, projectId, fileName, extraProjectInfo, projectOptionsTable, useUniqueStamp) =
let referencedProjectFileNames, referencedProjectOptions =
if enableInMemoryCrossProjectReferences then
referencedProjectsOf(enableInMemoryCrossProjectReferences, tryGetOptionsForReferencedProject, projectSite, serviceProvider, extraProjectInfo, projectOptionsTable, useUniqueStamp)
|> Array.unzip
else [| |], [| |]
let option =
let newOption () = {
ProjectFileName = projectSite.ProjectFileName
SourceFiles = projectSite.CompilationSourceFiles
OtherOptions = projectSite.CompilationOptions
ReferencedProjects = referencedProjectOptions
IsIncompleteTypeCheckEnvironment = projectSite.IsIncompleteTypeCheckEnvironment
UseScriptResolutionRules = SourceFile.MustBeSingleFileProject fileName
LoadTime = projectSite.LoadTime
UnresolvedReferences = None
OriginalLoadReferences = []
ExtraProjectInfo=extraProjectInfo
Stamp = if useUniqueStamp then (stamp <- stamp + 1L; Some stamp) else None
}
match projectId, projectOptionsTable with
| Some id, Some optionsTable ->
// Get options from cache
match optionsTable.TryGetOptionsForProject(id) with
| Some (_parsingOptions, _site, projectOptions) ->
if projectSite.CompilationSourceFiles <> projectOptions.SourceFiles ||
projectSite.CompilationOptions <> projectOptions.OtherOptions ||
referencedProjectOptions <> projectOptions.ReferencedProjects then
newOption()
else
projectOptions
| _ -> newOption()
| _ -> newOption()
referencedProjectFileNames, option
/// Construct a project site for a single file. May be a single file project (for scripts) or an orphan project site (for everything else).
static member ProjectSiteOfSingleFile(filename:string) : IProjectSite =
if SourceFile.MustBeSingleFileProject(filename) then
Debug.Assert(false, ".fsx or .fsscript should have been treated as implicit project")
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)
|> 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, useUniqueStamp) =
match projectSite with
| :? IHaveCheckOptions as hco -> hco.OriginalCheckOptions()
| _ -> getProjectOptionsForProjectSite(enableInMemoryCrossProjectReferences, tryGetOptionsForReferencedProject, projectSite, serviceProvider, projectId, filename, extraProjectInfo, projectOptionsTable, useUniqueStamp)
/// Create project site for these project options
static member CreateProjectSiteForScript (filename, referencedProjectFileNames, checkOptions) =
ProjectSiteOfScriptFile (filename, referencedProjectFileNames, checkOptions) :> IProjectSite
\ No newline at end of file
......@@ -1471,7 +1471,7 @@ namespace rec Microsoft.VisualStudio.FSharp.ProjectSystem
member __.TargetFrameworkMoniker = x.GetTargetFrameworkMoniker()
member __.ProjectGuid = x.GetProjectGuid()
member __.LoadTime = creationTime
member __.ProjectProvider = Some (x :> IProvideProjectSite)
member __.ProjectProvider = Some (x :> Microsoft.VisualStudio.FSharp.LanguageService.IProvideProjectSite)
}
......@@ -1507,7 +1507,7 @@ namespace rec Microsoft.VisualStudio.FSharp.ProjectSystem
member __.TargetFrameworkMoniker = targetFrameworkMoniker
member __.ProjectGuid = x.GetProjectGuid()
member __.LoadTime = creationTime
member __.ProjectProvider = Some (x :> IProvideProjectSite)
member __.ProjectProvider = Some (x :> Microsoft.VisualStudio.FSharp.LanguageService.IProvideProjectSite)
}
// let the language service ask us questions
......
......@@ -113,7 +113,7 @@ type internal FSharpLanguageServiceTestable() as this =
serviceProvider <- None
/// Respond to project settings changes
member this.OnProjectSettingsChanged(site:IProjectSite) =
member this.OnProjectSettingsChanged(site: Microsoft.VisualStudio.FSharp.LanguageService.IProjectSite) =
// The project may have changed its references. These would be represented as 'dependency files' of each source file. Each source file will eventually start listening
// for changes to those dependencies, at which point we'll get OnDependencyFileCreateOrDelete notifications. Until then, though, we just 'make a note' that this project is out of date.
bgRequests.AddOutOfDateProjectFileName(site.ProjectFileName)
......@@ -126,7 +126,7 @@ type internal FSharpLanguageServiceTestable() as this =
| None -> ()
/// Respond to project being cleaned/rebuilt (any live type providers in the project should be refreshed)
member this.OnProjectCleaned(projectSite:IProjectSite) =
member this.OnProjectCleaned(projectSite:Microsoft.VisualStudio.FSharp.LanguageService.IProjectSite) =
let enableInMemoryCrossProjectReferences = true
let _, checkOptions = ProjectSitesAndFiles.GetProjectOptionsForProjectSite(enableInMemoryCrossProjectReferences, (fun _ -> None), projectSite, serviceProvider.Value, None(*projectId*), "" ,None, None, false)
this.FSharpChecker.NotifyProjectCleaned(checkOptions) |> Async.RunSynchronously
......@@ -147,12 +147,12 @@ type internal FSharpLanguageServiceTestable() as this =
match result with
| Some(hier,_) ->
match hier with
| :? IProvideProjectSite as siteProvider ->
| :? Microsoft.VisualStudio.FSharp.LanguageService.IProvideProjectSite as siteProvider ->
let site = siteProvider.GetProjectSite()
site.AdviseProjectSiteChanges(FSharpConstants.FSharpLanguageServiceCallbackName,
new AdviseProjectSiteChanges(fun () -> this.OnProjectSettingsChanged(site)))
new Microsoft.VisualStudio.FSharp.LanguageService.AdviseProjectSiteChanges(fun () -> this.OnProjectSettingsChanged(site)))
site.AdviseProjectSiteCleaned(FSharpConstants.FSharpLanguageServiceCallbackName,
new AdviseProjectSiteChanges(fun () -> this.OnProjectCleaned(site)))
new Microsoft.VisualStudio.FSharp.LanguageService.AdviseProjectSiteChanges(fun () -> this.OnProjectCleaned(site)))
| _ ->
// This can happen when the file is in a solution folder or in, say, a C# project.
()
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册