Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 13 additions & 15 deletions src/Fable.Transforms/Fable2Babel.fs
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ module Reflection =
| Fable.Array _ | Fable.Tuple _ ->
libCall com ctx None "Util" "isArrayLike" [|com.TransformAsExpr(ctx, expr)|]
| Fable.List _ ->
jsInstanceof (libValue com ctx "Types" "List") expr
jsInstanceof (libValue com ctx "List" "FSharpList") expr
| Fable.AnonymousRecordType _ ->
warnAndEvalToFalse "anonymous records"
| Fable.MetaType ->
Expand Down Expand Up @@ -435,7 +435,7 @@ module Annotation =
makeNativeTypeAnnotation com ctx [genArg] "Array"

let makeListTypeAnnotation com ctx genArg =
makeImportTypeAnnotation com ctx [genArg] "Types" "List"
makeImportTypeAnnotation com ctx [genArg] "List" "List"

let makeUnionTypeAnnotation com ctx genArgs =
List.map (typeAnnotation com ctx) genArgs
Expand Down Expand Up @@ -662,12 +662,6 @@ module Util =
| [] -> expr
| m::ms -> get None expr m |> getParts ms

let makeList com ctx r headAndTail =
match headAndTail with
| None -> [||]
| Some(TransformExpr com ctx head, TransformExpr com ctx tail) -> [|head; tail|]
|> libConsCall com ctx r "Types" "List"

let makeArray (com: IBabelCompiler) ctx exprs =
List.mapToArray (fun e -> com.TransformAsExpr(ctx, e)) exprs
|> Expression.arrayExpression
Expand Down Expand Up @@ -933,8 +927,8 @@ module Util =
| Fable.NewArray (values, typ) -> makeTypedArray com ctx typ values
| Fable.NewArrayFrom (size, typ) -> makeTypedAllocatedFrom com ctx typ size
| Fable.NewTuple vals -> makeArray com ctx vals
| Fable.NewList (headAndTail, _) when List.contains "FABLE_LIBRARY" com.Options.Define ->
makeList com ctx r headAndTail
// | Fable.NewList (headAndTail, _) when List.contains "FABLE_LIBRARY" com.Options.Define ->
// makeList com ctx r headAndTail
// Optimization for bundle size: compile list literals as List.ofArray
| Fable.NewList (headAndTail, _) ->
let rec getItems acc = function
Expand Down Expand Up @@ -988,7 +982,7 @@ module Util =

let enumerator2iterator com ctx =
let enumerator = Expression.callExpression(get None (Expression.identifier("this")) "GetEnumerator", [||])
BlockStatement([| Statement.returnStatement(libCall com ctx None "Seq" "toIterator" [|enumerator|])|])
BlockStatement([| Statement.returnStatement(libCall com ctx None "Util" "toIterator" [|enumerator|])|])

let extractBaseExprFromBaseCall (com: IBabelCompiler) (ctx: Context) (baseType: Fable.DeclaredType option) baseCall =
match baseCall, baseType with
Expand Down Expand Up @@ -1206,10 +1200,12 @@ module Util =
| Fable.FieldKey field -> get range expr field.Name

| Fable.ListHead ->
get range (com.TransformAsExpr(ctx, fableExpr)) "head"
// get range (com.TransformAsExpr(ctx, fableExpr)) "head"
libCall com ctx range "List" "head" [|com.TransformAsExpr(ctx, fableExpr)|]

| Fable.ListTail ->
get range (com.TransformAsExpr(ctx, fableExpr)) "tail"
// get range (com.TransformAsExpr(ctx, fableExpr)) "tail"
libCall com ctx range "List" "tail" [|com.TransformAsExpr(ctx, fableExpr)|]

