Skip to content

Commit

Permalink
Fixes #3847 (#3852)
Browse files Browse the repository at this point in the history
  • Loading branch information
ncave authored Jun 15, 2024
1 parent de7d3fa commit 914ab37
Show file tree
Hide file tree
Showing 18 changed files with 1,895 additions and 215 deletions.
4 changes: 4 additions & 0 deletions src/Fable.Cli/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## Unreleased

### Fixed

* [JS/TS] Fixed unwrapping optional arguments (#3847) (by @ncave)

## 4.19.2 - 2024-06-13

### Fixed
Expand Down
8 changes: 4 additions & 4 deletions src/Fable.Transforms/Fable2Babel.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1891,10 +1891,10 @@ module Util =

let args =
match paramsInfo with
| Some i when List.sameLength args i.Parameters ->
List.zip args i.Parameters
|> List.map (fun (a, i) ->
if i.IsOptional then
| Some info when args.Length <= info.Parameters.Length ->
List.zipSafe args info.Parameters
|> List.map (fun (a, p) ->
if p.IsOptional then
unwrapOptionalArg com a |> snd
else
a
Expand Down
2 changes: 1 addition & 1 deletion src/Fable.Transforms/Rust/AST/Rust.AST.Adapters.fs
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ module fmt =
type Macros =
static member assert_eq(actual, expected) = assert (actual = expected)
static member assert_ne(actual, expected) = assert (actual <> expected)
static member unreachable() = failwith "should not happen"
static member unreachable() = failwith "unreachable!"
static member panic() = failwith "panic!"
static member panic(str: string) = failwith str

Expand Down
19 changes: 17 additions & 2 deletions src/Fable.Transforms/Rust/Fable2Rust.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1615,6 +1615,21 @@ module Util =
// let rest = List.rev rest |> List.map (fun e -> com.TransformExpr(ctx, e))
// rest @ [Expression.spreadElement(com.TransformExpr(ctx, last))]
| args ->
let optionalArgs =
if args.Length < parameters.Length then
parameters
|> List.skip args.Length
|> List.filter (fun p -> p.IsOptional)
|> List.map (fun p ->
match p.Type with
| Fable.Option(t, isStruct) -> Fable.Value(Fable.NewOption(None, t, isStruct), None)
| _ -> failwith "unreachable"
)
else
[]

let args = List.append args optionalArgs

let argsWithTypes =
if argTypes.Length = args.Length then
args |> List.zip argTypes |> List.map (fun (t, a) -> Some t, a)
Expand Down Expand Up @@ -2877,7 +2892,7 @@ module Util =
|> prepareRefForPatternMatch com ctx fableExpr.Type (tryGetIdentName fableExpr)

mkLetExpr pat expr
| _ -> failwith "Should not happen"
| _ -> failwith "unreachable"

let transformTest (com: IRustCompiler) ctx range kind (fableExpr: Fable.Expr) : Rust.Expr =
match kind with
Expand Down Expand Up @@ -2923,7 +2938,7 @@ module Util =
let thenExpr = mkBoolLitExpr true
let elseExpr = mkBoolLitExpr false
mkIfThenElseExpr guardExpr thenExpr elseExpr
| _ -> failwith "Should not happen"
| _ -> failwith "unreachable"

let transformSwitch (com: IRustCompiler) ctx (evalExpr: Fable.Expr) cases defaultCase targets : Rust.Expr =
let namesForIndex evalType evalName caseIndex = //todo refactor with below
Expand Down
8 changes: 3 additions & 5 deletions src/Fable.Transforms/Transforms.Util.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1265,11 +1265,9 @@ module AST =
| None -> args, []
| Some index when index > args.Length || index > info.Parameters.Length -> args, []
| Some index ->
let args, namedValues = List.splitAt index args

let namedKeys = List.skip index info.Parameters |> List.truncate namedValues.Length

args, List.zipSafe namedKeys namedValues
let args, namedArgs = List.splitAt index args
let namedParams = List.skip index info.Parameters |> List.truncate namedArgs.Length
args, List.zipSafe namedParams namedArgs

/// Used to compare arg idents of a lambda wrapping a function call
let argEquals (argIdents: Ident list) argExprs =
Expand Down
2 changes: 2 additions & 0 deletions tests/Dart/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import './src/SudokuTests.dart' as sudoku;
import './src/TailCallTests.dart' as tailcall;
import './src/TimeSpanTests.dart' as timespan;
import './src/TupleTests.dart' as tuple;
import './src/TypeTests.dart' as type_;
import './src/UnionTests.dart' as union;

void main() {
Expand Down Expand Up @@ -51,5 +52,6 @@ void main() {
tailcall.tests();
timespan.tests();
tuple.tests();
type_.tests();
union.tests();
}
1 change: 1 addition & 0 deletions tests/Dart/src/Fable.Tests.Dart.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
<Compile Include="TailCallTests.fs" />
<Compile Include="TimeSpanTests.fs" />
<Compile Include="TupleTests.fs" />
<Compile Include="TypeTests.fs" />
<Compile Include="UnionTests.fs" />
<Content Include="..\main.dart" />
</ItemGroup>
Expand Down
22 changes: 22 additions & 0 deletions tests/Dart/src/RecordTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,28 @@ let tests() =
// x = {| y with Baz = 23 |} |> equal true // Doesn't compile
x = {| y with Bar = 14 |} |> equal false

testCase "Anonymous records can have optional fields" <| fun () ->
let add (o: {| bar: int option; zas: string option; foo: int option option |}) =
let bar = o.bar |> Option.map string |> Option.defaultValue "-"
let zas = defaultArg o.zas ""
let foo = match o.foo with Some(Some i) -> string i | Some None -> "xx" | None -> "x"
bar + zas + foo

{| bar = Some 3; zas = Some "ooooo"; foo = Some None |} |> add |> equal "3oooooxx"
{| bar = Some 22; zas = Some ""; foo = Some(Some 999) |} |> add |> equal "22999"
{| bar = None; zas = None; foo = None |} |> add |> equal "-x"
{| foo = Some None; bar = None; zas = None |} |> add |> equal "-xx"

testCase "Anonymous records can have optional function fields" <| fun () ->
let add (o: {| bar: (int -> int -> int) option; foo: int -> int -> int |}) =
let fn = o.bar
let f1 = fn |> Option.map (fun f -> f 6 9) |> Option.defaultValue -3
let f2 = match fn with Some f -> f 1 8 | None -> -5
o.foo 3 4 + f1 + f2

{| bar = Some (+); foo = (*) |} |> add |> equal 36
{| bar = None; foo = (+) |} |> add |> equal -1

testCase "SRTP works with anonymous records" <| fun () ->
let ar = [| {|Id=Id"foo"; Name="Sarah"|}; {|Id=Id"bar"; Name="James"|} |]
replaceById {|Id=Id"ja"; Name="Voll"|} ar |> Seq.head |> fun x -> equal "Sarah" x.Name
Expand Down
Loading

0 comments on commit 914ab37

Please sign in to comment.