Skip to content

Commit 7863d4e

Browse files
Cleanup Array in library
1 parent bb6b5f5 commit 7863d4e

File tree

11 files changed

+260
-285
lines changed

11 files changed

+260
-285
lines changed

src/Fable.Transforms/AST/AST.Fable.fs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ type ValueKind =
175175
| EnumConstant of Expr * Entity
176176
| NewOption of value: Expr option * Type
177177
| NewArray of Expr list * Type
178-
| NewArrayAlloc of Expr * Type
178+
| NewArrayFrom of Expr * Type
179179
| NewList of headAndTail: (Expr * Expr) option * Type
180180
| NewTuple of Expr list
181181
| NewRecord of Expr list * Entity * genArgs: Type list
@@ -196,7 +196,7 @@ type ValueKind =
196196
| EnumConstant (_, ent) -> Enum ent
197197
| NewOption (_, t) -> Option t
198198
| NewArray (_, t) -> Array t
199-
| NewArrayAlloc (_, t) -> Array t
199+
| NewArrayFrom (_, t) -> Array t
200200
| NewList (_, t) -> List t
201201
| NewTuple exprs -> exprs |> List.map (fun e -> e.Type) |> Tuple
202202
| NewRecord (_, ent, genArgs) -> DeclaredType(ent, genArgs)

src/Fable.Transforms/Fable2Babel.fs

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -650,25 +650,32 @@ module Util =
650650
List.mapToArray (fun e -> com.TransformAsExpr(ctx, e)) exprs
651651
|> ArrayExpression :> Expression
652652

653-
let makeTypedArray (com: IBabelCompiler) ctx typ (args: Fable.Expr list) =
654-
match typ with
653+
let makeTypedArray (com: IBabelCompiler) ctx t (args: Fable.Expr list) =
654+
match t with
655655
| Fable.Number kind when com.Options.TypedArrays ->
656656
let jsName = getTypedArrayName com kind
657-
let args =
658-
[| List.mapToArray (fun e -> com.TransformAsExpr(ctx, e)) args
659-
|> ArrayExpression :> Expression |]
657+
let args = [|makeArray com ctx args|]
660658
NewExpression(Identifier jsName, args) :> Expression
659+
| _ -> makeArray com ctx args
660+
661+
let makeTypedAllocatedFrom (com: IBabelCompiler) ctx typ (fableExpr: Fable.Expr) =
662+
let getArrayCons t =
663+
match t with
664+
| Fable.Number kind when com.Options.TypedArrays ->
665+
getTypedArrayName com kind |> Identifier
666+
| _ -> Identifier "Array"
667+
668+
match fableExpr with
669+
| ExprType(Fable.Number _) ->
670+
let cons = getArrayCons typ
671+
let expr = com.TransformAsExpr(ctx, fableExpr)
672+
NewExpression(cons, [|expr|]) :> Expression
673+
| MaybeCasted(Replacements.ArrayOrListLiteral(exprs, _)) ->
674+
makeTypedArray com ctx typ exprs
661675
| _ ->
662-
makeArray com ctx args
663-
664-
let makeTypedAllocatedArray (com: IBabelCompiler) ctx typ (TransformExpr com ctx size) =
665-
match typ with
666-
| Fable.Number kind when com.Options.TypedArrays ->
667-
let jsName = getTypedArrayName com kind
668-
let args = [|size|]
669-
NewExpression(Identifier jsName, [|size|]) :> Expression
670-
| _ ->
671-
upcast NewExpression(Identifier "Array", [|size|])
676+
let cons = getArrayCons typ
677+
let expr = com.TransformAsExpr(ctx, fableExpr)
678+
CallExpression(get None cons "from", [|expr|]) :> Expression
672679

673680
let makeStringArray strings =
674681
strings
@@ -878,7 +885,7 @@ module Util =
878885
| Fable.NumberConstant (x,_) -> upcast NumericLiteral(x, ?loc=r)
879886
| Fable.RegexConstant (source, flags) -> upcast RegExpLiteral(source, flags, ?loc=r)
880887
| Fable.NewArray (values, typ) -> makeTypedArray com ctx typ values
881-
| Fable.NewArrayAlloc (size, typ) -> makeTypedAllocatedArray com ctx typ size
888+
| Fable.NewArrayFrom (size, typ) -> makeTypedAllocatedFrom com ctx typ size
882889
| Fable.NewTuple vals -> makeArray com ctx vals
883890
// Optimization for bundle size: compile list literals as List.ofArray
884891
| Replacements.ListLiteral(exprs, t) ->

