@@ -3908,9 +3908,10 @@ abstract class GenJSCode extends plugins.PluginComponent
39083908 * {name1: arg1, name2: arg2, ... }
39093909 */
39103910
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))
39143915 val duplicateKeyCounts = keyCounts.filter(1 < _._2)
39153916 if (duplicateKeyCounts.nonEmpty) {
39163917 reporter.warning(pos,
@@ -3923,12 +3924,21 @@ abstract class GenJSCode extends plugins.PluginComponent
39233924 }
39243925 }
39253926
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+
39263932 // Extract first arg to future proof against varargs
39273933 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+ })
39323942
39333943 /* case js.Dynamic.literal(x: _*)
39343944 * Even though scalac does not support this notation, it is still
@@ -3950,31 +3960,27 @@ abstract class GenJSCode extends plugins.PluginComponent
39503960 // case js.Dynamic.literal(x, y)
39513961 case (js.StringLiteral (" apply" ), tups) =>
39523962 // 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))
39613964
3962- // Assign fields
3965+ // Evaluate all tuples first
39633966 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)
39753970 }
39763971
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)
39783984
39793985 // case where another method is called
39803986 case (js.StringLiteral (name), _) if name != " apply" =>
0 commit comments