| Fable.TupleIndex index ->
match fableExpr with
Expand Down Expand Up @@ -1274,8 +1270,10 @@ module Util =
Expression.binaryExpression(op, com.TransformAsExpr(ctx, expr), Expression.nullLiteral(), ?loc=range)
| Fable.ListTest nonEmpty ->
let expr = com.TransformAsExpr(ctx, expr)
let op = if nonEmpty then BinaryUnequal else BinaryEqual
Expression.binaryExpression(op, get None expr "tail", Expression.nullLiteral(), ?loc=range)
// let op = if nonEmpty then BinaryUnequal else BinaryEqual
// Expression.binaryExpression(op, get None expr "tail", Expression.nullLiteral(), ?loc=range)
let expr = libCall com ctx range "List" "isEmpty" [|expr|]
if nonEmpty then Expression.unaryExpression(UnaryNot, expr, ?loc=range) else expr
| Fable.UnionCaseTest tag ->
let expected = ofInt tag
let actual = com.TransformAsExpr(ctx, expr) |> getUnionExprTag None
Expand Down
128 changes: 43 additions & 85 deletions src/Fable.Transforms/Replacements.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1372,12 +1372,12 @@ let operators (com: ICompiler) (ctx: Context) r t (i: CallInfo) (thisArg: Expr o
| _ -> args
let modul, meth, args =
match genArg with
| Char -> "Seq", "rangeChar", args
| Builtin BclInt64 -> "Seq", "rangeLong", (addStep args) @ [makeBoolConst false]
| Builtin BclUInt64 -> "Seq", "rangeLong", (addStep args) @ [makeBoolConst true]
| Builtin BclDecimal -> "Seq", "rangeDecimal", addStep args
| Builtin BclBigInt -> "BigInt", "range", addStep args
| _ -> "Seq", "rangeNumber", addStep args
| Char -> "Range", "rangeChar", args
| Builtin BclInt64 -> "Range", "rangeInt64", addStep args
| Builtin BclUInt64 -> "Range", "rangeUInt64", addStep args
| Builtin BclDecimal -> "Range", "rangeDecimal", addStep args
| Builtin BclBigInt -> "Range", "rangeBigInt", addStep args
| _ -> "Range", "rangeDouble", addStep args
Helper.LibCall(com, modul, meth, t, args, i.SignatureArgTypes, ?loc=r) |> Some
// Pipes and composition
| "op_PipeRight", [x; f]
Expand Down Expand Up @@ -1542,7 +1542,7 @@ let implementedStringFunctions =
|]

let getEnumerator com r t expr =
Helper.LibCall(com, "Seq", "getEnumerator", t, [toSeq Any expr], ?loc=r)
Helper.LibCall(com, "Util", "getEnumerator", t, [toSeq Any expr], ?loc=r)

