Skip to content

Commit

Permalink
add codefix for converting interpolation issues
Browse files Browse the repository at this point in the history
  • Loading branch information
baronfel committed Apr 5, 2022
1 parent 3e2d6ef commit 7350b8d
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 1 deletion.
9 changes: 9 additions & 0 deletions src/FsAutoComplete.Core/FCSPatches.fs
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,15 @@ type FSharpParseFileResults with
None
| _ -> defaultTraverse expr })

/// Attempts to find the range of the string interpolation that contains a given position.
member scope.TryRangeOfStringInterpolationContainingPos pos =
SyntaxTraversal.Traverse(pos, scope.ParseTree, { new SyntaxVisitorBase<_>() with
member _.VisitExpr(_, _, defaultTraverse, expr) =
match expr with
| SynExpr.InterpolatedString(range = range) when Range.rangeContainsPos range pos ->
Some range
| _ -> defaultTraverse expr })

module SyntaxTreeOps =
open FSharp.Compiler.Syntax
let rec synExprContainsError inpExpr =
Expand Down
3 changes: 2 additions & 1 deletion src/FsAutoComplete/FsAutoComplete.Lsp.fs
Original file line number Diff line number Diff line change
Expand Up @@ -868,7 +868,8 @@ type FSharpLspServer(backgroundServiceEnabled: bool, state: State, lspClient: FS
ChangeTypeOfNameToNameOf.fix tryGetParseResultsForFile
AddMissingInstanceMember.fix
AddExplicitTypeToParameter.fix tryGetParseResultsForFile
ConvertPositionalDUToNamed.fix tryGetParseResultsForFile getRangeText |]
ConvertPositionalDUToNamed.fix tryGetParseResultsForFile getRangeText
UseTripleQuotedInterpolation.fix tryGetParseResultsForFile getRangeText |]


match p.RootPath, c.AutomaticWorkspaceInit with
Expand Down
56 changes: 56 additions & 0 deletions test/FsAutoComplete.Tests.Lsp/CodeFixTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -852,6 +852,62 @@ let positionalToNamedDUTests state =

expectEdits patternPos edits) ]

let tripleQuotedInterpolationTests state =
let server =
async {
let path =
Path.Combine(__SOURCE_DIRECTORY__, "TestCases", "TripleQuotedInterpolation")

let cfg = defaultConfigDto
let! (server, events) = serverInitialize path cfg state
do! waitForWorkspaceFinishedParsing events
let path = Path.Combine(path, "Script.fsx")
let tdop: DidOpenTextDocumentParams = { TextDocument = loadDocument path }
do! server.TextDocumentDidOpen tdop

let! diagnostics =
events
|> waitForParseResultsForFile "Script.fsx"
|> AsyncResult.bimap (fun _ -> failtest "Should have had errors") id

return (server, path, diagnostics)
}
|> Async.Cache

testList
"interpolation fixes"
[ testCaseAsync
"converts erroring single-quoted interpolation to triple-quoted"
(async {
let! (server, filePath, diagnostics) = server

let diagnostic =
diagnostics
|> Array.tryFind (fun d -> d.Code = Some "3373")
|> Option.defaultWith (fun _ -> failtest "Should have gotten an error of type 3373")

let context: CodeActionParams =
{ Context = { Diagnostics = [| diagnostic |] }
Range =
{ Start = diagnostic.Range.Start
End = diagnostic.Range.Start }
TextDocument = { Uri = Path.FilePathToUri filePath } }

match! server.TextDocumentCodeAction context with
| Ok (Some (TextDocumentCodeActionResult.CodeActions [| { Title = "Use triple-quoted string interpolation"
Kind = Some "quickfix"
Edit = Some { DocumentChanges = Some [| { Edits = [| { Range = { Start = { Line = 0
Character = 8 }
End = { Line = 0
Character = 44 } }
NewText = "$\"\"\":^) {if true then \"y\" else \"n\"} d\"\"\"" } |] } |] } } |])) ->
()
| Ok other ->
failtestf
$"Should have converted single quoted interpolations to triple quotes, but instead generated %A{other}"
| Error reason -> failtestf $"Should have succeeded, but failed with %A{reason}"
}) ]

let tests state =
testList
"codefix tests"
Expand Down

0 comments on commit 7350b8d

Please sign in to comment.