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

Fix reference count positions #1319

Merged
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
43 changes: 28 additions & 15 deletions src/FsAutoComplete/LspServers/AdaptiveServerState.fs
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@ type AdaptiveWorkspaceChosen =





[<CustomEquality; NoComparison>]
type LoadedProject =
{ ProjectOptions: Types.ProjectOptions
Expand Down Expand Up @@ -1280,20 +1282,22 @@ type AdaptiveState

/// <summary>Parses a source code for a file and caches the results. Returns an AST that can be traversed for various features.</summary>
/// <param name="checker">The FSharpCompilerServiceChecker.</param>
/// <param name="sourceFilePath">The source to be parsed.</param>
/// <param name="file">The source to be parsed.</param>
/// <param name="compilerOptions"></param>
/// <returns></returns>

let parseFile (checker: FSharpCompilerServiceChecker) (sourceFilePath) (compilerOptions: CompilerProjectOption) =

let parseFile (checker: FSharpCompilerServiceChecker) (file: VolatileFile) (compilerOptions: CompilerProjectOption) =
task {
let! result =
match compilerOptions with
| CompilerProjectOption.TransparentCompiler snap ->
taskResult { return! checker.ParseFile(sourceFilePath, snap) }
taskResult { return! checker.ParseFile(file.FileName, snap) }
| CompilerProjectOption.BackgroundCompiler opts ->
taskResult {
let! file = forceFindOpenFileOrRead sourceFilePath
return! checker.ParseFile(sourceFilePath, file.Source, opts)


return! checker.ParseFile(file.FileName, file.Source, opts)
}

let! ct = Async.CancellationToken
Expand Down Expand Up @@ -1324,8 +1328,12 @@ type AdaptiveState
|> HashSet.toArray
|> Array.collect (fun (snap) -> snap.SourceFilesTagged |> List.toArray |> Array.map (fun s -> snap, s))
|> Array.map (fun (snap, filePath) ->
taskResult {
let! vFile = forceFindOpenFileOrRead filePath
return! parseFile checker vFile snap

})

parseFile checker filePath snap)
|> Task.WhenAll
}

Expand Down Expand Up @@ -1435,14 +1443,19 @@ type AdaptiveState

let allFSharpFilesAndProjectOptions =
asyncAVal {
let wins =
openFilesToChangesAndProjectOptions
|> AMap.map (fun _k v -> v |> AsyncAVal.mapSync (fun (_, projects) _ -> projects))
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The main issue here is the calls to parseFile weren't happening after file changes because of how F# Data Adaptive works when caching values. Even if something changes upstream (like file changes), the list of projects was staying the same and causing us to use stale parsechecks.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes sure to allow the file changes to pass thru so we can use them correctly for updates.

let wins = openFilesToChangesAndProjectOptions

let! sourceFileToProjectOptions = sourceFileToProjectOptions

let loses =
sourceFileToProjectOptions |> AMap.map (fun _ v -> AsyncAVal.constant (Ok v))
sourceFileToProjectOptions
|> AMap.map (fun file proj ->
asyncAVal {
let! lastTouched = AdaptiveFile.GetLastWriteTimeUtc(UMX.untag file)
let! vFile = createVolatileFileFromDisk lastTouched file

return vFile, Ok proj
})

return AMap.union loses wins
}
Expand All @@ -1462,7 +1475,7 @@ type AdaptiveState

return
allFSharpFilesAndProjectOptions
|> AMapAsync.mapAsyncAVal (fun filePath (options: Result<LoadedProject list, string>) _ctok ->
|> AMapAsync.mapAsyncAVal (fun filePath (file, options) _ctok ->
asyncAVal {
let! (checker: FSharpCompilerServiceChecker) = checker
and! selectProject = projectSelector
Expand All @@ -1473,7 +1486,7 @@ type AdaptiveState
match loadedProject with
| Ok x ->
let! snap = x.FSharpProjectCompilerOptions
let! r = parseFile checker filePath snap
let! r = parseFile checker file snap
return r
| Error e -> return Error e
})
Expand Down Expand Up @@ -1505,7 +1518,7 @@ type AdaptiveState

return
set
|> Array.choose (fun (k, v) ->
|> Array.choose (fun (k, (_, v)) ->
v
|> Result.bind (findProject k)
|> Result.toOption
Expand All @@ -1524,7 +1537,7 @@ type AdaptiveState
|> Array.map (AsyncAVal.forceAsync)
|> Async.parallel75

let set = set |> Array.choose (Result.toOption)
let set = set |> Array.choose (snd >> Result.toOption)

return set |> Array.collect (List.toArray)
}
Expand All @@ -1539,7 +1552,7 @@ type AdaptiveState
let! allFilesToFSharpProjectOptions = allFilesToFSharpProjectOptions

match! allFilesToFSharpProjectOptions |> AMapAsync.tryFindA filePath with
| Some projs -> return projs
| Some(_, projs) -> return projs
| None -> return Error $"Couldn't find project for {filePath}. Have you tried restoring your project/solution?"
}

Expand Down
Loading
Loading