@@ -2652,7 +2652,11 @@ class JSCodeGen()(using genCtx: Context) {
2652
2652
jsSuperClassValue : Option [js.Tree ] = None )(
2653
2653
implicit pos : SourcePosition ): js.Tree = {
2654
2654
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
+
2656
2660
val argc = args.size // meaningful only for methods that don't have varargs
2657
2661
2658
2662
def requireNotSuper (): Unit = {
@@ -2663,74 +2667,72 @@ class JSCodeGen()(using genCtx: Context) {
2663
2667
def requireNotSpread (arg : js.TreeOrJSSpread ): js.Tree =
2664
2668
arg.asInstanceOf [js.Tree ]
2665
2669
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
+ }
2670
2690
}
2671
2691
2672
- val boxedResult = sym.name match {
2673
- case JSUnaryOpMethodName (code) if argc == 0 =>
2692
+ val boxedResult = sym.jsCallingConvention match {
2693
+ case JSCallingConvention . UnaryOp (code) =>
2674
2694
requireNotSuper()
2695
+ assert(argc == 0 , s " bad argument count ( $argc) for unary op at $pos" )
2675
2696
js.JSUnaryOp (code, ruleOutGlobalScope(receiver))
2676
2697
2677
- case JSBinaryOpMethodName (code) if argc == 1 =>
2698
+ case JSCallingConvention . BinaryOp (code) =>
2678
2699
requireNotSuper()
2700
+ assert(argc == 1 , s " bad argument count ( $argc) for binary op at $pos" )
2679
2701
js.JSBinaryOp (code, ruleOutGlobalScope(receiver), requireNotSpread(args.head))
2680
2702
2681
- case nme.apply if ! hasExplicitJSEncoding =>
2703
+ case JSCallingConvention . Call =>
2682
2704
requireNotSuper()
2683
2705
if (jsdefn.isJSThisFunctionClass(sym.owner))
2684
2706
js.JSMethodApply (ruleOutGlobalScope(receiver), js.StringLiteral (" call" ), args)
2685
2707
else
2686
2708
js.JSFunctionApply (ruleOutGlobalScope(receiver), args)
2687
2709
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" )
2697
2718
}
2698
2719
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" )
2711
2728
}
2712
2729
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)
2734
2736
}
2735
2737
2736
2738
if (isStat) {
@@ -2743,46 +2745,6 @@ class JSCodeGen()(using genCtx: Context) {
2743
2745
}
2744
2746
}
2745
2747
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
-
2786
2748
/** Extract the first argument in a list of actual arguments.
2787
2749
*
2788
2750
* This is nothing else than decomposing into head and tail, except that
0 commit comments