Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

replace project system, use Dotnet.ProjInfo.Workspace #347

Merged
merged 3 commits into from
Jun 7, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,30 @@
"console": "integratedTerminal",
"stopAtEntry": false,
},
{
"name": ".NET Core mode stdio (debug)",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build_debug_netcore",
"program": "${workspaceFolder}/src/FsAutoComplete/bin/Debug/netcoreapp2.1/fsautocomplete.dll",
"args": ["--mode", "stdio", "-v"],
"cwd": "${workspaceFolder}",
"console": "integratedTerminal",
"stopAtEntry": false,
"internalConsoleOptions": "openOnSessionStart"
},
{
"name": ".NET mode stdio (debug)",
"type": "clr",
"request": "launch",
"preLaunchTask": "build_debug_net",
"program": "${workspaceFolder}/src/FsAutoComplete/bin/Debug/net461/fsautocomplete.exe",
"args": ["--mode", "stdio", "-v"],
"cwd": "${workspaceFolder}",
"console": "integratedTerminal",
"stopAtEntry": false,
"internalConsoleOptions": "openOnSessionStart"
},
{
"name": ".NET Core Attach",
"type": "coreclr",
Expand Down
4 changes: 0 additions & 4 deletions appveyor.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
image:
- Visual Studio 2017

install:
- ps: Invoke-WebRequest -Uri "https://download.microsoft.com/download/9/B/B/9BB1309E-1A8F-4A47-A6C5-ECF76672A3B3/BuildTools_Full.exe" -OutFile "BuildTools_Full.exe"
- BuildTools_Full.exe /Quiet /Silent /Full

build_script:
- cmd: build.cmd All

Expand Down
4 changes: 2 additions & 2 deletions paket.dependencies
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ github Microsoft/visualfsharp:Visual-Studio-2017-Version-15.4 src/fsharp/FSharp.

nuget Argu ~> 5.2.0
nuget FSharp.Compiler.Service ~> 29.0
nuget FSharp.Compiler.Service.ProjectCracker ~> 29.0 framework:net461, condition:net461
nuget Dotnet.ProjInfo ~> 0.31.0
nuget Dotnet.ProjInfo ~> 0.35.0
nuget Dotnet.ProjInfo.Workspace.FCS ~> 0.35.0
nuget FSharp.Data 3.0.1
nuget ICSharpCode.Decompiler 3.2.0.3856
nuget Sln ~> 0.3.0
Expand Down
16 changes: 10 additions & 6 deletions paket.lock
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,17 @@ NUGET
System.Data.SqlClient (>= 4.4) - restriction: || (&& (== net461) (< net451)) (== netcoreapp2.1) (== netstandard2.0)
System.Reflection.Emit.Lightweight (>= 4.3) - restriction: || (&& (== net461) (< net451)) (== netcoreapp2.1) (== netstandard2.0)
System.Reflection.TypeExtensions (>= 4.4) - restriction: || (&& (== net461) (< net451)) (== netcoreapp2.1) (== netstandard2.0)
Dotnet.ProjInfo (0.31)
FSharp.Core (>= 4.3.4)
Dotnet.ProjInfo (0.35)
FSharp.Core (>= 4.6.2)
System.ValueTuple (>= 4.4)
Dotnet.ProjInfo.Workspace (0.35)
Dotnet.ProjInfo (>= 0.35)
FSharp.Core (>= 4.6.2)
Sln (>= 0.3)
Dotnet.ProjInfo.Workspace.FCS (0.35)
Dotnet.ProjInfo.Workspace (>= 0.35)
FSharp.Compiler.Service (>= 29.0)
FSharp.Core (>= 4.6.2)
FParsec (1.0.3)
FSharp.Core (>= 4.0.0.1) - restriction: || (== net461) (&& (== netcoreapp2.1) (>= net40)) (&& (== netstandard2.0) (>= net40))
FSharp.Core (>= 4.2.3) - restriction: || (&& (== net461) (< net40) (>= netstandard1.6)) (== netcoreapp2.1) (== netstandard2.0)
Expand All @@ -31,10 +39,6 @@ NUGET
System.Runtime.Loader (>= 4.0) - restriction: || (== netcoreapp2.1) (== netstandard2.0)
System.Security.Cryptography.Algorithms (>= 4.3) - restriction: || (== netcoreapp2.1) (== netstandard2.0)
System.ValueTuple (>= 4.4) - restriction: || (== net461) (&& (== netcoreapp2.1) (>= net461)) (&& (== netstandard2.0) (>= net461))
FSharp.Compiler.Service.ProjectCracker (29.0) - condition: net461, restriction: == net461
FSharp.Compiler.Service (>= 29.0) - restriction: || (== net461) (&& (== netcoreapp2.1) (>= net461)) (&& (== netstandard2.0) (>= net461))
FSharp.Core (>= 4.6.2) - restriction: || (== net461) (&& (== netcoreapp2.1) (>= net461)) (&& (== netstandard2.0) (>= net461))
System.ValueTuple (>= 4.4) - restriction: || (== net461) (&& (== netcoreapp2.1) (>= net461)) (&& (== netstandard2.0) (>= net461))
FSharp.Core (4.6.2) - redirects: force
FSharp.Data (3.0.1)
FSharp.Core (>= 4.0.0.1) - restriction: || (== net461) (&& (== netcoreapp2.1) (>= net45)) (&& (== netstandard2.0) (>= net45))
Expand Down
71 changes: 57 additions & 14 deletions src/FsAutoComplete.Core/Commands.fs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ type CoreResponse =
| ErrorRes of text: string
| HelpText of name: string * tip: FSharpToolTipText * additionalEdit: (string * int * int * string) option
| HelpTextSimple of name: string * tip: string
| Project of projectFileName: ProjectFilePath * projectFiles: List<SourceFilePath> * outFileOpt : string option * references : ProjectFilePath list * logMap : Map<string,string> * extra: ExtraProjectInfoData * additionals : Map<string,string>
| Project of projectFileName: ProjectFilePath * projectFiles: List<SourceFilePath> * outFileOpt : string option * references : ProjectFilePath list * logMap : Map<string,string> * extra: Dotnet.ProjInfo.Workspace.ExtraProjectInfoData * additionals : Map<string,string>
| ProjectError of errorDetails: GetProjectOptionsErrors
| ProjectLoading of projectFileName: ProjectFilePath
| WorkspacePeek of found: WorkspacePeek.Interesting list
Expand Down Expand Up @@ -245,6 +245,11 @@ type Commands (serialize : Serializer) =
|> parseFilesInTheBackground
|> Async.Start

let workspaceBinder () =
let config = Dotnet.ProjInfo.Workspace.LoaderConfig.Default Environment.msbuildLocator
let loader = Dotnet.ProjInfo.Workspace.Loader.Create(config)
loader, checker.CreateFCSBinder(NETFrameworkInfoProvider.netFWInfo, loader)

member __.Notify = notify.Publish

member __.WorkspaceReady = workspaceReady.Publish
Expand Down Expand Up @@ -415,15 +420,8 @@ type Commands (serialize : Serializer) =
return [CoreResponse.Errors ([||], "") ]
}

