@@ -3908,9 +3908,10 @@ abstract class GenJSCode extends plugins.PluginComponent
3908
3908
* {name1: arg1, name2: arg2, ... }
3909
3909
*/
3910
3910
3911
- def warnIfDuplicatedKey (pairs : List [(js.StringLiteral , js.Tree )]): Unit = {
3912
- val allKeys = pairs.collect { case (js.StringLiteral (keyName), _) => keyName }
3913
- val keyCounts = allKeys.distinct.map(key => key -> allKeys.count(_ == key))
3911
+ def warnIfDuplicatedKey (keys : List [js.StringLiteral ]): Unit = {
3912
+ val keyNames = keys.map(_.value)
3913
+ val keyCounts =
3914
+ keyNames.distinct.map(key => key -> keyNames.count(_ == key))
3914
3915
val duplicateKeyCounts = keyCounts.filter(1 < _._2)
3915
3916
if (duplicateKeyCounts.nonEmpty) {
3916
3917
reporter.warning(pos,
@@ -3923,12 +3924,21 @@ abstract class GenJSCode extends plugins.PluginComponent
3923
3924
}
3924
3925
}
3925
3926
3927
+ def keyToPropName (key : js.Tree , index : Int ): js.PropertyName = key match {
3928
+ case key : js.StringLiteral => key
3929
+ case _ => js.ComputedName (key, " local" + index)
3930
+ }
3931
+
3926
3932
// Extract first arg to future proof against varargs
3927
3933
extractFirstArg(genArgs) match {
3928
- // case js.Dynamic.literal("name1" -> ..., "name2" -> ...)
3929
- case (js.StringLiteral (" apply" ), jse.LitNamed (pairs)) =>
3930
- warnIfDuplicatedKey(pairs)
3931
- js.JSObjectConstr (pairs)
3934
+ // case js.Dynamic.literal("name1" -> ..., nameExpr2 -> ...)
3935
+ case (js.StringLiteral (" apply" ), jse.Tuple2List (pairs)) =>
3936
+ warnIfDuplicatedKey(pairs.collect {
3937
+ case (key : js.StringLiteral , _) => key
3938
+ })
3939
+ js.JSObjectConstr (pairs.zipWithIndex.map {
3940
+ case ((key, value), index) => (keyToPropName(key, index), value)
3941
+ })
3932
3942
3933
3943
/* case js.Dynamic.literal(x: _*)
3934
3944
* Even though scalac does not support this notation, it is still
@@ -3950,31 +3960,27 @@ abstract class GenJSCode extends plugins.PluginComponent
3950
3960
// case js.Dynamic.literal(x, y)
3951
3961
case (js.StringLiteral (" apply" ), tups) =>
3952
3962
// Check for duplicated explicit keys
3953
- val pairs = jse.LitNamedExtractor .extractFrom(tups)
3954
- warnIfDuplicatedKey(pairs)
3955
-
3956
- // Create tmp variable
3957
- val resIdent = freshLocalIdent(" obj" )
3958
- val resVarDef = js.VarDef (resIdent, jstpe.AnyType , mutable = false ,
3959
- js.JSObjectConstr (Nil ))
3960
- val res = resVarDef.ref
3963
+ warnIfDuplicatedKey(jse.extractLiteralKeysFrom(tups))
3961
3964
3962
- // Assign fields
3965
+ // Evaluate all tuples first
3963
3966
val tuple2Type = encodeClassType(TupleClass (2 ))
3964
- val assigns = tups flatMap {
3965
- // special case for literals
3966
- case jse.Tuple2 (name, value) =>
3967
- js.Assign (js.JSBracketSelect (res, name), value) :: Nil
3968
- case tupExpr =>
3969
- val tupIdent = freshLocalIdent(" tup" )
3970
- val tup = js.VarRef (tupIdent)(tuple2Type)
3971
- js.VarDef (tupIdent, tuple2Type, mutable = false , tupExpr) ::
3972
- js.Assign (js.JSBracketSelect (res,
3973
- genApplyMethod(tup, js.Ident (" $$und1__O" ), Nil , jstpe.AnyType )),
3974
- genApplyMethod(tup, js.Ident (" $$und2__O" ), Nil , jstpe.AnyType )) :: Nil
3967
+ val evalTuples = tups.map { tup =>
3968
+ js.VarDef (freshLocalIdent(" tup" ), tuple2Type, mutable = false ,
3969
+ tup)(tup.pos)
3975
3970
}
3976
3971
3977
- js.Block (resVarDef +: assigns :+ res : _* )
3972
+ // Build the resulting object
3973
+ val result = js.JSObjectConstr (evalTuples.zipWithIndex.map {
3974
+ case (evalTuple, index) =>
3975
+ val tupRef = evalTuple.ref
3976
+ val key = genApplyMethod(tupRef, js.Ident (" $$und1__O" ), Nil ,
3977
+ jstpe.AnyType )
3978
+ val value = genApplyMethod(tupRef, js.Ident (" $$und2__O" ), Nil ,
3979
+ jstpe.AnyType )
3980
+ keyToPropName(key, index) -> value
3981
+ })
3982
+
3983
+ js.Block (evalTuples :+ result)
3978
3984
3979
3985
// case where another method is called
3980
3986
case (js.StringLiteral (name), _) if name != " apply" =>
0 commit comments