@@ -2652,7 +2652,11 @@ class JSCodeGen()(using genCtx: Context) {
26522652 jsSuperClassValue : Option [js.Tree ] = None )(
26532653 implicit pos : SourcePosition ): js.Tree = {
26542654
2655- def noSpread = ! args.exists(_.isInstanceOf [js.JSSpread ])
2655+ def argsNoSpread : List [js.Tree ] = {
2656+ assert(! args.exists(_.isInstanceOf [js.JSSpread ]), s " Unexpected spread at $pos" )
2657+ args.asInstanceOf [List [js.Tree ]]
2658+ }
2659+
26562660 val argc = args.size // meaningful only for methods that don't have varargs
26572661
26582662 def requireNotSuper (): Unit = {
@@ -2663,74 +2667,72 @@ class JSCodeGen()(using genCtx: Context) {
26632667 def requireNotSpread (arg : js.TreeOrJSSpread ): js.Tree =
26642668 arg.asInstanceOf [js.Tree ]
26652669
2666- def hasExplicitJSEncoding = {
2667- sym.hasAnnotation(jsdefn.JSNameAnnot ) ||
2668- sym.hasAnnotation(jsdefn.JSBracketAccessAnnot ) ||
2669- sym.hasAnnotation(jsdefn.JSBracketCallAnnot )
2670+ def genSuperReference (propName : js.Tree ): js.AssignLhs = {
2671+ jsSuperClassValue.fold[js.AssignLhs ] {
2672+ genJSSelectOrGlobalRef(receiver, propName)
2673+ } { superClassValue =>
2674+ js.JSSuperSelect (superClassValue, ruleOutGlobalScope(receiver), propName)
2675+ }
2676+ }
2677+
2678+ def genSelectGet (propName : js.Tree ): js.Tree =
2679+ genSuperReference(propName)
2680+
2681+ def genSelectSet (propName : js.Tree , value : js.Tree ): js.Tree =
2682+ js.Assign (genSuperReference(propName), value)
2683+
2684+ def genCall (methodName : js.Tree , args : List [js.TreeOrJSSpread ]): js.Tree = {
2685+ jsSuperClassValue.fold[js.Tree ] {
2686+ genJSMethodApplyOrGlobalRefApply(receiver, methodName, args)
2687+ } { superClassValue =>
2688+ js.JSSuperMethodCall (superClassValue, ruleOutGlobalScope(receiver), methodName, args)
2689+ }
26702690 }
26712691
2672- val boxedResult = sym.name match {
2673- case JSUnaryOpMethodName (code) if argc == 0 =>
2692+ val boxedResult = sym.jsCallingConvention match {
2693+ case JSCallingConvention . UnaryOp (code) =>
26742694 requireNotSuper()
2695+ assert(argc == 0 , s " bad argument count ( $argc) for unary op at $pos" )
26752696 js.JSUnaryOp (code, ruleOutGlobalScope(receiver))
26762697
2677- case JSBinaryOpMethodName (code) if argc == 1 =>
2698+ case JSCallingConvention . BinaryOp (code) =>
26782699 requireNotSuper()
2700+ assert(argc == 1 , s " bad argument count ( $argc) for binary op at $pos" )
26792701 js.JSBinaryOp (code, ruleOutGlobalScope(receiver), requireNotSpread(args.head))
26802702
2681- case nme.apply if ! hasExplicitJSEncoding =>
2703+ case JSCallingConvention . Call =>
26822704 requireNotSuper()
26832705 if (jsdefn.isJSThisFunctionClass(sym.owner))
26842706 js.JSMethodApply (ruleOutGlobalScope(receiver), js.StringLiteral (" call" ), args)
26852707 else
26862708 js.JSFunctionApply (ruleOutGlobalScope(receiver), args)
26872709
2688- case _ =>
2689- def jsFunName = genExpr(jsNameOf(sym))
2690-
2691- def genSuperReference (propName : js.Tree ): js.AssignLhs = {
2692- jsSuperClassValue.fold[js.AssignLhs ] {
2693- genJSSelectOrGlobalRef(receiver, propName)
2694- } { superClassValue =>
2695- js.JSSuperSelect (superClassValue, ruleOutGlobalScope(receiver), propName)
2696- }
2710+ case JSCallingConvention .Property (jsName) =>
2711+ argsNoSpread match {
2712+ case Nil =>
2713+ genSelectGet(genExpr(jsName))
2714+ case value :: Nil =>
2715+ genSelectSet(genExpr(jsName), value)
2716+ case _ =>
2717+ throw new AssertionError (s " property methods should have 0 or 1 non-varargs arguments at $pos" )
26972718 }
26982719
2699- def genSelectGet (propName : js.Tree ): js.Tree =
2700- genSuperReference(propName)
2701-
2702- def genSelectSet (propName : js.Tree , value : js.Tree ): js.Tree =
2703- js.Assign (genSuperReference(propName), value)
2704-
2705- def genCall (methodName : js.Tree , args : List [js.TreeOrJSSpread ]): js.Tree = {
2706- jsSuperClassValue.fold[js.Tree ] {
2707- genJSMethodApplyOrGlobalRefApply(receiver, methodName, args)
2708- } { superClassValue =>
2709- js.JSSuperMethodCall (superClassValue, ruleOutGlobalScope(receiver), methodName, args)
2710- }
2720+ case JSCallingConvention .BracketAccess =>
2721+ argsNoSpread match {
2722+ case keyArg :: Nil =>
2723+ genSelectGet(keyArg)
2724+ case keyArg :: valueArg :: Nil =>
2725+ genSelectSet(keyArg, valueArg)
2726+ case _ =>
2727+ throw new AssertionError (s " @JSBracketAccess methods should have 1 or 2 non-varargs arguments at $pos" )
27112728 }
27122729
2713- if (sym.isJSGetter) {
2714- assert(noSpread && argc == 0 )
2715- genSelectGet(jsFunName)
2716- } else if (sym.isJSSetter) {
2717- assert(noSpread && argc == 1 )
2718- genSelectSet(jsFunName, requireNotSpread(args.head))
2719- } else if (sym.isJSBracketAccess) {
2720- assert(noSpread && (argc == 1 || argc == 2 ),
2721- s " @JSBracketAccess methods should have 1 or 2 non-varargs arguments " )
2722- (args : @ unchecked) match {
2723- case List (keyArg) =>
2724- genSelectGet(requireNotSpread(keyArg))
2725- case List (keyArg, valueArg) =>
2726- genSelectSet(requireNotSpread(keyArg), requireNotSpread(valueArg))
2727- }
2728- } else if (sym.isJSBracketCall) {
2729- val (methodName, actualArgs) = extractFirstArg(args)
2730- genCall(methodName, actualArgs)
2731- } else {
2732- genCall(jsFunName, args)
2733- }
2730+ case JSCallingConvention .BracketCall =>
2731+ val (methodName, actualArgs) = extractFirstArg(args)
2732+ genCall(methodName, actualArgs)
2733+
2734+ case JSCallingConvention .Method (jsName) =>
2735+ genCall(genExpr(jsName), args)
27342736 }
27352737
27362738 if (isStat) {
@@ -2743,46 +2745,6 @@ class JSCodeGen()(using genCtx: Context) {
27432745 }
27442746 }
27452747
2746- private object JSUnaryOpMethodName {
2747- private val map = Map (
2748- nme.UNARY_+ -> js.JSUnaryOp .+ ,
2749- nme.UNARY_- -> js.JSUnaryOp .- ,
2750- nme.UNARY_~ -> js.JSUnaryOp .~ ,
2751- nme.UNARY_! -> js.JSUnaryOp .!
2752- )
2753-
2754- def unapply (name : TermName ): Option [js.JSUnaryOp .Code ] =
2755- map.get(name)
2756- }
2757-
2758- private object JSBinaryOpMethodName {
2759- private val map = Map (
2760- nme.ADD -> js.JSBinaryOp .+ ,
2761- nme.SUB -> js.JSBinaryOp .- ,
2762- nme.MUL -> js.JSBinaryOp .* ,
2763- nme.DIV -> js.JSBinaryOp ./ ,
2764- nme.MOD -> js.JSBinaryOp .% ,
2765-
2766- nme.LSL -> js.JSBinaryOp .<< ,
2767- nme.ASR -> js.JSBinaryOp .>> ,
2768- nme.LSR -> js.JSBinaryOp .>>> ,
2769- nme.OR -> js.JSBinaryOp .| ,
2770- nme.AND -> js.JSBinaryOp .& ,
2771- nme.XOR -> js.JSBinaryOp .^ ,
2772-
2773- nme.LT -> js.JSBinaryOp .< ,
2774- nme.LE -> js.JSBinaryOp .<= ,
2775- nme.GT -> js.JSBinaryOp .> ,
2776- nme.GE -> js.JSBinaryOp .>= ,
2777-
2778- nme.ZAND -> js.JSBinaryOp .&& ,
2779- nme.ZOR -> js.JSBinaryOp .||
2780- )
2781-
2782- def unapply (name : TermName ): Option [js.JSBinaryOp .Code ] =
2783- map.get(name)
2784- }
2785-
27862748 /** Extract the first argument in a list of actual arguments.
27872749 *
27882750 * This is nothing else than decomposing into head and tail, except that
0 commit comments