diff --git a/src/FsAutoComplete/CodeFixes/AddMissingWildcardOperator.fs b/src/FsAutoComplete/CodeFixes/AddMissingWildcardOperator.fs new file mode 100644 index 000000000..0ddbf5108 --- /dev/null +++ b/src/FsAutoComplete/CodeFixes/AddMissingWildcardOperator.fs @@ -0,0 +1,56 @@ +module FsAutoComplete.CodeFix.AddMissingWildcardOperator + +open FsToolkit.ErrorHandling +open FsAutoComplete.CodeFix.Navigation +open FsAutoComplete.CodeFix.Types +open Ionide.LanguageServerProtocol.Types +open FsAutoComplete +open FsAutoComplete.LspHelpers +open FSharp.Compiler.Syntax +open FSharp.Compiler.Text +open FSharp.Compiler.SyntaxTrivia + +let title = "Add missing wildcard operator" + + +let tryFindPattern pos input = + + let visitor = + { new SyntaxVisitorBase() with + + member _.VisitExpr(path, traverseSynExpr, defaultTraverse, expr) = + match expr with + | SynExpr.LongIdent( + longDotId = SynLongIdent.SynLongIdent(trivia = [ Some(IdentTrivia.OriginalNotation("|->")) ]) + range = range) when FSharp.Compiler.Text.Range.rangeContainsPos range pos -> + + Some(range) + + | _ -> defaultTraverse expr } + + SyntaxTraversal.Traverse(pos, input, visitor) + + + +/// a codefix that adds a missing 'fun' keyword to a lambda +let fix (getParseResultsForFile: GetParseResultsForFile) : CodeFix = + Run.ifDiagnosticByCode (Set.ofList [ "43" ]) (fun diagnostic codeActionParams -> + asyncResult { + + let filePath = codeActionParams.TextDocument.GetFilePath() |> Utils.normalizePath + let fcsPos = protocolPosToPos codeActionParams.Range.Start + let! (parseAndCheck, lineStr, _sourceText) = getParseResultsForFile filePath fcsPos + + match tryFindPattern fcsPos parseAndCheck.GetAST with + | None -> return [] + | Some operatorRange -> + + let lspRange = fcsRangeToLsp operatorRange + + return + [ { Title = title + File = codeActionParams.TextDocument + SourceDiagnostic = Some diagnostic + Edits = [| { Range = lspRange; NewText = "| _ ->" } |] + Kind = FixKind.Fix } ] + }) diff --git a/src/FsAutoComplete/CodeFixes/AddMissingWildcardOperator.fsi b/src/FsAutoComplete/CodeFixes/AddMissingWildcardOperator.fsi new file mode 100644 index 000000000..ff5286f6f --- /dev/null +++ b/src/FsAutoComplete/CodeFixes/AddMissingWildcardOperator.fsi @@ -0,0 +1,12 @@ +module FsAutoComplete.CodeFix.AddMissingWildcardOperator + +open FsToolkit.ErrorHandling +open FsAutoComplete.CodeFix.Navigation +open FsAutoComplete.CodeFix.Types +open Ionide.LanguageServerProtocol.Types +open FsAutoComplete +open FsAutoComplete.LspHelpers + +val title: string +/// a codefix that adds a missing wildcard pattern to a match case +val fix: getParseResultsForFile: GetParseResultsForFile -> CodeFix diff --git a/src/FsAutoComplete/LspServers/AdaptiveFSharpLspServer.fs b/src/FsAutoComplete/LspServers/AdaptiveFSharpLspServer.fs index b92ac2875..1c8b3c7bc 100644 --- a/src/FsAutoComplete/LspServers/AdaptiveFSharpLspServer.fs +++ b/src/FsAutoComplete/LspServers/AdaptiveFSharpLspServer.fs @@ -1806,6 +1806,7 @@ type AdaptiveFSharpLspServer RemoveUnnecessaryReturnOrYield.fix tryGetParseResultsForFile getLineText ConvertCSharpLambdaToFSharpLambda.fix tryGetParseResultsForFile getLineText AddMissingFunKeyword.fix forceFindSourceText getLineText + AddMissingWildcardOperator.fix tryGetParseResultsForFile MakeOuterBindingRecursive.fix tryGetParseResultsForFile getLineText AddMissingRecKeyword.fix forceFindSourceText getLineText ConvertBangEqualsToInequality.fix getRangeText diff --git a/src/FsAutoComplete/LspServers/FsAutoComplete.Lsp.fs b/src/FsAutoComplete/LspServers/FsAutoComplete.Lsp.fs index b11db9eee..87be6ccf4 100644 --- a/src/FsAutoComplete/LspServers/FsAutoComplete.Lsp.fs +++ b/src/FsAutoComplete/LspServers/FsAutoComplete.Lsp.fs @@ -1152,6 +1152,7 @@ type FSharpLspServer(state: State, lspClient: FSharpLspClient, sourceTextFactory RemoveUnnecessaryReturnOrYield.fix tryGetParseResultsForFile getLineText ConvertCSharpLambdaToFSharpLambda.fix tryGetParseResultsForFile getLineText AddMissingFunKeyword.fix getFileLines getLineText + AddMissingWildcardOperator.fix tryGetParseResultsForFile MakeOuterBindingRecursive.fix tryGetParseResultsForFile getLineText AddMissingRecKeyword.fix getFileLines getLineText ConvertBangEqualsToInequality.fix getRangeText diff --git a/test/FsAutoComplete.Tests.Lsp/CodeFixTests/AddMissingWildcardOperatorTests.fs b/test/FsAutoComplete.Tests.Lsp/CodeFixTests/AddMissingWildcardOperatorTests.fs new file mode 100644 index 000000000..309dfbeac --- /dev/null +++ b/test/FsAutoComplete.Tests.Lsp/CodeFixTests/AddMissingWildcardOperatorTests.fs @@ -0,0 +1,37 @@ +module private FsAutoComplete.Tests.CodeFixTests.AddMissingWildcardOperatorTests + +open Expecto +open Helpers +open Utils.ServerTests +open Utils.CursorbasedTests +open FsAutoComplete.CodeFix + +let tests state = + serverTestList (nameof AddMissingWildcardOperator) state defaultConfigDto None (fun server -> + [ let selectCodeFix = CodeFix.withTitle AddMissingWildcardOperator.title + + ftestCaseAsync "can suggest wildcard pattern for missing match case" + <| CodeFix.check + server + """ + type SomeUnion = + | First + | Second + + let testMatch su = + match su with + | First -> "hey" + $0|-> "hello" + """ + (Diagnostics.expectCode "43") + selectCodeFix + """ + type SomeUnion = + | First + | Second + + let testMatch su = + match su with + | First -> "hey" + | _ -> "hello" + """ ]) diff --git a/test/FsAutoComplete.Tests.Lsp/CodeFixTests/Tests.fs b/test/FsAutoComplete.Tests.Lsp/CodeFixTests/Tests.fs index 9230d36a8..91b7d0467 100644 --- a/test/FsAutoComplete.Tests.Lsp/CodeFixTests/Tests.fs +++ b/test/FsAutoComplete.Tests.Lsp/CodeFixTests/Tests.fs @@ -3351,4 +3351,5 @@ let tests state = useTripleQuotedInterpolationTests state wrapExpressionInParenthesesTests state removeRedundantAttributeSuffixTests state - removePatternArgumentTests state ] + removePatternArgumentTests state + AddMissingWildcardOperatorTests.tests state ]