Skip to content

Commit

Permalink
Merge pull request #144 from ionide/optimize_getdeclarations
Browse files Browse the repository at this point in the history
Optimize GetDeclarations
  • Loading branch information
rneatherway authored Jan 27, 2017
2 parents a358c20 + 857286c commit 4dd66f0
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 17 deletions.
27 changes: 15 additions & 12 deletions src/FsAutoComplete.Core/Commands.fs
Original file line number Diff line number Diff line change
Expand Up @@ -101,27 +101,30 @@ type Commands (serialize : Serializer) =
project)

let (|NetCore|Net45|Unsupported|) file =
//.NET Core Sdk preview3 replace project.json with fsproj
//.NET Core Sdk preview3+ replace project.json with fsproj
//Easy way to detect new fsproj is to check the msbuild version of .fsproj
// MSBuild version 15 (`ToolsVersion="15.0"`) is the new project format
//The `dotnet-compile-fsc.rsp` are created also in `preview3`, so we can
//Post preview5 has (`Sdk="Fsharp.NET.Sdk;Microsoft.NET.Sdk"`), use that
// for checking .NET Core fsproj
//The `dotnet-compile-fsc.rsp` are created also in `preview3+`, so we can
// reuse the same behaviour of `preview2`
let rec findToolsVersion (sr:StreamReader) limit =
// only preview3+ uses ToolsVersion='15.0'
let isPreview3 (toolsVersion:string) = toolsVersion.Contains("=\"15.0\"")
let rec getProjectType (sr:StreamReader) limit =
// only preview3-5 uses ToolsVersion='15.0'
// post preview5 dropped this, check Sdk field
let isNetCore (line:string) = line.Contains("=\"15.0\"") || line.Contains("Fsharp.NET.Sdk")
if limit = 0 then
Unsupported // unsupported project type
else
let line = sr.ReadLine()
if not <| line.Contains("ToolsVersion") then
findToolsVersion sr (limit-1)
else // both net45 and preview3+ have 'ToolsVersion'
if isPreview3 line then NetCore else Net45
if not <| line.Contains("ToolsVersion") && not <| line.Contains("Sdk=") then
getProjectType sr (limit-1)
else // both net45 and preview3-5 have 'ToolsVersion', > 5 has 'Sdk'
if isNetCore line then NetCore else Net45
if not <| File.Exists(projectFileName) then Net45 // no such file is handled downstream
elif Path.GetExtension file = ".json" then NetCore // dotnet core preview 2 or earlier
else
use sr = File.OpenText(file)
findToolsVersion sr 3
getProjectType sr 3


return
Expand All @@ -147,12 +150,12 @@ type Commands (serialize : Serializer) =
[response]
}

member __.Declarations file = async {
member __.Declarations file version = async {
let file = Path.GetFullPath file
match state.TryGetFileCheckerOptionsWithSource file with
| Failure s -> return [Response.error serialize s]
| Success (checkOptions, source) ->
let! decls = checker.GetDeclarations(file, source, checkOptions)
let! decls = checker.GetDeclarations(file, source, checkOptions, version)
let decls = decls |> Array.map (fun a -> a,file)
return [Response.declarations serialize decls]
}
Expand Down
19 changes: 17 additions & 2 deletions src/FsAutoComplete.Core/CompilerServiceInterface.fs
Original file line number Diff line number Diff line change
Expand Up @@ -373,8 +373,23 @@ type FSharpCompilerServiceChecker() =
return res |> Array.collect id }
}

member __.GetDeclarations (fileName, source, options) = async {
let! parseResult = checker.ParseFileInProject(fileName, source, options)
member __.GetDeclarations (fileName, source, options, version) = async {
let! parseResult =
match checker.TryGetRecentCheckResultsForFile(fileName, options,source), version with
| Some (pr, _, v), Some ver when v = ver -> async {return pr}
| _, None -> checker.ParseFileInProject(fileName, source, options)
| _ ->
async {
let! chkd =
checker.FileParsed
|> Event.filter ((=) fileName)
|> Async.AwaitEvent

return!
match checker.TryGetRecentCheckResultsForFile(fileName,options,source) with
| None -> checker.ParseFileInProject(fileName, source, options)
| Some (pr,_,_) -> async {return pr}
}
return parseResult.GetNavigationItems().Declarations
}

Expand Down
4 changes: 2 additions & 2 deletions src/FsAutoComplete.Suave/FsAutoComplete.Suave.fs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ open FsAutoComplete.JsonSerializer
module Contract =
type ParseRequest = { FileName : string; IsAsync : bool; Lines : string[]; Version : int }
type ProjectRequest = { FileName : string;}
type DeclarationsRequest = {FileName : string}
type DeclarationsRequest = {FileName : string; Version : int}
type HelptextRequest = {Symbol : string}
type CompletionRequest = {FileName : string; SourceLine : string; Line : int; Column : int; Filter : string; IncludeKeywords : bool;}
type PositionRequest = {FileName : string; Line : int; Column : int; Filter : string}
Expand Down Expand Up @@ -116,7 +116,7 @@ let main argv =
//TODO: Add filewatcher
path "/parseProjectsInBackground" >=> handler (fun (data : ProjectRequest) -> commands.ParseAndCheckProjectsInBackgroundForFile data.FileName)
path "/project" >=> handler (fun (data : ProjectRequest) -> commands.Project data.FileName false ignore)
path "/declarations" >=> handler (fun (data : DeclarationsRequest) -> commands.Declarations data.FileName)
path "/declarations" >=> handler (fun (data : DeclarationsRequest) -> commands.Declarations data.FileName (Some data.Version) )
path "/declarationsProjects" >=> fun httpCtx ->
async {
let! errors = commands.DeclarationsInProjects ()
Expand Down
2 changes: 1 addition & 1 deletion src/FsAutoComplete/Program.fs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ module internal Main =

| Project (file, verbose) ->
return! commands.Project file verbose (fun fullPath -> commandQueue.Add(Project (fullPath, verbose)))
| Declarations file -> return! commands.Declarations file
| Declarations file -> return! commands.Declarations file None
| HelpText sym -> return commands.Helptext sym
| PosCommand (cmd, file, lineStr, pos, _timeout, filter) ->
let file = Path.GetFullPath file
Expand Down

0 comments on commit 4dd66f0

Please sign in to comment.