let strings (com: ICompiler) (ctx: Context) r t (i: CallInfo) (thisArg: Expr option) (args: Expr list) =
match i.CompiledName, thisArg, args with
Expand Down Expand Up @@ -1660,51 +1660,13 @@ let stringModule (com: ICompiler) (ctx: Context) r t (i: CallInfo) (_: Expr opti
| meth, args ->
Helper.LibCall(com, "String", Naming.lowerFirst meth, t, args, i.SignatureArgTypes, ?loc=r) |> Some

let seqs (com: ICompiler) (ctx: Context) r (t: Type) (i: CallInfo) (thisArg: Expr option) (args: Expr list) =
let sort r returnType descending projection args genArg =
let compareFn =
let identExpr ident =
match projection with
| Some projection ->
let info = makeCallInfo None [IdentExpr ident] []
Call(projection, info, genArg, None)
| None -> IdentExpr ident
let x = makeUniqueIdent ctx genArg "x"
let y = makeUniqueIdent ctx genArg "y"
let comparison =
let comparison = compare com ctx None (identExpr x) (identExpr y)
if descending
then makeUnOp None (Number Int32) comparison UnaryMinus
else comparison
Delegate([x; y], comparison, None)
Helper.LibCall(com, "Seq", "sortWith", returnType, compareFn::args, ?loc=r) |> Some

let seqModule (com: ICompiler) (ctx: Context) r (t: Type) (i: CallInfo) (thisArg: Expr option) (args: Expr list) =
match i.CompiledName, args with
| "Cast", [arg] -> Some arg // Erase
| ("Cache" | "ToArray"), [arg] -> toArray r t arg |> Some
| "OfList", [arg] -> toSeq t arg |> Some
| "ToList", _ -> Helper.LibCall(com, "List", "ofSeq", t, args, i.SignatureArgTypes, ?loc=r) |> Some
| ("ChunkBySize" | "Permute" | "SplitInto") as meth, [arg1; arg2] ->
let arg2 = toArray r (Array Any) arg2
let result = Helper.LibCall(com, "Array", Naming.lowerFirst meth, Any, [arg1; arg2])
Helper.LibCall(com, "Seq", "ofArray", t, [result]) |> Some
// For Using we need to cast the argument to IDisposable
| "EnumerateUsing", [arg; f] ->
Helper.LibCall(com, "Seq", "enumerateUsing", t, [arg; f], i.SignatureArgTypes, ?loc=r) |> Some
| ("Sort" | "SortDescending" as meth), args ->
(genArg com ctx r 0 i.GenericArgs) |> sort r t (meth = "SortDescending") None args
| ("SortBy" | "SortByDescending" as meth), projection::args ->
(genArg com ctx r 1 i.GenericArgs) |> sort r t (meth = "SortByDescending") (Some projection) args
| ("GroupBy" | "CountBy" as meth), args ->
let meth = Naming.lowerFirst meth
let args = injectArg com ctx r "Map" meth i.GenericArgs args
Helper.LibCall(com, "Map", meth, t, args, i.SignatureArgTypes, ?loc=r) |> Some
| ("Distinct" | "DistinctBy" as meth), args ->
| ("Distinct" | "DistinctBy" | "Except" | "GroupBy" | "CountBy" as meth), args ->
let meth = Naming.lowerFirst meth
let args = injectArg com ctx r "Set" meth i.GenericArgs args
Helper.LibCall(com, "Set", meth, t, args, i.SignatureArgTypes, ?loc=r) |> Some
| "TryExactlyOne", args ->
tryCoreOp com r t "Seq" "exactlyOne" args |> Some
let args = injectArg com ctx r "Seq2" meth i.GenericArgs args
Helper.LibCall(com, "Seq2", meth, t, args, i.SignatureArgTypes, ?loc=r) |> Some
| meth, _ ->
let meth = Naming.lowerFirst meth
let args = injectArg com ctx r "Seq" meth i.GenericArgs args
Expand Down Expand Up @@ -1749,16 +1711,16 @@ let resizeArrays (com: ICompiler) (ctx: Context) r (t: Type) (i: CallInfo) (this
| "Clear", Some ar, _ ->
Helper.LibCall(com, "Util", "clear", t, [ar], ?loc=r) |> Some
| "Find", Some ar, [arg] ->
let opt = Helper.LibCall(com, "Seq", "tryFind", t, [arg; ar; defaultof com ctx t], ?loc=r)
Helper.LibCall(com, "Option", "value", t, [opt], ?loc=r) |> Some
let opt = Helper.LibCall(com, "Array", "tryFind", t, [arg; ar], ?loc=r)
Helper.LibCall(com, "Option", "defaultArg", t, [opt; defaultof com ctx t], ?loc=r) |> Some
| "Exists", Some ar, [arg] ->
let left = Helper.InstanceCall(ar, "findIndex", Number Int32, [arg], ?loc=r)
makeEqOp r left (makeIntConst -1) BinaryGreater |> Some
| "FindLast", Some ar, [arg] ->
let opt = Helper.LibCall(com, "Seq", "tryFindBack", t, [arg; ar; defaultof com ctx t], ?loc=r)
Helper.LibCall(com, "Option", "value", t, [opt], ?loc=r) |> Some
let opt = Helper.LibCall(com, "Array", "tryFindBack", t, [arg; ar], ?loc=r)
Helper.LibCall(com, "Option", "defaultArg", t, [opt; defaultof com ctx t], ?loc=r) |> Some
| "FindAll", Some ar, [arg] ->
Helper.LibCall(com, "Seq", "filter", t, [arg; ar], ?loc=r) |> toArray r t |> Some
Helper.LibCall(com, "Array", "filter", t, [arg; ar], ?loc=r) |> Some
| "AddRange", Some ar, [arg] ->
Helper.LibCall(com, "Array", "addRangeInPlace", t, [arg; ar], ?loc=r) |> Some
| "GetRange", Some ar, [idx; cnt] ->
Expand Down Expand Up @@ -1845,8 +1807,10 @@ let arrayModule (com: ICompiler) (ctx: Context) r (t: Type) (i: CallInfo) (_: Ex
match i.CompiledName, args with
| "ToSeq", [arg] -> Some arg
| "OfSeq", [arg] -> toArray r t arg |> Some
| "OfList", [arg] -> toArray r t arg |> Some
| "ToList", _ -> Helper.LibCall(com, "List", "ofArray", t, args, i.SignatureArgTypes, ?loc=r) |> Some
| "OfList", [arg] ->
Helper.LibCall(com, "List", "toArray", t, args, i.SignatureArgTypes, ?loc=r) |> Some
| "ToList", args ->
Helper.LibCall(com, "List", "ofArray", t, args, i.SignatureArgTypes, ?loc=r) |> Some
| ("Length" | "Count"), [arg] -> get r t arg "length" |> Some
| "Item", [idx; ar] -> getExpr r t ar idx |> Some
| "Get", [ar; idx] -> getExpr r t ar idx |> Some
Expand All @@ -1858,22 +1822,16 @@ let arrayModule (com: ICompiler) (ctx: Context) r (t: Type) (i: CallInfo) (_: Ex
newArray (makeIntConst 0) t |> Some
| "IsEmpty", [ar] ->
eq (get r (Number Int32) ar "length") (makeIntConst 0) |> Some
| "AllPairs", args ->
let allPairs = Helper.LibCall(com, "Seq", "allPairs", t, args, i.SignatureArgTypes, ?loc=r)
toArray r t allPairs |> Some
| "TryExactlyOne", args ->
tryCoreOp com r t "Array" "exactlyOne" args |> Some
| "SortInPlace", args ->
let _, thisArg = List.splitLast args
let argTypes = List.take (List.length args) i.SignatureArgTypes
let compareFn = (genArg com ctx r 0 i.GenericArgs) |> makeComparerFunction com ctx
Helper.InstanceCall(thisArg, "sort", t, [compareFn], argTypes, ?loc=r) |> Some
| "CopyTo", args ->
copyToArray com r t i args
| Patterns.DicContains nativeArrayFunctions meth, _ ->
let args, thisArg = List.splitLast args
let argTypes = List.take (List.length args) i.SignatureArgTypes
Helper.InstanceCall(thisArg, meth, t, args, argTypes, ?loc=r) |> Some
| ("Distinct" | "DistinctBy" | "Except" | "GroupBy" | "CountBy" as meth), args ->
let meth = Naming.lowerFirst meth
let args = injectArg com ctx r "Seq2" meth i.GenericArgs args
Helper.LibCall(com, "Seq2", "Array_" + meth, t, args, i.SignatureArgTypes, ?loc=r) |> Some
| meth, _ ->
let meth = Naming.lowerFirst meth
let args = injectArg com ctx r "Array" meth i.GenericArgs args
Expand Down Expand Up @@ -1906,12 +1864,10 @@ let listModule (com: ICompiler) (ctx: Context) r (t: Type) (i: CallInfo) (_: Exp
// Use a cast to give it better chances of optimization (e.g. converting list
// literals to arrays) after the beta reduction pass
| "ToSeq", [x] -> toSeq t x |> Some
| "ToArray", [x] -> toArray r t x |> Some
| "AllPairs", args ->
let allPairs = Helper.LibCall(com, "Seq", "allPairs", t, args, i.SignatureArgTypes, ?loc=r)
toList com t allPairs |> Some
| "TryExactlyOne", args ->
tryCoreOp com r t "List" "exactlyOne" args |> Some
| ("Distinct" | "DistinctBy" | "Except" | "GroupBy" | "CountBy" as meth), args ->
let meth = Naming.lowerFirst meth
let args = injectArg com ctx r "Seq2" meth i.GenericArgs args
Helper.LibCall(com, "Seq2", "List_" + meth, t, args, i.SignatureArgTypes, ?loc=r) |> Some
| meth, _ ->
let meth = Naming.lowerFirst meth
let args = injectArg com ctx r "List" meth i.GenericArgs args
Expand Down Expand Up @@ -1989,19 +1945,20 @@ let optionModule (com: ICompiler) (ctx: Context) r (t: Type) (i: CallInfo) (_: E
Helper.LibCall(com, "Option", Naming.lowerFirst meth, t, args, i.SignatureArgTypes, ?loc=r) |> Some
| "ToArray", [arg] ->
toArray r t arg |> Some
| "ToList", [arg] ->
let args = args |> List.replaceLast (toArray None t)
Helper.LibCall(com, "List", "ofArray", t, args, ?loc=r) |> Some
| "FoldBack", [folder; opt; state] ->
Helper.LibCall(com, "Seq", "foldBack", t, [folder; toArray None t opt; state], i.SignatureArgTypes, ?loc=r) |> Some
| ("DefaultValue" | "OrElse"), _ ->
Helper.LibCall(com, "Option", "defaultArg", t, List.rev args, ?loc=r) |> Some
| ("DefaultWith" | "OrElseWith"), _ ->
Helper.LibCall(com, "Option", "defaultArgWith", t, List.rev args, List.rev i.SignatureArgTypes, ?loc=r) |> Some
| ("Count" | "Contains" | "Exists" | "Fold" | "ForAll" | "Iterate" | "ToList" as meth), _ ->
| ("Count" | "Contains" | "Exists" | "Fold" | "ForAll" | "Iterate" as meth), _ ->
let meth = Naming.lowerFirst meth
let args = args |> List.replaceLast (toArray None t)
let moduleName, meth =
if meth = "ToList"
then "List", "ofArray"
else "Seq", Naming.lowerFirst meth
Helper.LibCall(com, moduleName, meth, t, args, i.SignatureArgTypes, ?loc=r) |> Some
let args = injectArg com ctx r "Seq" meth i.GenericArgs args
Helper.LibCall(com, "Seq", meth, t, args, i.SignatureArgTypes, ?loc=r) |> Some
| _ -> None

let parseBool (com: ICompiler) (ctx: Context) r t (i: CallInfo) (thisArg: Expr option) (args: Expr list) =
Expand Down Expand Up @@ -2266,18 +2223,19 @@ let intrinsicFunctions (com: ICompiler) (ctx: Context) r t (i: CallInfo) (thisAr
// Type: RangeChar : char -> char -> seq<char>
// Usage: RangeChar start stop
| "RangeChar", None, _ ->
Helper.LibCall(com, "Seq", "rangeChar", t, args, i.SignatureArgTypes, ?loc=r) |> Some
Helper.LibCall(com, "Range", "rangeChar", t, args, i.SignatureArgTypes, ?loc=r) |> Some
// reference: https://msdn.microsoft.com/visualfsharpdocs/conceptual/operatorintrinsics.rangedouble-function-%5bfsharp%5d
// Type: RangeDouble: float -> float -> float -> seq<float>
// Usage: RangeDouble start step stop
| ("RangeSByte" | "RangeByte"
| "RangeInt16" | "RangeUInt16"
| "RangeInt32" | "RangeUInt32"
| "RangeSingle" | "RangeDouble"), None, args ->
Helper.LibCall(com, "Seq", "rangeNumber", t, args, i.SignatureArgTypes, ?loc=r) |> Some
| ("RangeInt64" | "RangeUInt64"), None, args ->
let isUnsigned = makeBoolConst (i.CompiledName = "RangeUInt64")
Helper.LibCall(com, "Seq", "rangeLong", t, args @ [isUnsigned] , i.SignatureArgTypes, ?loc=r) |> Some
Helper.LibCall(com, "Range", "rangeDouble", t, args, i.SignatureArgTypes, ?loc=r) |> Some
| "RangeInt64", None, args ->
Helper.LibCall(com, "Range", "rangeInt64", t, args, i.SignatureArgTypes, ?loc=r) |> Some
| "RangeUInt64", None, args ->
Helper.LibCall(com, "Range", "rangeUInt64", t, args, i.SignatureArgTypes, ?loc=r) |> Some
| _ -> None

let runtimeHelpers (com: ICompiler) (ctx: Context) r t (i: CallInfo) thisArg args =
Expand Down Expand Up @@ -3061,8 +3019,8 @@ let private replacedModules =
"Microsoft.FSharp.Collections.ListModule", listModule
"Microsoft.FSharp.Collections.HashIdentity", fsharpModule
"Microsoft.FSharp.Collections.ComparisonIdentity", fsharpModule
"Microsoft.FSharp.Core.CompilerServices.RuntimeHelpers", seqs
"Microsoft.FSharp.Collections.SeqModule", seqs
"Microsoft.FSharp.Core.CompilerServices.RuntimeHelpers", seqModule
"Microsoft.FSharp.Collections.SeqModule", seqModule
"System.Collections.Generic.KeyValuePair`2", keyValuePairs
"System.Collections.Generic.Comparer`1", bclType
"System.Collections.Generic.EqualityComparer`1", bclType
Expand Down
Loading