diff --git a/src/Fable.Cli/CHANGELOG.md b/src/Fable.Cli/CHANGELOG.md index 931a5c3807..234c887d11 100644 --- a/src/Fable.Cli/CHANGELOG.md +++ b/src/Fable.Cli/CHANGELOG.md @@ -103,6 +103,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * `DateTime.TryParse` * `DateTime.SpecifyKind` +#### JavaScript + +* [GH-3715](https://github.com/fable-compiler/Fable/pull/3715) Add support for System.Array.Resize (by @chkn) + ## 4.9.0 - 2023-12-14 ### Fixed diff --git a/src/Fable.Transforms/Replacements.fs b/src/Fable.Transforms/Replacements.fs index 869492802c..8b1cc6f0b3 100644 --- a/src/Fable.Transforms/Replacements.fs +++ b/src/Fable.Transforms/Replacements.fs @@ -3369,6 +3369,22 @@ let arrays ) |> Some | "GetEnumerator", Some arg, _ -> getEnumerator com r t arg |> Some + | "Resize", None, args -> + let args = + args @ [ getZero com ctx (List.head i.GenericArgs) ] + |> injectArg com ctx r "Array" "resize" i.GenericArgs + + Helper.LibCall( + com, + "Array", + "resize", + Unit, + args, + i.SignatureArgTypes, + genArgs = i.GenericArgs, + ?loc = r + ) + |> Some | _ -> None let arrayModule diff --git a/src/Fable.Transforms/ReplacementsInject.fs b/src/Fable.Transforms/ReplacementsInject.fs index 5d82a60edf..3a08d22ef8 100644 --- a/src/Fable.Transforms/ReplacementsInject.fs +++ b/src/Fable.Transforms/ReplacementsInject.fs @@ -50,6 +50,7 @@ let fableReplacementsModules = "insertAt", (Types.arrayCons, 0) "insertManyAt", (Types.arrayCons, 0) "updateAt", (Types.arrayCons, 0) + "resize", (Types.arrayCons, 0) ] "List", Map diff --git a/src/fable-library/Array.fs b/src/fable-library/Array.fs index c990c2ea89..668adb6e5a 100644 --- a/src/fable-library/Array.fs +++ b/src/fable-library/Array.fs @@ -1405,3 +1405,29 @@ let updateAt xs.[i] target + +let resize + (xs: byref<'T[]>) + (newSize: int) + ([] zero: 'T option) + ([] cons: Cons<'T>) + : unit + = + if newSize < 0 then + invalidArg "newSize" "The input must be non-negative." + + let len = xs.Length + + if newSize < len then + xs <- subArrayImpl xs 0 newSize + + elif newSize > len then + let target = allocateArrayFromCons cons newSize + copyTo xs 0 target 0 len + + xs <- + fillImpl + target + (defaultArg zero Unchecked.defaultof<_>) + len + (newSize - len) diff --git a/tests/Js/Main/ArrayTests.fs b/tests/Js/Main/ArrayTests.fs index ad5552b7f7..2d3d3d5792 100644 --- a/tests/Js/Main/ArrayTests.fs +++ b/tests/Js/Main/ArrayTests.fs @@ -1190,4 +1190,13 @@ let tests = equal c1 true equal c2 -1 equal c3 1 + + testCase "Array.Resize works" <| fun () -> + let mutable xs = [|1; 2; 3; 4; 5|] + Array.Resize(&xs, 3) + xs |> equal [|1; 2; 3|] + Array.Resize(&xs, 7) + xs |> equal [|1; 2; 3; 0; 0; 0; 0|] + Array.Resize(&xs, 0) + xs |> equal [||] ]