Skip to content
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
29 changes: 21 additions & 8 deletions src/FsAutoComplete/LspServers/AdaptiveFSharpLspServer.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1183,19 +1183,32 @@ type AdaptiveFSharpLspServer
ranges
|> Seq.map (fun kvp ->
async {
let file: string<LocalPath> = kvp.Key
let! fileContent = state.GetOpenFileOrRead file

// FCS incorrectly returns `get` and `set` accessor keywords as symbol uses
// of the property when explicit getter/setter syntax is used, e.g.
// member this.Prop with get () = ... and set v = ...
// It may also return duplicate ranges for the property name itself.
// Filter and deduplicate to avoid spurious renames and overlapping edits.
let filteredRanges =
match fileContent with
| Error _ -> kvp.Value
| Ok volatileFile ->
kvp.Value
|> Array.filter (fun range ->
match volatileFile.Source.GetText(range) with
| Ok text -> text <> "get" && text <> "set"
| Error _ -> true)
|> Array.distinctBy (fun r -> r.StartLine, r.StartColumn)

let edits =
kvp.Value
filteredRanges
|> Array.map (fun range ->
let range = fcsRangeToLsp range
U2.C1 { Range = range; NewText = newName })

let file: string<LocalPath> = kvp.Key

let! version =
async {
let! file = state.GetOpenFileOrRead file
return file |> Option.ofResult |> Option.map (fun (f) -> f.Version)
}
let version = fileContent |> Option.ofResult |> Option.map (fun f -> f.Version)

return
{ TextDocument =
Expand Down
20 changes: 20 additions & 0 deletions test/FsAutoComplete.Tests.Lsp/RenameTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,26 @@ let private sameScriptTests state =
let value = 42

let _ = value + 42
"""

// Regression test for https://github.com/ionide/FsAutoComplete/issues/1269
// FCS incorrectly returns `get`/`set` accessor keywords as rename targets for the property.
testCaseAsync "renaming property with explicit get/set does not rename accessor keywords"
<| checkRename
"""
type MyClass() =
let mutable _v = 0
member this.Va$0lue
with get () = _v
and set v = _v <- v
"""
"Count"
"""
type MyClass() =
let mutable _v = 0
member this.Count
with get () = _v
and set v = _v <- v
""" ])

let private crossProjectTests state =
Expand Down