member private __.ToProjectCache (opts, extraInfo, projectFiles, logMap) =
let outFileOpt =
match extraInfo.ProjectSdkType with
| ProjectSdkType.Verbose v ->
Some (v.TargetPath)
| ProjectSdkType.ProjectJson ->
FscArguments.outputFile (Path.GetDirectoryName(opts.ProjectFileName)) (opts.OtherOptions |> List.ofArray)
| ProjectSdkType.DotnetSdk v ->
Some (v.TargetPath)
member private __.ToProjectCache (opts, extraInfo: Dotnet.ProjInfo.Workspace.ExtraProjectInfoData, projectFiles, logMap) =
let outFileOpt = Some (extraInfo.TargetPath)
let references = FscArguments.references (opts.OtherOptions |> List.ofArray)
let projectFiles = projectFiles |> List.map (Path.GetFullPath >> Utils.normalizePath)

Expand All @@ -438,7 +436,7 @@ type Commands (serialize : Serializer) =

(opts.ProjectFileName, cached)

member x.Project projectFileName verbose onChange = async {
member x.Project projectFileName _verbose onChange = async {
let projectFileName = Path.GetFullPath projectFileName
let project =
match state.Projects.TryFind projectFileName with
Expand All @@ -447,12 +445,19 @@ type Commands (serialize : Serializer) =
let proj = new Project(projectFileName, onChange)
state.Projects.[projectFileName] <- proj
proj

let workspaceBinder = workspaceBinder ()

let projResponse =
match project.Response with
| Some response ->
Result.Ok (projectFileName, response)
| None ->
match projectFileName |> Workspace.parseProject verbose |> Result.map (x.ToProjectCache) with
let projectCached =
projectFileName
|> Workspace.parseProject workspaceBinder
|> Result.map (fun (opts, optsDPW, projectFiles, logMap) -> x.ToProjectCache(opts, optsDPW.ExtraProjectInfo, projectFiles, logMap) )
match projectCached with
| Result.Ok (projectFileName, response) ->
project.Response <- Some response
Result.Ok (projectFileName, response)
Expand Down Expand Up @@ -961,7 +966,7 @@ type Commands (serialize : Serializer) =

onProjectLoaded projectFileName response

let rec onLoaded p =
let onLoaded p =
match p with
| WorkspaceProjectState.Loading projectFileName ->
CoreResponse.ProjectLoading projectFileName
Expand Down Expand Up @@ -990,7 +995,45 @@ type Commands (serialize : Serializer) =
do! Async.Sleep(Environment.workspaceLoadDelay().TotalMilliseconds |> int)
| _ -> ()

do! Workspace.loadInBackground onLoaded false (projects |> List.map snd)
let loader, fcsBinder = workspaceBinder ()

let projViewer = Dotnet.ProjInfo.Workspace.ProjectViewer ()

let bindNewOnloaded (n: Dotnet.ProjInfo.Workspace.WorkspaceProjectState) : WorkspaceProjectState option =
match n with
| Dotnet.ProjInfo.Workspace.WorkspaceProjectState.Loading (path, _) ->
Some (WorkspaceProjectState.Loading path)
| Dotnet.ProjInfo.Workspace.WorkspaceProjectState.Loaded (opts, logMap) ->
match fcsBinder.GetProjectOptions(opts.ProjectFileName) with
| Some fcsOpts ->
match Workspace.extractOptionsDPW fcsOpts with
| Ok optsDPW ->
let view = projViewer.Render optsDPW
let projectFiles =
view.Items
|> List.map (fun item ->
match item with
| Dotnet.ProjInfo.Workspace.ProjectViewerItem.Compile path -> path)

Some (WorkspaceProjectState.Loaded (fcsOpts, optsDPW.ExtraProjectInfo, projectFiles, logMap))
| Error _ ->
None //TODO not ignore the error
| None ->
//TODO notify C# project too
None
| Dotnet.ProjInfo.Workspace.WorkspaceProjectState.Failed (path, e) ->
let error =
match e with
| Dotnet.ProjInfo.Workspace.GetProjectOptionsErrors.ProjectNotRestored s ->
GetProjectOptionsErrors.ProjectNotRestored s
| Dotnet.ProjInfo.Workspace.GetProjectOptionsErrors.GenericError (a, b) ->
GetProjectOptionsErrors.GenericError (a,b)
Some (WorkspaceProjectState.Failed (path, error))

loader.Notifications.Add(fun (_, arg) ->
arg |> bindNewOnloaded |> Option.iter onLoaded )

do! Workspace.loadInBackground onLoaded (loader, fcsBinder) (projects |> List.map snd)

CoreResponse.WorkspaceLoad true
|> NotificationEvent.Workspace
Expand Down
77 changes: 8 additions & 69 deletions src/FsAutoComplete.Core/CompilerServiceInterface.fs
Original file line number Diff line number Diff line change
Expand Up @@ -403,45 +403,6 @@ type ParseAndCheckResults

type Version = int

module FSharpCompilerServiceCheckerHelper =

let isFSharpCore (s : string) = s.EndsWith "FSharp.Core.dll"

let ensureCorrectFSharpCore (options: string[]) =
let fsharpCores, others = Array.partition isFSharpCore options

// ensure that there is only one fsharpcore ref provided
let fsharpCoreRef =
match fsharpCores with
| [||] -> sprintf "-r:%s" Environment.fsharpCore
| [| ref |] -> ref
| refs -> Array.head refs

[| yield fsharpCoreRef
yield! others |]

#if SCRIPT_REFS_FROM_MSBUILD
#else
let ensureCorrectVersions (options: string[]) =
if Utils.runningOnMono then options
else
match Environment.referenceAssembliesPath (), NETFrameworkInfoProvider.netReferencesAssembliesTFMLatest () with
| _, None -> options
| Some referenceAssembliesPath, Some version ->
let oldRef = referenceAssembliesPath </> "v4.0"
let newRef = referenceAssembliesPath </> version

let fsharpCoreRef = options |> Seq.find isFSharpCore

let newOptions =
options
|> Seq.filter (not << isFSharpCore)
|> Seq.map (fun (s : string) -> s.Replace(oldRef, newRef) )
[| yield fsharpCoreRef
yield! newOptions |]
| None, _ -> options
#endif

type FSharpCompilerServiceChecker() =
let checker =
FSharpChecker.Create(
Expand All @@ -468,11 +429,15 @@ type FSharpCompilerServiceChecker() =
let clearProjectReferecnes (opts: FSharpProjectOptions) =
if disableInMemoryProjectReferences then {opts with ReferencedProjects = [||]} else opts

let logDebug fmt =
let fsxBinder = Dotnet.ProjInfo.Workspace.FCS.FsxBinder(NETFrameworkInfoProvider.netFWInfo, checker)

let logDebug fmt =
if Debug.verbose then Debug.print "[FSharpChecker] Current Queue Length: %d" checker.CurrentQueueLength
Debug.print fmt

member __.CreateFCSBinder(netFwInfo: Dotnet.ProjInfo.Workspace.NetFWInfo, loader: Dotnet.ProjInfo.Workspace.Loader) =
Dotnet.ProjInfo.Workspace.FCS.FCSBinder(netFwInfo, loader, checker)

member __.DisableInMemoryProjectReferences
with get() = disableInMemoryProjectReferences
and set(value) = disableInMemoryProjectReferences <- value
Expand All @@ -488,37 +453,11 @@ type FSharpCompilerServiceChecker() =
])

member __.GetProjectOptionsFromScript(file, source) = async {
let source = SourceText.ofString source
#if SCRIPT_REFS_FROM_MSBUILD

let targetFramework = NETFrameworkInfoProvider.netReferencesAssembliesTFMLatest ()

let additionaRefs =
NETFrameworkInfoProvider.additionalArgumentsBy targetFramework
|> Array.ofList

let! (rawOptions, _) = checker.GetProjectOptionsFromScript(file, source, otherFlags = additionaRefs, assumeDotNetFramework = true)

let opts =
rawOptions.OtherOptions
|> FSharpCompilerServiceCheckerHelper.ensureCorrectFSharpCore

let opts =
opts
|> Array.distinct

return { rawOptions with OtherOptions = opts }
#else
let! (rawOptions, _) = checker.GetProjectOptionsFromScript(file, source)

let opts =
rawOptions.OtherOptions
|> FSharpCompilerServiceCheckerHelper.ensureCorrectFSharpCore
|> FSharpCompilerServiceCheckerHelper.ensureCorrectVersions
let targetFramework = NETFrameworkInfoProvider.latestInstalledNETVersion ()

return { rawOptions with OtherOptions = opts }
#endif
let! projOptions = fsxBinder.GetProjectOptionsFromScriptBy(targetFramework, file, source)

return projOptions
}


Expand Down
Loading