src/Fable.Transforms/FableTransforms.fs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ let visit f e =
2020
| NewOption(e, t) -> NewOption(Option.map f e, t) |> makeValue r
2121
| NewTuple exprs -> NewTuple(List.map f exprs) |> makeValue r
2222
| NewArray(exprs, t) -> NewArray(List.map f exprs, t) |> makeValue r
23-
| NewArrayAlloc(e, t) -> NewArrayAlloc(f e, t) |> makeValue r
23+
| NewArrayFrom(e, t) -> NewArrayFrom(f e, t) |> makeValue r
2424
| NewList(ht, t) ->
2525
let ht = ht |> Option.map (fun (h,t) -> f h, f t)
2626
NewList(ht, t) |> makeValue r
@@ -104,7 +104,7 @@ let getSubExpressions = function
104104
| NewOption(e, _) -> Option.toList e
105105
| NewTuple exprs -> exprs
106106
| NewArray(exprs, _) -> exprs
107-
| NewArrayAlloc(e, _) -> [e]
107+
| NewArrayFrom(e, _) -> [e]
108108
| NewList(ht, _) ->
109109
match ht with Some(h,t) -> [h;t] | None -> []
110110
| NewRecord(exprs, _, _) -> exprs

src/Fable.Transforms/Replacements.fs

Lines changed: 42 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -583,38 +583,17 @@ let round com (args: Expr list) =
583583
rounded::args.Tail
584584
| _ -> args
585585

586-
let arrayCons (com: ICompiler) genArg =
587-
match genArg with
588-
| Number numberKind when com.Options.TypedArrays ->
589-
getTypedArrayName com numberKind |> makeIdentExpr
590-
| _ -> makeIdentExpr "Array"
591-
592586
let toList com returnType expr =
593587
Helper.LibCall(com, "List", "ofSeq", returnType, [expr])
594588

595-
let toArray (com: ICompiler) returnType expr =
596-
// match expr, returnType with
597-
// | _, Array(Number numberKind) when com.Options.typedArrays ->
598-
// Helper.GlobalCall(getTypedArrayName com numberKind, returnType, [expr], memb="from")
599-
// | _ -> Helper.GlobalCall("Array", returnType, [expr], memb="from")
600-
601-
// Calling the JS global methods (Array.from) directly creates problems with lambda optimization
602-
// because passing these functions as values in JS (e.g. `foo(Array.from)`) doesn't work
603-
let args =
604-
match returnType with
605-
| Array genArg
589+
let toArray r t expr =
590+
let t =
591+
match t with
592+
| Array t
606593
// This is used also by Seq.cache, which returns `'T seq` instead of `'T array`
607-
| DeclaredType(_, [genArg]) -> [expr; arrayCons com genArg]
608-
| _ -> [expr]
609-
Helper.LibCall(com, "Array", "ofSeq", returnType, args)
610-
611-
let listToArray com r t (li: Expr) =
612-
match li with
613-
| Value(ListLiteral(exprs, t),_) ->
614-
NewArray(exprs, t) |> makeValue r
615-
| _ ->
616-
let args = match t with Array genArg -> [li; arrayCons com genArg] | _ -> [li]
617-
Helper.LibCall(com, "Array", "ofList", t, args, ?loc=r)
594+
| DeclaredType(_, [t]) -> t
595+
| t -> t
596+
Value(NewArrayFrom(expr, t), r)
618597

619598
let stringToCharArray t e =
620599
Helper.InstanceCall(e, "split", t, [makeStrConst ""])
@@ -938,32 +917,37 @@ let makePojoFromLambda com arg =
938917
|> Option.defaultWith (fun () -> Helper.LibCall(com, "Util", "jsOptions", Any, [arg]))
939918

