Skip to content

Commit

Permalink
Support ValueOption module
Browse files Browse the repository at this point in the history
  • Loading branch information
alfonsogarciacaro committed Nov 23, 2022
1 parent 0696acd commit 5b806eb
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 11 deletions.
18 changes: 10 additions & 8 deletions src/Fable.Transforms/Dart/Replacements.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1484,17 +1484,18 @@ let nullables (com: ICompiler) (_: Context) r (t: Type) (i: CallInfo) (thisArg:
| "get_HasValue", Some c -> makeEqOp r c (makeNull()) BinaryUnequal |> Some
| _ -> None

// See fable-library/Option.ts for more info on how options behave in Fable runtime
let options (com: ICompiler) (_: Context) r (t: Type) (i: CallInfo) (thisArg: Expr option) (args: Expr list) =
let options isStruct (com: ICompiler) (_: Context) r (t: Type) (i: CallInfo) (thisArg: Expr option) (args: Expr list) =
match i.CompiledName, thisArg with
| "get_None", _ -> NewOption(None, t.Generics.Head, isStruct) |> makeValue r |> Some
| "Some", _ -> NewOption(List.tryHead args, t.Generics.Head, isStruct) |> makeValue r |> Some
| "get_Value", Some c -> getOptionValue r t c |> Some
| "get_IsSome", Some c -> Test(c, OptionTest true, r) |> Some
| "get_IsNone", Some c -> Test(c, OptionTest false, r) |> Some
| _ -> None

let optionModule (com: ICompiler) (ctx: Context) r (t: Type) (i: CallInfo) (_: Expr option) (args: Expr list) =
let optionModule isStruct (com: ICompiler) (ctx: Context) r (t: Type) (i: CallInfo) (_: Expr option) (args: Expr list) =
match i.CompiledName, args with
| "None", _ -> NewOption(None, t, false) |> makeValue r |> Some
| "None", _ -> NewOption(None, t, isStruct) |> makeValue r |> Some
| "GetValue", [c] -> getOptionValue r t c |> Some
| "IsSome", [c] -> Test(c, OptionTest true, r) |> Some
| "IsNone", [c] -> Test(c, OptionTest false, r) |> Some
Expand Down Expand Up @@ -2708,10 +2709,11 @@ let private replacedModules =
Types.queue, bclType
Types.iset, hashSets
Types.idisposable, disposables
Types.option, options
Types.valueOption, options
Types.option, options false
Types.valueOption, options true
"System.Nullable`1", nullables
"Microsoft.FSharp.Core.OptionModule", optionModule
"Microsoft.FSharp.Core.OptionModule", optionModule false
"Microsoft.FSharp.Core.ValueOption", optionModule true
"Microsoft.FSharp.Core.ResultModule", results
Types.bigint, bigints
"Microsoft.FSharp.Core.NumericLiterals.NumericLiteralI", bigints
Expand Down Expand Up @@ -2892,7 +2894,7 @@ let tryType = function
Some(getNumberFullName false kind info, f, [])
| String -> Some(Types.string, strings, [])
| Tuple(genArgs, _) as t -> Some(getTypeFullName false t, tuples, genArgs)
| Option(genArg, _) -> Some(Types.option, options, [genArg])
| Option(genArg, isStruct) -> Some(Types.option, options isStruct, [genArg])
| Array(genArg,_) -> Some(Types.array, arrays, [genArg])
| List genArg -> Some(Types.list, lists, [genArg])
| Builtin kind ->
Expand Down
7 changes: 4 additions & 3 deletions src/Fable.Transforms/Replacements.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1687,11 +1687,11 @@ let options isStruct (com: ICompiler) (_: Context) r (t: Type) (i: CallInfo) (th
| "get_IsNone", Some c -> Test(c, OptionTest false, r) |> Some
| _ -> None

let optionModule (com: ICompiler) (ctx: Context) r (t: Type) (i: CallInfo) (_: Expr option) (args: Expr list) =
let optionModule isStruct (com: ICompiler) (ctx: Context) r (t: Type) (i: CallInfo) (_: Expr option) (args: Expr list) =
let toArray r t arg =
Helper.LibCall(com, "Option", "toArray", Array(t, MutableArray), [arg], ?loc=r)
match i.CompiledName, args with
| "None", _ -> NewOption(None, t, false) |> makeValue r |> Some
| "None", _ -> NewOption(None, t, isStruct) |> makeValue r |> Some
| "GetValue", [c] ->
Helper.LibCall(com, "Option", "value", t, args, ?loc=r) |> Some
| ("OfObj" | "OfNullable"), _ ->
Expand Down Expand Up @@ -2900,7 +2900,8 @@ let private replacedModules =
Types.option, options false
Types.valueOption, options true
"System.Nullable`1", nullables
"Microsoft.FSharp.Core.OptionModule", optionModule
"Microsoft.FSharp.Core.OptionModule", optionModule false
"Microsoft.FSharp.Core.ValueOption", optionModule true
"Microsoft.FSharp.Core.ResultModule", results
Types.bigint, bigints
"Microsoft.FSharp.Core.NumericLiterals.NumericLiteralI", bigints
Expand Down
16 changes: 16 additions & 0 deletions tests/Dart/src/OptionTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,14 @@ let tests() =
Option.isNone o2 |> equal false
Option.isSome o2 |> equal true

testCase "ValueOption.isSome/isNone works" <| fun () ->
let o1: int voption = ValueNone
let o2 = ValueSome 5
ValueOption.isNone o1 |> equal true
ValueOption.isSome o1 |> equal false
ValueOption.isNone o2 |> equal false
ValueOption.isSome o2 |> equal true

testCase "Option.IsSome/IsNone works" <| fun () ->
let o1: int option = None
let o2 = Some 5
Expand All @@ -82,6 +90,14 @@ let tests() =
o2.IsNone |> equal false
o2.IsSome |> equal true

testCase "ValueOption.IsSome/IsNone works" <| fun () ->
let o1: int voption = ValueNone
let o2 = Some 5
o1.IsNone |> equal true
o1.IsSome |> equal false
o2.IsNone |> equal false
o2.IsSome |> equal true

testCase "Option.iter works" <| fun () -> // See #198
let mutable res = false
let getOnlyOnce =
Expand Down
16 changes: 16 additions & 0 deletions tests/Js/Main/OptionTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,14 @@ let tests =
Option.isNone o2 |> equal false
Option.isSome o2 |> equal true

testCase "ValueOption.isSome/isNone works" <| fun () ->
let o1: int voption = ValueNone
let o2 = ValueSome 5
ValueOption.isNone o1 |> equal true
ValueOption.isSome o1 |> equal false
ValueOption.isNone o2 |> equal false
ValueOption.isSome o2 |> equal true

testCase "Option.IsSome/IsNone works" <| fun () ->
let o1 = None
let o2 = Some 5
Expand All @@ -88,6 +96,14 @@ let tests =
o2.IsNone |> equal false
o2.IsSome |> equal true

testCase "ValueOption.IsSome/IsNone works" <| fun () ->
let o1: int voption = ValueNone
let o2 = Some 5
o1.IsNone |> equal true
o1.IsSome |> equal false
o2.IsNone |> equal false
o2.IsSome |> equal true

testCase "Option.iter works" <| fun () -> // See #198
let mutable res = false
let getOnlyOnce =
Expand Down

0 comments on commit 5b806eb

Please sign in to comment.