Skip to content

Commit

Permalink
RemovePatternArgument quick fix (#1142)
Browse files Browse the repository at this point in the history
  • Loading branch information
edgarfgp authored Jul 14, 2023
1 parent 24b547d commit f6b3c97
Show file tree
Hide file tree
Showing 4 changed files with 275 additions and 2 deletions.
54 changes: 54 additions & 0 deletions src/FsAutoComplete/CodeFixes/RemovePatternArgument.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
module FsAutoComplete.CodeFix.RemovePatternArgument

open FsToolkit.ErrorHandling
open FsAutoComplete.CodeFix.Types
open Ionide.LanguageServerProtocol.Types
open FsAutoComplete
open FsAutoComplete.LspHelpers
open FSharp.Compiler.Syntax
open FSharp.Compiler.Text.Range
open FSharp.Compiler.Text

let title = "Remove argument"

let tryFindPattern pos input =
let visitor =
{ new SyntaxVisitorBase<range>() with

member _.VisitExpr(path, traverseSynExpr, defaultTraverse, expr) = defaultTraverse expr

member this.VisitPat(path: SyntaxVisitorPath, defaultTraverse: SynPat -> range option, synPat: SynPat) =
match synPat with
| SynPat.LongIdent(longDotId = synLongIdent; argPats = SynArgPats.Pats(pats); range = m) when
rangeContainsPos synPat.Range pos && not pats.IsEmpty
->
let mRemove = mkRange m.FileName synLongIdent.Range.End m.End
Some mRemove
| SynPat.Paren(pat = innerPat) ->
let nextPath = SyntaxNode.SynPat(synPat) :: path
this.VisitPat(nextPath, defaultTraverse, innerPat)
| _ -> None }

SyntaxTraversal.Traverse(pos, input, visitor)

let fix (getParseResultsForFile: GetParseResultsForFile) : CodeFix =
Run.ifDiagnosticByCode (Set.ofList [ "725"; "3191" ]) (fun _ codeActionParams ->
asyncResult {
let filePath = codeActionParams.TextDocument.GetFilePath() |> Utils.normalizePath
let fcsPos = protocolPosToPos codeActionParams.Range.Start
let! parseAndCheck, _, _ = getParseResultsForFile filePath fcsPos

match tryFindPattern fcsPos parseAndCheck.GetAST with
| None -> return []
| Some removeRange ->
let e =
{ Range = fcsRangeToLsp removeRange
NewText = "" }

return
[ { Edits = [| e |]
File = codeActionParams.TextDocument
Title = title
SourceDiagnostic = None
Kind = FixKind.Refactor } ]
})
3 changes: 2 additions & 1 deletion src/FsAutoComplete/LspServers/AdaptiveFSharpLspServer.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1691,7 +1691,8 @@ type AdaptiveFSharpLspServer
(fun _ -> config.AddPrivateAccessModifier)
(AddPrivateAccessModifier.fix tryGetParseResultsForFile symbolUseWorkspace)
UseTripleQuotedInterpolation.fix tryGetParseResultsForFile getRangeText
RenameParamToMatchSignature.fix tryGetParseResultsForFile |])
RenameParamToMatchSignature.fix tryGetParseResultsForFile
RemovePatternArgument.fix tryGetParseResultsForFile |])

let forgetDocument (uri: DocumentUri) =
async {
Expand Down
3 changes: 2 additions & 1 deletion src/FsAutoComplete/LspServers/FsAutoComplete.Lsp.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1228,7 +1228,8 @@ type FSharpLspServer(state: State, lspClient: FSharpLspClient, sourceTextFactory
(fun _ -> config.AddPrivateAccessModifier)
(AddPrivateAccessModifier.fix tryGetParseResultsForFile symbolUseWorkspace)
UseTripleQuotedInterpolation.fix tryGetParseResultsForFile getRangeText
RenameParamToMatchSignature.fix tryGetParseResultsForFile |]
RenameParamToMatchSignature.fix tryGetParseResultsForFile
RemovePatternArgument.fix tryGetParseResultsForFile |]