940919
let injectArg com (ctx: Context) r moduleName methName (genArgs: (string * Type) list) args =
941-
let (|GenericArg|_|) genArgs genArgIndex =
942-
List.tryItem genArgIndex genArgs
943-
944-
let buildArg = function
945-
| (Types.comparer, GenericArg genArgs (_,genArg)) ->
946-
makeComparer com ctx genArg |> Some
947-
| (Types.equalityComparer, GenericArg genArgs (_,genArg)) ->
948-
makeEqualityComparer com ctx genArg |> Some
949-
| (Types.arrayCons, GenericArg genArgs (_,genArg)) ->
950-
arrayCons com genArg |> Some
951-
| (Types.adder, GenericArg genArgs (_,genArg)) ->
952-
makeGenericAdder com ctx genArg |> Some
953-
| (Types.averager, GenericArg genArgs (_,genArg)) ->
954-
makeGenericAverager com ctx genArg |> Some
955-
| (_, genArgIndex) ->
920+
let injectArgInner args (injectType, injectGenArgIndex) =
921+
let fail () =
956922
sprintf "Cannot inject arg to %s.%s (genArgs %A - expected index %i)"
957-
moduleName methName (List.map fst genArgs) genArgIndex
923+
moduleName methName (List.map fst genArgs) injectGenArgIndex
958924
|> addError com ctx.InlinePath r
959-
None
925+
args
926+
927+
match List.tryItem injectGenArgIndex genArgs with
928+
| None -> fail()
929+
| Some (_,genArg) ->
930+
match injectType with
931+
| Types.comparer ->
932+
args @ [makeComparer com ctx genArg]
933+
| Types.equalityComparer ->
934+
args @ [makeEqualityComparer com ctx genArg]
935+
| Types.arrayCons ->
936+
match genArg with
937+
| Number numberKind when com.Options.TypedArrays ->
938+
args @ [getTypedArrayName com numberKind |> makeIdentExpr]
939+
| _ -> args
940+
| Types.adder ->
941+
args @ [makeGenericAdder com ctx genArg]
942+
| Types.averager ->
943+
args @ [makeGenericAverager com ctx genArg]
944+
| _ -> fail()
960945

961946
Map.tryFind moduleName ReplacementsInject.fableReplacementsModules
962947
|> Option.bind (Map.tryFind methName)
963-
|> Option.map (List.choose buildArg)
964948
|> function
965949
| None -> args
966-
| Some injections -> args @ injections
950+
| Some injectInfo -> injectArgInner args injectInfo
967951

