From 824f582d07c106788489bd3be8a92d07e2086d6b Mon Sep 17 00:00:00 2001 From: nojaf Date: Thu, 8 Feb 2024 15:08:23 +0100 Subject: [PATCH 1/7] Naieve implementation --- src/Fable.Transforms/Replacements.fs | 1 + .../FSharp.Core.CompilerServices.fs | 20 +++++++++++++++++++ src/fable-library/Fable.Library.fsproj | 1 + src/quicktest/QuickTest.fs | 11 ++++++++++ 4 files changed, 33 insertions(+) create mode 100644 src/fable-library/FSharp.Core.CompilerServices.fs diff --git a/src/Fable.Transforms/Replacements.fs b/src/Fable.Transforms/Replacements.fs index a6af1edad7..691cbb4ec3 100644 --- a/src/Fable.Transforms/Replacements.fs +++ b/src/Fable.Transforms/Replacements.fs @@ -4672,6 +4672,7 @@ let private replacedModules = "Microsoft.FSharp.Control.ObservableModule", observable Types.type_, types "System.Reflection.TypeInfo", types + "Microsoft.FSharp.Core.CompilerServices.ListCollector`1", bclType ] let tryCall (com: ICompiler) (ctx: Context) r t (info: CallInfo) (thisArg: Expr option) (args: Expr list) = diff --git a/src/fable-library/FSharp.Core.CompilerServices.fs b/src/fable-library/FSharp.Core.CompilerServices.fs new file mode 100644 index 0000000000..cc14fa95ee --- /dev/null +++ b/src/fable-library/FSharp.Core.CompilerServices.fs @@ -0,0 +1,20 @@ +namespace Microsoft.FSharp.Core.CompilerServices + +open Fable.Core + +[] +[] +type ListCollector<'T>() = + let collector = ResizeArray<'T>() + + member this.Add(value: 'T) = collector.Add(value) + + member this.AddMany(values: seq<'T>) = collector.AddRange(values) + + // In the particular case of closing with a final add of an F# list + // we can simply stitch the list into the end of the resulting list + member this.AddManyAndClose(values: seq<'T>) = + collector.AddRange(values) + Seq.toList collector + + member this.Close() = Seq.toList collector diff --git a/src/fable-library/Fable.Library.fsproj b/src/fable-library/Fable.Library.fsproj index c8ffc86036..764d2b4c3f 100644 --- a/src/fable-library/Fable.Library.fsproj +++ b/src/fable-library/Fable.Library.fsproj @@ -33,6 +33,7 @@ + diff --git a/src/quicktest/QuickTest.fs b/src/quicktest/QuickTest.fs index 7bd62ccbf2..f2f62b7188 100644 --- a/src/quicktest/QuickTest.fs +++ b/src/quicktest/QuickTest.fs @@ -98,3 +98,14 @@ printfn "Running quick tests..." // to Fable.Tests project. For example: // testCase "Addition works" <| fun () -> // 2 + 2 |> equal 4 + +open Microsoft.FSharp.Core.CompilerServices + +testCase + "meh" + (fun () -> + let c = ListCollector() + c.Add(1) + let r = c.Close() + ignore r + ) From 8c64bf50f6c017fa4c493d52384449718c817eb1 Mon Sep 17 00:00:00 2001 From: ncave <777696+ncave@users.noreply.github.com> Date: Thu, 8 Feb 2024 15:12:54 -0800 Subject: [PATCH 2/7] Fixed ListCollector constructor --- src/Fable.Transforms/Replacements.Util.fs | 1 - src/Fable.Transforms/Replacements.fs | 4 +++- src/fable-library/FSharp.Core.CompilerServices.fs | 3 --- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/Fable.Transforms/Replacements.Util.fs b/src/Fable.Transforms/Replacements.Util.fs index 610872fab8..94e98ab7a9 100644 --- a/src/Fable.Transforms/Replacements.Util.fs +++ b/src/Fable.Transforms/Replacements.Util.fs @@ -322,7 +322,6 @@ let (|BuiltinDefinition|_|) = | Types.dateOnly -> Some BclDateOnly | Types.timeOnly -> Some BclTimeOnly | "System.Timers.Timer" -> Some BclTimer - | Types.decimal | Types.fsharpSet -> Some(FSharpSet(Any)) | Types.fsharpMap -> Some(FSharpMap(Any, Any)) | Types.hashset -> Some(BclHashSet(Any)) diff --git a/src/Fable.Transforms/Replacements.fs b/src/Fable.Transforms/Replacements.fs index 691cbb4ec3..dfe79f9db1 100644 --- a/src/Fable.Transforms/Replacements.fs +++ b/src/Fable.Transforms/Replacements.fs @@ -1148,6 +1148,8 @@ let tryEntityIdent (com: Compiler) entFullName = makeImportLib com Any "AsyncReplyChannel" "AsyncBuilder" |> Some | "Microsoft.FSharp.Control.FSharpEvent`1" -> makeImportLib com Any "Event" "Event" |> Some | "Microsoft.FSharp.Control.FSharpEvent`2" -> makeImportLib com Any "Event$2" "Event" |> Some + | "Microsoft.FSharp.Core.CompilerServices.ListCollector`1" -> + makeImportLib com Any "ListCollector$1" "FSharp.Core.CompilerServices" |> Some | _ -> None let tryConstructor com (ent: Entity) = @@ -4566,6 +4568,7 @@ let private replacedModules = "Microsoft.FSharp.Collections.ListModule", listModule "Microsoft.FSharp.Collections.HashIdentity", fsharpModule "Microsoft.FSharp.Collections.ComparisonIdentity", fsharpModule + "Microsoft.FSharp.Core.CompilerServices.ListCollector`1", bclType "Microsoft.FSharp.Core.CompilerServices.RuntimeHelpers", seqModule "Microsoft.FSharp.Collections.SeqModule", seqModule Types.keyValuePair, keyValuePairs @@ -4672,7 +4675,6 @@ let private replacedModules = "Microsoft.FSharp.Control.ObservableModule", observable Types.type_, types "System.Reflection.TypeInfo", types - "Microsoft.FSharp.Core.CompilerServices.ListCollector`1", bclType ] let tryCall (com: ICompiler) (ctx: Context) r t (info: CallInfo) (thisArg: Expr option) (args: Expr list) = diff --git a/src/fable-library/FSharp.Core.CompilerServices.fs b/src/fable-library/FSharp.Core.CompilerServices.fs index cc14fa95ee..9482203c54 100644 --- a/src/fable-library/FSharp.Core.CompilerServices.fs +++ b/src/fable-library/FSharp.Core.CompilerServices.fs @@ -1,9 +1,6 @@ namespace Microsoft.FSharp.Core.CompilerServices -open Fable.Core - [] -[] type ListCollector<'T>() = let collector = ResizeArray<'T>() From 382b63a3c9271a0d2482ab824fde5eb9db210689 Mon Sep 17 00:00:00 2001 From: nojaf Date: Fri, 9 Feb 2024 10:43:08 +0100 Subject: [PATCH 3/7] Add unit test for ListCollector --- tests/Js/Main/Fable.Tests.fsproj | 1 + tests/Js/Main/ListCollectorTests.fs | 26 ++++++++++++++++++++++++++ tests/Js/Main/Main.fs | 1 + 3 files changed, 28 insertions(+) create mode 100644 tests/Js/Main/ListCollectorTests.fs diff --git a/tests/Js/Main/Fable.Tests.fsproj b/tests/Js/Main/Fable.Tests.fsproj index 2d3733bcf2..983cf5539c 100644 --- a/tests/Js/Main/Fable.Tests.fsproj +++ b/tests/Js/Main/Fable.Tests.fsproj @@ -78,6 +78,7 @@ + diff --git a/tests/Js/Main/ListCollectorTests.fs b/tests/Js/Main/ListCollectorTests.fs new file mode 100644 index 0000000000..70a4a61079 --- /dev/null +++ b/tests/Js/Main/ListCollectorTests.fs @@ -0,0 +1,26 @@ +module Fable.Tests.ListCollector + +open Util.Testing +open Fable.Tests.Util +open Microsoft.FSharp.Core.CompilerServices + +let cutOffLast list = + let mutable headList = ListCollector<'a>() + + let rec visit list = + match list with + | [] + | [ _ ] -> () + | head :: tail -> + headList.Add(head) + visit tail + + visit list + headList.Close() + +let tests = + testList "ListCollector" [ + testCase "ListCollector.Add and .Close" <| fun () -> + let result = cutOffLast [ 1; 2; 3 ] + result |> equal [ 1; 2 ] + ] diff --git a/tests/Js/Main/Main.fs b/tests/Js/Main/Main.fs index f145fe5341..17837f9aa3 100644 --- a/tests/Js/Main/Main.fs +++ b/tests/Js/Main/Main.fs @@ -50,6 +50,7 @@ let allTests = TypeTests.tests UnionTypes.tests Uri.tests + ListCollector.tests |] #if FABLE_COMPILER From a3ca9b3685f3b1739e884d2b87f776a5484055ae Mon Sep 17 00:00:00 2001 From: nojaf Date: Fri, 9 Feb 2024 10:44:05 +0100 Subject: [PATCH 4/7] Revert QuickTest.fs --- src/quicktest/QuickTest.fs | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/quicktest/QuickTest.fs b/src/quicktest/QuickTest.fs index f2f62b7188..7bd62ccbf2 100644 --- a/src/quicktest/QuickTest.fs +++ b/src/quicktest/QuickTest.fs @@ -98,14 +98,3 @@ printfn "Running quick tests..." // to Fable.Tests project. For example: // testCase "Addition works" <| fun () -> // 2 + 2 |> equal 4 - -open Microsoft.FSharp.Core.CompilerServices - -testCase - "meh" - (fun () -> - let c = ListCollector() - c.Add(1) - let r = c.Close() - ignore r - ) From 47ef3fe3544e58cc5668663556eb7dd8c7a67117 Mon Sep 17 00:00:00 2001 From: Maxime Mangel Date: Fri, 9 Feb 2024 11:49:46 +0100 Subject: [PATCH 5/7] Use 4 spaces for indentation --- tests/Js/Main/ListCollectorTests.fs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/Js/Main/ListCollectorTests.fs b/tests/Js/Main/ListCollectorTests.fs index 70a4a61079..958de83c98 100644 --- a/tests/Js/Main/ListCollectorTests.fs +++ b/tests/Js/Main/ListCollectorTests.fs @@ -19,8 +19,8 @@ let cutOffLast list = headList.Close() let tests = - testList "ListCollector" [ - testCase "ListCollector.Add and .Close" <| fun () -> - let result = cutOffLast [ 1; 2; 3 ] - result |> equal [ 1; 2 ] - ] + testList "ListCollector" [ + testCase "ListCollector.Add and .Close" <| fun () -> + let result = cutOffLast [ 1; 2; 3 ] + result |> equal [ 1; 2 ] + ] From f1aaedbfd1a16db898cf0dd14fc48d39ae34f6d3 Mon Sep 17 00:00:00 2001 From: Maxime Mangel Date: Fri, 9 Feb 2024 11:54:51 +0100 Subject: [PATCH 6/7] Cover more API in the tests for ListCollector --- tests/Js/Main/ListCollectorTests.fs | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/tests/Js/Main/ListCollectorTests.fs b/tests/Js/Main/ListCollectorTests.fs index 958de83c98..f4a9f83da9 100644 --- a/tests/Js/Main/ListCollectorTests.fs +++ b/tests/Js/Main/ListCollectorTests.fs @@ -1,7 +1,6 @@ module Fable.Tests.ListCollector open Util.Testing -open Fable.Tests.Util open Microsoft.FSharp.Core.CompilerServices let cutOffLast list = @@ -23,4 +22,32 @@ let tests = testCase "ListCollector.Add and .Close" <| fun () -> let result = cutOffLast [ 1; 2; 3 ] result |> equal [ 1; 2 ] + + testCase "ListCollector.Close works for empty list" <| fun () -> + let mutable l = ListCollector<_>() + let result = l.Close() + + result |> equal [] + + testCase "ListCollector.AddMany works" <| fun () -> + let mutable l = ListCollector<_>() + l.AddMany([ 1; 2; 3 ]) + + let result = l.Close() + + result |> equal [ 1; 2; 3 ] + + testCase "ListCollector.AddMany works for empty list" <| fun () -> + let mutable l = ListCollector<_>() + l.AddMany([]) + + let result = l.Close() + + result |> equal [] + + testCase "ListCollector.AddManyAndClose works" <| fun () -> + let mutable l = ListCollector<_>() + let result = l.AddManyAndClose([ 1; 2; 3 ]) + + result |> equal [ 1; 2; 3 ] ] From 320819b24816ec92f5d75a23ccb965d6c4023005 Mon Sep 17 00:00:00 2001 From: Maxime Mangel Date: Fri, 9 Feb 2024 12:02:38 +0100 Subject: [PATCH 7/7] Update the changelog --- src/Fable.Cli/CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Fable.Cli/CHANGELOG.md b/src/Fable.Cli/CHANGELOG.md index 4045e8036a..76491ea2c1 100644 --- a/src/Fable.Cli/CHANGELOG.md +++ b/src/Fable.Cli/CHANGELOG.md @@ -27,6 +27,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * `Result.ToList` * `Result.ToOption` +#### JavaScript + +* [GH-3745](https://github.com/fable-compiler/Fable/pull/3745) Add support for `ListCollector` (by @nojaf) + * `instance.Add` + * `instance.AddMany` + * `instance.AddManyAndClose` + * `instance.Close` + ### Removed #### JavaScript