match p.RootPath, c.AutomaticWorkspaceInit with
Expand Down
217 changes: 217 additions & 0 deletions test/FsAutoComplete.Tests.Lsp/CodeFixTests/Tests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2873,6 +2873,222 @@ let private removeRedundantAttributeSuffixTests state =
class end
""" ])

let private removePatternArgumentTests state =
fserverTestList (nameof RemovePatternArgument) state defaultConfigDto None (fun server -> [
let selectCodeFix = CodeFix.withTitle RemovePatternArgument.title
testCaseAsync "Literal pattern qualified single parameter" <|
CodeFix.check server
"""
type E =
| A = 1
| B = 2
let (E.A x$0) = E.A
"""
(Diagnostics.expectCode "3191")
selectCodeFix
"""
type E =
| A = 1
| B = 2
let (E.A) = E.A
"""

testCaseAsync "Local literal pattern qualified match parens parameter" <|
CodeFix.check server
"""
type E =
| A = 1
| B = 2
match E.A with
| (E.A x$0) -> ()
"""
(Diagnostics.expectCode "3191")
selectCodeFix
"""
type E =
| A = 1
| B = 2
match E.A with
| (E.A) -> ()
"""

testCaseAsync "Local literal pattern qualified single parameter" <|
CodeFix.check server
"""
type E =
| A = 1
| B = 2
do
let (E.A x$0) = E.A
()
"""
(Diagnostics.expectCode "3191")
selectCodeFix
"""
type E =
| A = 1
| B = 2
do
let (E.A) = E.A
()
"""

testCaseAsync "Local literal constant pattern qualified parameter" <|
CodeFix.check server
"""
let [<Literal>] A = 1
match 1 with
| A x$0 -> ()
"""
(Diagnostics.expectCode "3191")
selectCodeFix
"""
let [<Literal>] A = 1
match 1 with
| A -> ()
"""

testCaseAsync "Local literal constant pattern qualified parens parameter" <|
CodeFix.check server
"""
let [<Literal>] A = 1
match 1 with
| (A x$0) -> ()
"""
(Diagnostics.expectCode "3191")
selectCodeFix
"""
let [<Literal>] A = 1
match 1 with
| (A) -> ()
"""

testCaseAsync "Local match qualified single parameter" <|
CodeFix.check server
"""
match None with
| Option.None x$0 -> ()
"""
(Diagnostics.expectCode "725")
selectCodeFix
"""
match None with
| Option.None -> ()
"""

testCaseAsync "Local match qualified single parens parameter" <|
CodeFix.check server
"""
match None with
| (Option.None x$0) -> ()
"""
(Diagnostics.expectCode "725")
selectCodeFix
"""
match None with
| (Option.None) -> ()
"""

testCaseAsync "Qualified single parameter" <|
CodeFix.check server
"""
let (Option.None x$0) = None
"""
(Diagnostics.expectCode "725")
selectCodeFix
"""
let (Option.None) = None
"""

testCaseAsync "Local single parameter" <|
CodeFix.check server
"""
do
let (Option.None x$0) = None
()
"""
(Diagnostics.expectCode "725")
selectCodeFix
"""
do
let (Option.None) = None
()
"""

testCaseAsync "Local two match parameters" <|
CodeFix.check server
"""
match None with
| None x$0 y -> ()
"""
(Diagnostics.expectCode "725")
selectCodeFix
"""
match None with
| None -> ()
"""

testCaseAsync "Local two match parens parameters" <|
CodeFix.check server
"""
match None with
| None (x$0 y) -> ()
"""
(Diagnostics.expectCode "725")
selectCodeFix
"""
match None with
| None -> ()
"""

testCaseAsync "Local two parameter" <|
CodeFix.check server
"""
do
let (Option.None x$0 y) = None
()
"""
(Diagnostics.expectCode "725")
selectCodeFix
"""
do
let (Option.None) = None
()
"""

testCaseAsync "Single parameter" <|
CodeFix.check server
"""
let (None x$0) = None
"""
(Diagnostics.expectCode "725")
selectCodeFix
"""
let (None) = None
"""

testCaseAsync "Two parameters" <|
CodeFix.check server
"""
let (None x$0 y) = None
"""
(Diagnostics.expectCode "725")
selectCodeFix
"""
let (None) = None
"""
])

let tests state = testList "CodeFix-tests" [
HelpersTests.tests

Expand Down Expand Up @@ -2916,4 +3132,5 @@ let tests state = testList "CodeFix-tests" [
useTripleQuotedInterpolationTests state
wrapExpressionInParenthesesTests state
removeRedundantAttributeSuffixTests state
removePatternArgumentTests state
]

0 comments on commit f6b3c97

Please sign in to comment.