968952
let tryEntityRef (com: Fable.Compiler) (ent: Entity) =
969953
match ent.FullName with
@@ -1152,10 +1136,6 @@ let fableCoreLib (com: ICompiler) (ctx: Context) r t (i: CallInfo) (thisArg: Exp
11521136
| "op_EqualsEqualsGreater", [name; MaybeLambdaUncurriedAtCompileTime value] ->
11531137
NewTuple [name; value] |> makeValue r |> Some
11541138
| "createObj", _ ->
1155-
let args =
1156-
match args with
1157-
| [Value(ListLiteral(args,t),r)] -> [NewArray(args, t) |> makeValue r]
1158-
| _ -> args
11591139
let m = if com.Options.DebugMode then "createObjDebug" else "createObj"
11601140
Helper.LibCall(com, "Util", m, Any, args) |> Some
11611141
| "keyValueList", [caseRule; keyValueList] ->
@@ -1627,11 +1607,11 @@ let seqs (com: ICompiler) (ctx: Context) r (t: Type) (i: CallInfo) (thisArg: Exp
16271607

16281608
match i.CompiledName, args with
16291609
| "Cast", [arg] -> Some arg // Erase
1630-
| ("Cache" | "ToArray"), [arg] -> toArray com t arg |> Some
1610+
| ("Cache" | "ToArray"), [arg] -> toArray r t arg |> Some
16311611
| "OfList", [arg] -> toSeq t arg |> Some
16321612
| "ToList", _ -> Helper.LibCall(com, "List", "ofSeq", t, args, i.SignatureArgTypes, ?loc=r) |> Some
16331613
| ("ChunkBySize" | "Permute" | "SplitInto") as meth, [arg1; arg2] ->
1634-
let arg2 = toArray com (Array Any) arg2
1614+
let arg2 = toArray r (Array Any) arg2
16351615
let result = Helper.LibCall(com, "Array", Naming.lowerFirst meth, Any, [arg1; arg2])
16361616
Helper.LibCall(com, "Seq", "ofArray", t, [result]) |> Some
16371617
// For Using we need to cast the argument to IDisposable
@@ -1701,7 +1681,7 @@ let resizeArrays (com: ICompiler) (ctx: Context) r (t: Type) (i: CallInfo) (this
17011681
let opt = Helper.LibCall(com, "Seq", "tryFindBack", t, [arg; ar; defaultof com ctx t], ?loc=r)
17021682
Helper.LibCall(com, "Option", "value", t, [opt], ?loc=r) |> Some
17031683
| "FindAll", Some ar, [arg] ->
1704-
Helper.LibCall(com, "Seq", "filter", t, [arg; ar], ?loc=r) |> toArray com t |> Some
1684+
Helper.LibCall(com, "Seq", "filter", t, [arg; ar], ?loc=r) |> toArray r t |> Some
17051685
| "AddRange", Some ar, [arg] ->
17061686
Helper.LibCall(com, "Array", "addRangeInPlace", t, [arg; ar], ?loc=r) |> Some
17071687
| "GetRange", Some ar, [idx; cnt] ->
@@ -1767,8 +1747,8 @@ let arrays (com: ICompiler) (ctx: Context) r (t: Type) (i: CallInfo) (thisArg: E
17671747
| _ -> None
17681748

17691749
let arrayModule (com: ICompiler) (ctx: Context) r (t: Type) (i: CallInfo) (_: Expr option) (args: Expr list) =
1770-
let inline newArray size t =
1771-
Value(NewArrayAlloc(size, t), None)
1750+
let newArray size t =
1751+
Value(NewArrayFrom(size, t), None)
17721752
let createArray size value =
17731753
match t, value with
17741754
| Array(Number _ as t2), None when com.Options.TypedArrays -> newArray size t2
@@ -1780,8 +1760,8 @@ let arrayModule (com: ICompiler) (ctx: Context) r (t: Type) (i: CallInfo) (_: Ex
17801760
|> addErrorAndReturnNull com ctx.InlinePath r
17811761
match i.CompiledName, args with
17821762
| "ToSeq", [arg] -> Some arg
1783-
| "OfSeq", [arg] -> toArray com t arg |> Some
1784-
| "OfList", [arg] -> listToArray com r t arg |> Some
1763+
| "OfSeq", [arg] -> toArray r t arg |> Some
1764+
| "OfList", [arg] -> toArray r t arg |> Some
17851765
| "ToList", _ -> Helper.LibCall(com, "List", "ofArray", t, args, i.SignatureArgTypes, ?loc=r) |> Some
17861766
| ("Length" | "Count"), [arg] -> get r t arg "length" |> Some
17871767
| "Item", [idx; ar] -> getExpr r t ar idx |> Some
@@ -1796,7 +1776,7 @@ let arrayModule (com: ICompiler) (ctx: Context) r (t: Type) (i: CallInfo) (_: Ex
17961776
eq (get r (Number Int32) ar "length") (makeIntConst 0) |> Some
17971777
| "AllPairs", args ->
17981778
let allPairs = Helper.LibCall(com, "Seq", "allPairs", t, args, i.SignatureArgTypes, ?loc=r)
1799-
toArray com t allPairs |> Some
1779+
toArray r t allPairs |> Some
18001780
| "TryExactlyOne", args ->
18011781
tryCoreOp com r t "Array" "exactlyOne" args |> Some
18021782
| "SortInPlace", args ->
@@ -1840,7 +1820,7 @@ let listModule (com: ICompiler) (ctx: Context) r (t: Type) (i: CallInfo) (_: Exp
18401820
// Use a cast to give it better chances of optimization (e.g. converting list
18411821
// literals to arrays) after the beta reduction pass
18421822
| "ToSeq", [x] -> toSeq t x |> Some
1843-
| "ToArray", [x] -> listToArray com r t x |> Some
1823+
| "ToArray", [x] -> toArray r t x |> Some
18441824
| "AllPairs", args ->
18451825
let allPairs = Helper.LibCall(com, "Seq", "allPairs", t, args, i.SignatureArgTypes, ?loc=r)
18461826
toList com t allPairs |> Some
@@ -2377,7 +2357,7 @@ let bitConvert (com: ICompiler) (ctx: Context) r t (i: CallInfo) (_: Expr option
23772357
| x -> failwithf "Unsupported type in BitConverter.GetBytes(): %A" x
23782358
let expr = Helper.LibCall(com, "BitConverter", memberName, Boolean, args, i.SignatureArgTypes, ?loc=r)
23792359
if com.Options.TypedArrays then expr |> Some
2380-
else toArray com t expr |> Some // convert to dynamic array
2360+
else toArray r t expr |> Some // convert to dynamic array
23812361
| _ ->
23822362
let memberName = Naming.lowerFirst i.CompiledName
23832363
Helper.LibCall(com, "BitConverter", memberName, Boolean, args, i.SignatureArgTypes, ?loc=r) |> Some
@@ -2630,7 +2610,7 @@ let encoding (com: ICompiler) (ctx: Context) r t (i: CallInfo) (thisArg: Expr op
26302610
let meth = Naming.lowerFirst i.CompiledName
26312611
let expr = Helper.InstanceCall(callee, meth, t, args, i.SignatureArgTypes, ?loc=r)
26322612
if com.Options.TypedArrays then expr |> Some
2633-
else toArray com t expr |> Some // convert to dynamic array
2613+
else toArray r t expr |> Some // convert to dynamic array
26342614
| "GetString", Some callee, (1 | 3) ->
26352615
let meth = Naming.lowerFirst i.CompiledName
26362616
Helper.InstanceCall(callee, meth, t, args, i.SignatureArgTypes, ?loc=r) |> Some

0 commit comments

Comments
 (0)