From 24e4427a0ecadb2d4a0502508d038fc50efc9c1a Mon Sep 17 00:00:00 2001 From: nojaf Date: Mon, 25 Mar 2024 09:59:51 +0100 Subject: [PATCH 1/7] Add ignore expression code fix. --- .../CodeFixes/IgnoreExpression.fs | 58 ++++++++++++++++++ .../CodeFixes/IgnoreExpression.fsi | 6 ++ .../LspServers/AdaptiveServerState.fs | 3 +- .../CodeFixTests/IgnoreExpressionTests.fs | 61 +++++++++++++++++++ .../CodeFixTests/Tests.fs | 3 +- 5 files changed, 129 insertions(+), 2 deletions(-) create mode 100644 src/FsAutoComplete/CodeFixes/IgnoreExpression.fs create mode 100644 src/FsAutoComplete/CodeFixes/IgnoreExpression.fsi create mode 100644 test/FsAutoComplete.Tests.Lsp/CodeFixTests/IgnoreExpressionTests.fs diff --git a/src/FsAutoComplete/CodeFixes/IgnoreExpression.fs b/src/FsAutoComplete/CodeFixes/IgnoreExpression.fs new file mode 100644 index 000000000..6ff7e2b0f --- /dev/null +++ b/src/FsAutoComplete/CodeFixes/IgnoreExpression.fs @@ -0,0 +1,58 @@ +module FsAutoComplete.CodeFix.IgnoreExpression + +open FSharp.Compiler.Syntax +open FSharp.Compiler.Text +open FsToolkit.ErrorHandling +open Ionide.LanguageServerProtocol.Types +open FsAutoComplete.CodeFix.Types +open FsAutoComplete +open FsAutoComplete.LspHelpers + +let title = "Ignore expression" + +let fix (getParseResultsForFile: GetParseResultsForFile) : CodeFix = + Run.ifDiagnosticByCode (set [ "20" ]) (fun diagnostic (codeActionParams: CodeActionParams) -> + asyncResult { + let fileName = codeActionParams.TextDocument.GetFilePath() |> Utils.normalizePath + let fcsPos = protocolPosToPos codeActionParams.Range.Start + + let! (parseAndCheckResults: ParseAndCheckResults, _line: string, sourceText: IFSACSourceText) = + getParseResultsForFile fileName fcsPos + + let mDiag = + protocolRangeToRange parseAndCheckResults.GetParseResults.FileName diagnostic.Range + + let mExprOpt = + (fcsPos, parseAndCheckResults.GetParseResults.ParseTree) + ||> ParsedInput.tryPick (fun path node -> + match node with + | SyntaxNode.SynExpr(e) when Range.equals mDiag e.Range -> Some(path, e) + | _ -> None) + + match mExprOpt with + | None -> return [] + | Some(path, expr) -> + // Only do single line for now + if expr.Range.StartLine <> expr.Range.EndLine then + return [] + else + let needsParentheses = + SynExpr.shouldBeParenthesizedInContext sourceText.GetLineString path expr + + let newText = + let currentText = sourceText.GetSubTextFromRange expr.Range + + if not needsParentheses then + $"%s{currentText} |> ignore" + else + $"(%s{currentText}) |> ignore" + + return + [ { SourceDiagnostic = None + Title = title + File = codeActionParams.TextDocument + Edits = + [| { Range = fcsRangeToLsp expr.Range + NewText = newText } |] + Kind = FixKind.Fix } ] + }) diff --git a/src/FsAutoComplete/CodeFixes/IgnoreExpression.fsi b/src/FsAutoComplete/CodeFixes/IgnoreExpression.fsi new file mode 100644 index 000000000..30d31289f --- /dev/null +++ b/src/FsAutoComplete/CodeFixes/IgnoreExpression.fsi @@ -0,0 +1,6 @@ +module FsAutoComplete.CodeFix.IgnoreExpression + +open FsAutoComplete.CodeFix.Types + +val title: string +val fix: getParseResultsForFile: GetParseResultsForFile -> CodeFix diff --git a/src/FsAutoComplete/LspServers/AdaptiveServerState.fs b/src/FsAutoComplete/LspServers/AdaptiveServerState.fs index 28ff20d58..26c97e39b 100644 --- a/src/FsAutoComplete/LspServers/AdaptiveServerState.fs +++ b/src/FsAutoComplete/LspServers/AdaptiveServerState.fs @@ -1924,7 +1924,8 @@ type AdaptiveState(lspClient: FSharpLspClient, sourceTextFactory: ISourceTextFac RemoveUnnecessaryParentheses.fix forceFindSourceText AddTypeAliasToSignatureFile.fix forceGetFSharpProjectOptions tryGetParseAndCheckResultsForFile UpdateTypeAbbreviationInSignatureFile.fix tryGetParseAndCheckResultsForFile - AddBindingToSignatureFile.fix forceGetFSharpProjectOptions tryGetParseAndCheckResultsForFile |]) + AddBindingToSignatureFile.fix forceGetFSharpProjectOptions tryGetParseAndCheckResultsForFile + IgnoreExpression.fix tryGetParseAndCheckResultsForFile |]) let forgetDocument (uri: DocumentUri) = async { diff --git a/test/FsAutoComplete.Tests.Lsp/CodeFixTests/IgnoreExpressionTests.fs b/test/FsAutoComplete.Tests.Lsp/CodeFixTests/IgnoreExpressionTests.fs new file mode 100644 index 000000000..930768263 --- /dev/null +++ b/test/FsAutoComplete.Tests.Lsp/CodeFixTests/IgnoreExpressionTests.fs @@ -0,0 +1,61 @@ +module private FsAutoComplete.Tests.CodeFixTests.IgnoreExpressionTests + +open Expecto +open Helpers +open Utils.ServerTests +open Utils.CursorbasedTests +open FsAutoComplete.CodeFix + +let tests state = + serverTestList (nameof IgnoreExpression) state defaultConfigDto None (fun server -> + [ let selectCodeFix = CodeFix.withTitle IgnoreExpression.title + + testCaseAsync "ignore constant" + <| CodeFix.check + server + " +let a b = + 9$0 + null" + Diagnostics.acceptAll + selectCodeFix + " +let a b = + (9) |> ignore + null" + + testCaseAsync "ignore infix application" + <| CodeFix.check + server + " +let a b = + 0 / 9$0 + null" + Diagnostics.acceptAll + selectCodeFix + " +let a b = + (0 / 9) |> ignore + null" + + testCaseAsync "ignore member invocation" + <| CodeFix.check + server + " +open System.Collections.Generic + +let foo () = + let dict = dict [] + di$0ct.TryAdd(\"foo\", \"bar\") + ()" + Diagnostics.acceptAll + selectCodeFix + " +open System.Collections.Generic + +let foo () = + let dict = dict [] + (dict.TryAdd(\"foo\", \"bar\")) |> ignore + ()" + + ]) diff --git a/test/FsAutoComplete.Tests.Lsp/CodeFixTests/Tests.fs b/test/FsAutoComplete.Tests.Lsp/CodeFixTests/Tests.fs index 88ee76a6a..81c31e2cd 100644 --- a/test/FsAutoComplete.Tests.Lsp/CodeFixTests/Tests.fs +++ b/test/FsAutoComplete.Tests.Lsp/CodeFixTests/Tests.fs @@ -3435,4 +3435,5 @@ let tests textFactory state = removeUnnecessaryParenthesesTests state AddTypeAliasToSignatureFileTests.tests state UpdateTypeAbbreviationInSignatureFileTests.tests state - AddBindingToSignatureFileTests.tests state ] + AddBindingToSignatureFileTests.tests state + IgnoreExpressionTests.tests state ] \ No newline at end of file From 3aee389c027f52ea515ca8208255181b68763d0d Mon Sep 17 00:00:00 2001 From: nojaf Date: Thu, 28 Mar 2024 16:42:32 +0100 Subject: [PATCH 2/7] Check for multiline diagnostic sooner. --- .editorconfig | 3 ++ .../CodeFixes/IgnoreExpression.fs | 51 ++++++++++--------- 2 files changed, 29 insertions(+), 25 deletions(-) diff --git a/.editorconfig b/.editorconfig index 8d1e1bb03..2637ff747 100644 --- a/.editorconfig +++ b/.editorconfig @@ -23,3 +23,6 @@ fsharp_max_array_or_list_width=80 fsharp_max_dot_get_expression_width=80 fsharp_max_function_binding_width=80 fsharp_max_value_binding_width=80 + +[src/FsAutoComplete/CodeFixes/*.fs] +fsharp_experimental_keep_indent_in_branch = true \ No newline at end of file diff --git a/src/FsAutoComplete/CodeFixes/IgnoreExpression.fs b/src/FsAutoComplete/CodeFixes/IgnoreExpression.fs index 6ff7e2b0f..7acad6916 100644 --- a/src/FsAutoComplete/CodeFixes/IgnoreExpression.fs +++ b/src/FsAutoComplete/CodeFixes/IgnoreExpression.fs @@ -2,6 +2,7 @@ module FsAutoComplete.CodeFix.IgnoreExpression open FSharp.Compiler.Syntax open FSharp.Compiler.Text +open FSharp.UMX open FsToolkit.ErrorHandling open Ionide.LanguageServerProtocol.Types open FsAutoComplete.CodeFix.Types @@ -15,13 +16,16 @@ let fix (getParseResultsForFile: GetParseResultsForFile) : CodeFix = asyncResult { let fileName = codeActionParams.TextDocument.GetFilePath() |> Utils.normalizePath let fcsPos = protocolPosToPos codeActionParams.Range.Start + let mDiag = protocolRangeToRange (UMX.untag fileName) diagnostic.Range + + // Only do single line for now + if mDiag.StartLine <> mDiag.EndLine then + return [] + else let! (parseAndCheckResults: ParseAndCheckResults, _line: string, sourceText: IFSACSourceText) = getParseResultsForFile fileName fcsPos - let mDiag = - protocolRangeToRange parseAndCheckResults.GetParseResults.FileName diagnostic.Range - let mExprOpt = (fcsPos, parseAndCheckResults.GetParseResults.ParseTree) ||> ParsedInput.tryPick (fun path node -> @@ -32,27 +36,24 @@ let fix (getParseResultsForFile: GetParseResultsForFile) : CodeFix = match mExprOpt with | None -> return [] | Some(path, expr) -> - // Only do single line for now - if expr.Range.StartLine <> expr.Range.EndLine then - return [] + + let needsParentheses = + SynExpr.shouldBeParenthesizedInContext sourceText.GetLineString path expr + + let newText = + let currentText = sourceText.GetSubTextFromRange expr.Range + + if not needsParentheses then + $"%s{currentText} |> ignore" else - let needsParentheses = - SynExpr.shouldBeParenthesizedInContext sourceText.GetLineString path expr - - let newText = - let currentText = sourceText.GetSubTextFromRange expr.Range - - if not needsParentheses then - $"%s{currentText} |> ignore" - else - $"(%s{currentText}) |> ignore" - - return - [ { SourceDiagnostic = None - Title = title - File = codeActionParams.TextDocument - Edits = - [| { Range = fcsRangeToLsp expr.Range - NewText = newText } |] - Kind = FixKind.Fix } ] + $"(%s{currentText}) |> ignore" + + return + [ { SourceDiagnostic = None + Title = title + File = codeActionParams.TextDocument + Edits = + [| { Range = fcsRangeToLsp expr.Range + NewText = newText } |] + Kind = FixKind.Fix } ] }) From 207afa89098fb18fc0ff35d0d2bd44dc133143f7 Mon Sep 17 00:00:00 2001 From: nojaf Date: Thu, 28 Mar 2024 17:06:25 +0100 Subject: [PATCH 3/7] Check new expression if it needs parentheses or not. --- .../CodeFixes/IgnoreExpression.fs | 39 ++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/src/FsAutoComplete/CodeFixes/IgnoreExpression.fs b/src/FsAutoComplete/CodeFixes/IgnoreExpression.fs index 7acad6916..a54b674ee 100644 --- a/src/FsAutoComplete/CodeFixes/IgnoreExpression.fs +++ b/src/FsAutoComplete/CodeFixes/IgnoreExpression.fs @@ -1,6 +1,7 @@ module FsAutoComplete.CodeFix.IgnoreExpression open FSharp.Compiler.Syntax +open FSharp.Compiler.SyntaxTrivia open FSharp.Compiler.Text open FSharp.UMX open FsToolkit.ErrorHandling @@ -38,7 +39,43 @@ let fix (getParseResultsForFile: GetParseResultsForFile) : CodeFix = | Some(path, expr) -> let needsParentheses = - SynExpr.shouldBeParenthesizedInContext sourceText.GetLineString path expr + // expr |> ignore + let exprInPipe = + let lineNumber = expr.Range.StartLine + + let mkRangeInFile (offset: int) (length: int) : range = + Range.mkRange + expr.Range.FileName + (Position.mkPos lineNumber (expr.Range.EndColumn + offset)) + (Position.mkPos lineNumber (expr.Range.EndColumn + offset + length)) + + let mPipe = mkRangeInFile 2 2 + let mIgnore = mkRangeInFile 5 6 + + SynExpr.App( + ExprAtomicFlag.NonAtomic, + false, + SynExpr.App( + ExprAtomicFlag.NonAtomic, + true, + SynExpr.LongIdent( + false, + SynLongIdent( + [ FSharp.Compiler.Syntax.Ident("op_PipeRight", mPipe) ], + [], + [ Some(IdentTrivia.OriginalNotation "|>") ] + ), + None, + mPipe + ), + expr, // The expr that will now be piped into ignore. + Range.unionRanges expr.Range mPipe + ), + SynExpr.Ident(FSharp.Compiler.Syntax.Ident("ignore", mIgnore)), + Range.unionRanges expr.Range mIgnore + ) + + SynExpr.shouldBeParenthesizedInContext sourceText.GetLineString path exprInPipe let newText = let currentText = sourceText.GetSubTextFromRange expr.Range From f9c93442ca57c025c8e2192cb4f9227773c640c6 Mon Sep 17 00:00:00 2001 From: nojaf Date: Fri, 29 Mar 2024 15:49:42 +0100 Subject: [PATCH 4/7] Construct correct path for SynExpr.shouldBeParenthesizedInContext --- .../CodeFixes/IgnoreExpression.fs | 28 ++++++++++++------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/src/FsAutoComplete/CodeFixes/IgnoreExpression.fs b/src/FsAutoComplete/CodeFixes/IgnoreExpression.fs index a54b674ee..31169c3e0 100644 --- a/src/FsAutoComplete/CodeFixes/IgnoreExpression.fs +++ b/src/FsAutoComplete/CodeFixes/IgnoreExpression.fs @@ -39,8 +39,7 @@ let fix (getParseResultsForFile: GetParseResultsForFile) : CodeFix = | Some(path, expr) -> let needsParentheses = - // expr |> ignore - let exprInPipe = + let appPipe, appIgnore = let lineNumber = expr.Range.StartLine let mkRangeInFile (offset: int) (length: int) : range = @@ -52,9 +51,7 @@ let fix (getParseResultsForFile: GetParseResultsForFile) : CodeFix = let mPipe = mkRangeInFile 2 2 let mIgnore = mkRangeInFile 5 6 - SynExpr.App( - ExprAtomicFlag.NonAtomic, - false, + let appPipe = SynExpr.App( ExprAtomicFlag.NonAtomic, true, @@ -70,12 +67,23 @@ let fix (getParseResultsForFile: GetParseResultsForFile) : CodeFix = ), expr, // The expr that will now be piped into ignore. Range.unionRanges expr.Range mPipe - ), - SynExpr.Ident(FSharp.Compiler.Syntax.Ident("ignore", mIgnore)), - Range.unionRanges expr.Range mIgnore - ) + ) - SynExpr.shouldBeParenthesizedInContext sourceText.GetLineString path exprInPipe + let appIgnore = + SynExpr.App( + ExprAtomicFlag.NonAtomic, + false, + appPipe, + SynExpr.Ident(FSharp.Compiler.Syntax.Ident("ignore", mIgnore)), + Range.unionRanges expr.Range mIgnore + ) + + appPipe, appIgnore + + let pathWithPipeIgnore = + SyntaxNode.SynExpr appPipe :: SyntaxNode.SynExpr appIgnore :: path + + SynExpr.shouldBeParenthesizedInContext sourceText.GetLineString pathWithPipeIgnore expr let newText = let currentText = sourceText.GetSubTextFromRange expr.Range From 6b0e7125f3501bc14bc265bf574ae1660850f77c Mon Sep 17 00:00:00 2001 From: nojaf Date: Mon, 8 Apr 2024 08:59:10 +0200 Subject: [PATCH 5/7] Update FCS with fix from Brian --- paket.dependencies | 2 +- paket.lock | 21 ++++++++++--------- .../CodeFixTests/IgnoreExpressionTests.fs | 6 +++--- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/paket.dependencies b/paket.dependencies index dcd89e5dc..ae5eed6ee 100644 --- a/paket.dependencies +++ b/paket.dependencies @@ -13,7 +13,7 @@ lowest_matching: true nuget BenchmarkDotNet 0.13.5 nuget Fantomas.Client >= 0.9 -nuget FSharp.Compiler.Service >= 43.8.300-preview.24080.5 +nuget FSharp.Compiler.Service >= 43.8.300-preview.24205.4 nuget Ionide.Analyzers 0.7.0 nuget FSharp.Analyzers.Build 0.3.0 nuget Ionide.ProjInfo >= 0.62.0 diff --git a/paket.lock b/paket.lock index 03b7638f3..8b2c76528 100644 --- a/paket.lock +++ b/paket.lock @@ -56,22 +56,12 @@ NUGET FParsec (1.1.1) - restriction: || (== net6.0) (== net7.0) (== net8.0) (&& (== netstandard2.0) (>= net5.0)) (&& (== netstandard2.1) (>= net5.0)) FSharp.Core (>= 4.3.4) FSharp.Analyzers.Build (0.3) - FSharp.Compiler.Service (43.8.300-preview.24154.4) - FSharp.Core (8.0.300-beta.24154.4) - System.Buffers (>= 4.5.1) - System.Collections.Immutable (>= 7.0) - System.Diagnostics.DiagnosticSource (>= 7.0.2) - System.Memory (>= 4.5.5) - System.Reflection.Emit (>= 4.7) - System.Reflection.Metadata (>= 7.0) - System.Runtime.CompilerServices.Unsafe (>= 6.0) FSharp.Control.AsyncSeq (3.2.1) FSharp.Core (>= 4.7.2) Microsoft.Bcl.AsyncInterfaces (>= 5.0) FSharp.Control.Reactive (5.0.5) - restriction: || (== net6.0) (== net7.0) (== net8.0) (&& (== netstandard2.0) (>= net6.0)) (&& (== netstandard2.1) (>= net6.0)) FSharp.Core (>= 4.7.2) System.Reactive (>= 5.0 < 6.0) - FSharp.Core (8.0.300-beta.24154.4) FSharp.Data.Adaptive (1.2.13) FSharp.Core (>= 4.7) System.Reflection.Emit.Lightweight (>= 4.6) @@ -758,6 +748,17 @@ NUGET Expecto (>= 10.0 < 11.0) - restriction: || (== net6.0) (== net7.0) (== net8.0) (&& (== netstandard2.0) (>= net6.0)) (&& (== netstandard2.1) (>= net6.0)) FSharp.Core (>= 7.0.200) - restriction: || (== net6.0) (== net7.0) (== net8.0) (&& (== netstandard2.0) (>= net6.0)) (&& (== netstandard2.1) (>= net6.0)) System.Collections.Immutable (>= 6.0) - restriction: || (== net6.0) (== net7.0) (== net8.0) (&& (== netstandard2.0) (>= net6.0)) (&& (== netstandard2.1) (>= net6.0)) + remote: https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet8/nuget/v3/index.json + FSharp.Compiler.Service (43.8.300-preview.24205.4) + FSharp.Core (8.0.300-beta.24205.4) + System.Buffers (>= 4.5.1) + System.Collections.Immutable (>= 7.0) + System.Diagnostics.DiagnosticSource (>= 7.0.2) + System.Memory (>= 4.5.5) + System.Reflection.Emit (>= 4.7) + System.Reflection.Metadata (>= 7.0) + System.Runtime.CompilerServices.Unsafe (>= 6.0) + FSharp.Core (8.0.300-beta.24205.4) GROUP Build STORAGE: NONE diff --git a/test/FsAutoComplete.Tests.Lsp/CodeFixTests/IgnoreExpressionTests.fs b/test/FsAutoComplete.Tests.Lsp/CodeFixTests/IgnoreExpressionTests.fs index 930768263..5b43bbe89 100644 --- a/test/FsAutoComplete.Tests.Lsp/CodeFixTests/IgnoreExpressionTests.fs +++ b/test/FsAutoComplete.Tests.Lsp/CodeFixTests/IgnoreExpressionTests.fs @@ -21,7 +21,7 @@ let a b = selectCodeFix " let a b = - (9) |> ignore + 9 |> ignore null" testCaseAsync "ignore infix application" @@ -35,7 +35,7 @@ let a b = selectCodeFix " let a b = - (0 / 9) |> ignore + 0 / 9 |> ignore null" testCaseAsync "ignore member invocation" @@ -55,7 +55,7 @@ open System.Collections.Generic let foo () = let dict = dict [] - (dict.TryAdd(\"foo\", \"bar\")) |> ignore + dict.TryAdd(\"foo\", \"bar\") |> ignore ()" ]) From d1d610645f62b638c69701c9b2e18730f154e743 Mon Sep 17 00:00:00 2001 From: nojaf Date: Mon, 8 Apr 2024 09:10:47 +0200 Subject: [PATCH 6/7] Update AST usage --- src/FsAutoComplete.Core/FCSPatches.fs | 2 +- src/FsAutoComplete.Core/TestAdapter.fs | 4 ++-- src/FsAutoComplete.Core/UntypedAstUtils.fs | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/FsAutoComplete.Core/FCSPatches.fs b/src/FsAutoComplete.Core/FCSPatches.fs index f8baac0f4..83ba575c7 100644 --- a/src/FsAutoComplete.Core/FCSPatches.fs +++ b/src/FsAutoComplete.Core/FCSPatches.fs @@ -141,7 +141,7 @@ module SyntaxTreeOps = | SynExpr.TryFinally(tryExpr = e1; finallyExpr = e2) -> walkExpr e1 || walkExpr e2 - | SynExpr.Sequential(_, _, e1, e2, _) -> walkExpr e1 || walkExpr e2 + | SynExpr.Sequential(expr1 = e1; expr2 = e2) -> walkExpr e1 || walkExpr e2 | SynExpr.SequentialOrImplicitYield(_, e1, e2, _, _) -> walkExpr e1 || walkExpr e2 diff --git a/src/FsAutoComplete.Core/TestAdapter.fs b/src/FsAutoComplete.Core/TestAdapter.fs index fe75b9a65..2f589caf6 100644 --- a/src/FsAutoComplete.Core/TestAdapter.fs +++ b/src/FsAutoComplete.Core/TestAdapter.fs @@ -36,8 +36,8 @@ let private ModuleWithSuffixType = "ModuleWithSuffix" let rec private (|Sequentials|_|) = function - | SynExpr.Sequential(_, _, e, Sequentials es, _) -> Some(e :: es) - | SynExpr.Sequential(_, _, e1, e2, _) -> Some [ e1; e2 ] + | SynExpr.Sequential(expr1 = e; expr2 = Sequentials es) -> Some(e :: es) + | SynExpr.Sequential(expr1 = e1; expr2 = e2) -> Some [ e1; e2 ] | _ -> None let getExpectoTests (ast: ParsedInput) : TestAdapterEntry list = diff --git a/src/FsAutoComplete.Core/UntypedAstUtils.fs b/src/FsAutoComplete.Core/UntypedAstUtils.fs index 5a59a0374..ddf4de0de 100644 --- a/src/FsAutoComplete.Core/UntypedAstUtils.fs +++ b/src/FsAutoComplete.Core/UntypedAstUtils.fs @@ -9,8 +9,8 @@ module Syntax = /// An recursive pattern that collect all sequential expressions to avoid StackOverflowException let rec (|Sequentials|_|) = function - | SynExpr.Sequential(_, _, e, Sequentials es, _) -> Some(e :: es) - | SynExpr.Sequential(_, _, e1, e2, _) -> Some [ e1; e2 ] + | SynExpr.Sequential(expr1 = e; expr2 = Sequentials es) -> Some(e :: es) + | SynExpr.Sequential(expr1 = e1; expr2 = e2) -> Some [ e1; e2 ] | _ -> None let (|ConstructorPats|) = From c2a00f0c56291b7a5e66081deaff8e5f7456fe73 Mon Sep 17 00:00:00 2001 From: nojaf Date: Mon, 8 Apr 2024 15:44:24 +0200 Subject: [PATCH 7/7] Add test to ignore tuple. --- .../CodeFixTests/IgnoreExpressionTests.fs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/test/FsAutoComplete.Tests.Lsp/CodeFixTests/IgnoreExpressionTests.fs b/test/FsAutoComplete.Tests.Lsp/CodeFixTests/IgnoreExpressionTests.fs index 5b43bbe89..cc8013686 100644 --- a/test/FsAutoComplete.Tests.Lsp/CodeFixTests/IgnoreExpressionTests.fs +++ b/test/FsAutoComplete.Tests.Lsp/CodeFixTests/IgnoreExpressionTests.fs @@ -58,4 +58,18 @@ let foo () = dict.TryAdd(\"foo\", \"bar\") |> ignore ()" + testCaseAsync "ignore tuple" + <| CodeFix.check + server + " +let _ = + 1, 2$0 + null" + Diagnostics.acceptAll + selectCodeFix + " +let _ = + (1, 2) |> ignore + null" + ])