@@ -518,7 +518,7 @@ final class JSExportsGen(jsCodeGen: JSCodeGen)(using Context) {
518
518
// If argument is undefined and there is a default getter, call it
519
519
val verifiedOrDefault = if (param.hasDefault) {
520
520
js.If (js.BinaryOp (js.BinaryOp .=== , jsArg, js.Undefined ()), {
521
- genCallDefaultGetter(exported.sym, i, param.sym.sourcePos, static) {
521
+ genCallDefaultGetter(exported.sym, i, static) {
522
522
prevArgsCount => result.take(prevArgsCount).toList.map(_.ref)
523
523
}
524
524
}, {
@@ -537,7 +537,7 @@ final class JSExportsGen(jsCodeGen: JSCodeGen)(using Context) {
537
537
result.toList
538
538
}
539
539
540
- private def genCallDefaultGetter (sym : Symbol , paramIndex : Int , paramPos : SourcePosition , static : Boolean )(
540
+ private def genCallDefaultGetter (sym : Symbol , paramIndex : Int , static : Boolean )(
541
541
previousArgsValues : Int => List [js.Tree ])(
542
542
implicit pos : SourcePosition ): js.Tree = {
543
543
@@ -562,29 +562,17 @@ final class JSExportsGen(jsCodeGen: JSCodeGen)(using Context) {
562
562
report.error(
563
563
" When overriding a native method with default arguments, " +
564
564
" the overriding method must explicitly repeat the default arguments." ,
565
- paramPos )
565
+ sym.srcPos )
566
566
js.Undefined ()
567
567
}
568
568
} else {
569
569
genApplyMethod(targetTree, defaultGetter, defaultGetterArgs)
570
570
}
571
571
}
572
572
573
- private def targetSymForDefaultGetter (sym : Symbol ): Symbol = {
574
- if (sym.isClassConstructor) {
575
- /* /* Get the companion module class.
576
- * For inner classes the sym.owner.companionModule can be broken,
577
- * therefore companionModule is fetched at uncurryPhase.
578
- */
579
- val companionModule = enteringPhase(currentRun.namerPhase) {
580
- sym.owner.companionModule
581
- }
582
- companionModule.moduleClass*/
583
- sym.owner.companionModule.moduleClass
584
- } else {
585
- sym.owner
586
- }
587
- }
573
+ private def targetSymForDefaultGetter (sym : Symbol ): Symbol =
574
+ if (sym.isClassConstructor) sym.owner.companionModule.moduleClass
575
+ else sym.owner
588
576
589
577
private def defaultGetterDenot (targetSym : Symbol , sym : Symbol , paramIndex : Int ): Denotation =
590
578
targetSym.info.member(DefaultGetterName (sym.name.asTermName, paramIndex))
@@ -607,9 +595,8 @@ final class JSExportsGen(jsCodeGen: JSCodeGen)(using Context) {
607
595
js.This ()(encodeClassType(sym.owner))
608
596
}
609
597
610
- def boxIfNeeded (call : js.Tree ): js.Tree = {
598
+ def boxIfNeeded (call : js.Tree ): js.Tree =
611
599
box(call, atPhase(elimErasedValueTypePhase)(sym.info.resultType))
612
- }
613
600
614
601
if (currentClassSym.isNonNativeJSClass) {
615
602
assert(sym.owner == currentClassSym.get, sym.fullName)
@@ -627,19 +614,18 @@ final class JSExportsGen(jsCodeGen: JSCodeGen)(using Context) {
627
614
private def genThrowTypeError (msg : String = " No matching overload" )(implicit pos : Position ): js.Tree =
628
615
js.Throw (js.JSNew (js.JSGlobalRef (" TypeError" ), js.StringLiteral (msg) :: Nil ))
629
616
630
- private final class ParamSpec (val sym : Symbol , val info : Type ,
631
- val isRepeated : Boolean , val hasDefault : Boolean ) {
617
+ private final class ParamSpec (val info : Type , val isRepeated : Boolean , val hasDefault : Boolean ) {
632
618
override def toString (): String =
633
- s " ParamSpec( ${sym.name} , ${ info.show} , isRepeated = $isRepeated, hasDefault = $hasDefault) "
619
+ i " ParamSpec( $info, isRepeated = $isRepeated, hasDefault = $hasDefault) "
634
620
}
635
621
636
622
private object ParamSpec {
637
- def apply (methodSym : Symbol , sym : Symbol , infoAtElimRepeated : Type , infoAtElimEVT : Type ,
623
+ def apply (methodSym : Symbol , infoAtElimRepeated : Type , infoAtElimEVT : Type ,
638
624
methodHasDefaultParams : Boolean , paramIndex : Int ): ParamSpec = {
639
625
val isRepeated = infoAtElimRepeated.isRepeatedParam
640
626
val info = if (isRepeated) infoAtElimRepeated.repeatedToSingle else infoAtElimEVT
641
627
val hasDefault = methodHasDefaultParams && defaultGetterDenot(methodSym, paramIndex).exists
642
- new ParamSpec (sym, info, isRepeated, hasDefault)
628
+ new ParamSpec (info, isRepeated, hasDefault)
643
629
}
644
630
}
645
631
@@ -650,73 +636,70 @@ final class JSExportsGen(jsCodeGen: JSCodeGen)(using Context) {
650
636
651
637
// params: List[ParamSpec] ; captureParams and captureParamsBack: List[js.ParamDef]
652
638
val (params, captureParamsFront, captureParamsBack) = {
653
- val paramNamessNow = sym.info.paramNamess
654
- val paramInfosNow = sym.info.paramInfoss.flatten
655
- val paramSymsAtElimRepeated = atPhase(elimRepeatedPhase)(sym.paramSymss.flatten.filter(_.isTerm))
656
- val (paramNamessAtElimRepeated, paramInfosAtElimRepeated, methodHasDefaultParams) =
657
- atPhase(elimRepeatedPhase)((sym.info.paramNamess, sym.info.paramInfoss.flatten, sym.hasDefaultParams))
658
- val (paramNamessAtElimEVT, paramInfosAtElimEVT) =
659
- atPhase(elimErasedValueTypePhase)((sym.info.paramNamess, sym.info.paramInfoss.flatten))
660
-
661
- def buildFormalParams ( paramSyms : List [ Symbol ], paramInfosAtElimRepeated : List [ Type ],
662
- paramInfosAtElimEVT : List [Type ]): IndexedSeq [ParamSpec ] = {
639
+ val (paramNamesAtElimRepeated, paramInfosAtElimRepeated, methodHasDefaultParams) =
640
+ atPhase(elimRepeatedPhase)((sym.info.paramNamess.flatten, sym.info.paramInfoss.flatten, sym.hasDefaultParams))
641
+ val (paramNamesAtElimEVT, paramInfosAtElimEVT) =
642
+ atPhase(elimErasedValueTypePhase)((sym.info.firstParamNames, sym.info.firstParamTypes))
643
+ val (paramNamesNow, paramInfosNow) =
644
+ (sym.info.firstParamNames, sym.info.firstParamTypes)
645
+
646
+ val formalParamCount = paramInfosAtElimRepeated.size
647
+
648
+ def buildFormalParams ( formalParamInfosAtElimEVT : List [Type ]): IndexedSeq [ParamSpec ] = {
663
649
(for {
664
- (paramSym, infoAtElimRepeated, infoAtElimEVT, paramIndex) <-
665
- paramSyms.lazyZip( paramInfosAtElimRepeated) .lazyZip(paramInfosAtElimEVT ).lazyZip(0 until paramSyms.size )
650
+ (infoAtElimRepeated, infoAtElimEVT, paramIndex) <-
651
+ paramInfosAtElimRepeated.lazyZip(formalParamInfosAtElimEVT ).lazyZip(0 until formalParamCount )
666
652
} yield {
667
- ParamSpec (sym, paramSym, infoAtElimRepeated, infoAtElimEVT, methodHasDefaultParams, paramIndex)
653
+ ParamSpec (sym, infoAtElimRepeated, infoAtElimEVT, methodHasDefaultParams, paramIndex)
668
654
}).toIndexedSeq
669
655
}
670
656
657
+ def buildCaptureParams (namesAndInfosNow : List [(TermName , Type )]): List [js.ParamDef ] = {
658
+ implicit val pos : Position = sym.span
659
+ for ((name, info) <- namesAndInfosNow) yield {
660
+ js.ParamDef (freshLocalIdent(name.mangledString), NoOriginalName , toIRType(info),
661
+ mutable = false , rest = false )
662
+ }
663
+ }
664
+
671
665
if (! isConstructorOfNestedJSClass) {
672
- // Easy case: all params are formal params.
673
- assert(paramInfosAtElimRepeated.size == paramInfosAtElimEVT.size,
674
- s " Found ${paramInfosAtElimRepeated.size} params entering elimRepeated but " +
675
- s " ${paramInfosAtElimEVT.size} params entering elimErasedValueType for " +
676
- s " non-lifted symbol ${sym.fullName}" )
677
- val formalParams = buildFormalParams(paramSymsAtElimRepeated, paramInfosAtElimRepeated, paramInfosAtElimEVT)
666
+ // Easy case: all params are formal params
667
+ assert(paramInfosAtElimEVT.size == formalParamCount && paramInfosNow.size == formalParamCount,
668
+ s " Found $formalParamCount params entering elimRepeated but ${paramInfosAtElimEVT.size} params entering " +
669
+ s " elimErasedValueType and ${paramInfosNow.size} params at the back-end for non-lifted symbol ${sym.fullName}" )
670
+ val formalParams = buildFormalParams(paramInfosAtElimEVT)
678
671
(formalParams, Nil , Nil )
672
+ } else if (formalParamCount == 0 ) {
673
+ // Fast path: all params are capture params
674
+ val captureParams = buildCaptureParams(paramNamesNow.zip(paramInfosNow))
675
+ (IndexedSeq .empty, Nil , captureParams)
679
676
} else {
680
- /* The `arg$outer` param is added by erasure, following "instructions"
681
- * by explicitouter, while the other capture params are added by
682
- * lambdalift (between elimErasedValueType and now).
683
- *
684
- * Since we cannot reliably get Symbols for parameters created by
685
- * intermediate phases, we have to perform some dance with the
686
- * paramNamess and paramInfoss observed at some phases, combined with
687
- * the paramSymss observed at elimRepeated.
677
+ /* Slow path: we have to isolate formal params (which were already present at elimRepeated)
678
+ * from capture params (which are later, typically by erasure and/or lambdalift).
688
679
*/
689
680
690
- val hasOuterParam = {
691
- paramInfosAtElimEVT.size == paramInfosAtElimRepeated.size + 1 &&
692
- paramNamessAtElimEVT.flatten.head == nme.OUTER
681
+ def findStartOfFormalParamsIn (paramNames : List [TermName ]): Int = {
682
+ val start = paramNames.indexOfSlice(paramNamesAtElimRepeated)
683
+ assert(start >= 0 , s " could not find formal param names $paramNamesAtElimRepeated in $paramNames" )
684
+ start
693
685
}
694
- assert(
695
- hasOuterParam || paramInfosAtElimEVT.size == paramInfosAtElimRepeated.size,
696
- s " Found ${paramInfosAtElimRepeated.size} params entering elimRepeated but " +
697
- s " ${paramInfosAtElimEVT.size} params entering elimErasedValueType for " +
698
- s " lifted constructor symbol ${sym.fullName}" )
699
-
700
- val startOfFormalParams = paramNamessNow.flatten.indexOfSlice(paramNamessAtElimRepeated.flatten)
701
- val formalParamCount = paramInfosAtElimRepeated.size
702
-
703
- val nonOuterParamInfosAtElimEVT =
704
- if (hasOuterParam) paramInfosAtElimEVT.tail
705
- else paramInfosAtElimEVT
706
- val formalParams = buildFormalParams(paramSymsAtElimRepeated, paramInfosAtElimRepeated, nonOuterParamInfosAtElimEVT)
707
-
708
- val paramNamesAndInfosNow = paramNamessNow.flatten.zip(paramInfosNow)
709
- val (captureParamsFrontNow, restOfParamsNow) = paramNamesAndInfosNow.splitAt(startOfFormalParams)
710
- val captureParamsBackNow = restOfParamsNow.drop(formalParamCount)
711
686
712
- def makeCaptureParamDef (nameAndInfo : (TermName , Type )): js.ParamDef = {
713
- implicit val pos : Position = sym.span
714
- js.ParamDef (freshLocalIdent(nameAndInfo._1.mangledString), NoOriginalName , toIRType(nameAndInfo._2),
715
- mutable = false , rest = false )
716
- }
687
+ // Find the infos of formal params at elimEVT
688
+ val startOfFormalParamsAtElimEVT = findStartOfFormalParamsIn(paramNamesAtElimEVT)
689
+ val formalParamInfosAtElimEVT = paramInfosAtElimEVT.drop(startOfFormalParamsAtElimEVT).take(formalParamCount)
690
+
691
+ // Build the formal param specs from their infos at elimRepeated and elimEVT
692
+ val formalParams = buildFormalParams(formalParamInfosAtElimEVT)
693
+
694
+ // Find the formal params now to isolate the capture params (before and after the formal params)
695
+ val startOfFormalParamsNow = findStartOfFormalParamsIn(paramNamesNow)
696
+ val paramNamesAndInfosNow = paramNamesNow.zip(paramInfosNow)
697
+ val (captureParamsFrontNow, restOfParamsNow) = paramNamesAndInfosNow.splitAt(startOfFormalParamsNow)
698
+ val captureParamsBackNow = restOfParamsNow.drop(formalParamCount)
717
699
718
- val captureParamsFront = captureParamsFrontNow.map(makeCaptureParamDef(_))
719
- val captureParamsBack = captureParamsBackNow.map(makeCaptureParamDef(_))
700
+ // Build the capture param defs from the isolated capture params
701
+ val captureParamsFront = buildCaptureParams(captureParamsFrontNow)
702
+ val captureParamsBack = buildCaptureParams(captureParamsBackNow)
720
703
721
704
(formalParams, captureParamsFront, captureParamsBack)
722
705
}
0 commit comments