@@ -697,24 +697,78 @@ trait GenJSExports[G <: Global with Singleton] extends SubComponent {
697
697
previousArgsValues : Int => List [js.Tree ])(
698
698
implicit pos : Position ): js.Tree = {
699
699
700
- val trgSym = {
701
- if (sym.isClassConstructor) {
702
- /* Get the companion module class.
703
- * For inner classes the sym.owner.companionModule can be broken,
704
- * therefore companionModule is fetched at uncurryPhase.
700
+ val owner = sym.owner
701
+ val isNested = owner.isLifted && ! isStaticModule(owner.originalOwner)
702
+
703
+ val (trgSym, trgTree) = {
704
+ if (! sym.isClassConstructor && ! static) {
705
+ /* Default getter is on the receiver.
706
+ *
707
+ * Since we only use this method for class internal exports
708
+ * dispatchers, we know the default getter is on `this`. This applies
709
+ * to both top-level and nested classes.
710
+ */
711
+ (owner, js.This ()(encodeClassType(owner)))
712
+ } else if (isNested) {
713
+ assert(captures.size == 1 ,
714
+ s " expected exactly one capture got $captures ( $sym at $pos) " )
715
+
716
+ /* Find the module accessor.
705
717
*
706
718
* #4465: If owner is a nested class, the linked class is *not* a
707
719
* module value, but another class. In this case we need to call the
708
720
* module accessor on the enclosing class to retrieve this.
721
+ *
722
+ * #4526: If the companion module is private, linkedClassOfClass
723
+ * does not work (because the module name is prefixed with the full
724
+ * path). So we find the module accessor first and take its result
725
+ * type to be the companion module type.
726
+ */
727
+ val outer = owner.originalOwner
728
+
729
+ val modAccessor = {
730
+ val name = enteringPhase(currentRun.typerPhase) {
731
+ owner.unexpandedName.toTermName
732
+ }
733
+
734
+ outer.info.members.find { sym =>
735
+ sym.isModule && sym.unexpandedName == name
736
+ }.getOrElse {
737
+ throw new AssertionError (
738
+ s " couldn't find module accessor for ${owner.fullName} at $pos" )
739
+ }
740
+ }
741
+
742
+ val receiver = captures.head
743
+
744
+ val trgSym = modAccessor.tpe.resultType.typeSymbol
745
+
746
+ val trgTree = if (isJSType(outer)) {
747
+ genApplyJSClassMethod(receiver, modAccessor, Nil )
748
+ } else {
749
+ genApplyMethodMaybeStatically(receiver, modAccessor, Nil )
750
+ }
751
+
752
+ (trgSym, trgTree)
753
+ } else if (sym.isClassConstructor) {
754
+ assert(captures.isEmpty, " expected empty captures" )
755
+
756
+ /* Get the companion module class.
757
+ * For classes nested inside modules the sym.owner.companionModule
758
+ * can be broken, therefore companionModule is fetched at
759
+ * uncurryPhase.
709
760
*/
710
- val companionModule = enteringPhase(currentRun.uncurryPhase) {
711
- sym. owner.companionModule
761
+ val trgSym = enteringPhase(currentRun.uncurryPhase) {
762
+ owner.linkedClassOfClass
712
763
}
713
- companionModule.moduleClass
764
+ (trgSym, genLoadModule(trgSym))
714
765
} else {
715
- sym.owner
766
+ assert(static, " expected static" )
767
+ assert(captures.isEmpty, " expected empty captures" )
768
+ (owner, genLoadModule(owner))
716
769
}
717
770
}
771
+
718
772
val defaultGetter = trgSym.tpe.member(
719
773
nme.defaultGetterName(sym.name, paramIndex + 1 ))
720
774
@@ -723,31 +777,6 @@ trait GenJSExports[G <: Global with Singleton] extends SubComponent {
723
777
assert(! defaultGetter.isOverloaded,
724
778
s " found overloaded default getter $defaultGetter" )
725
779
726
- val trgTree = {
727
- if (sym.isClassConstructor || static) {
728
- if (! trgSym.isLifted) {
729
- assert(captures.isEmpty, " expected empty captures" )
730
- genLoadModule(trgSym)
731
- } else {
732
- assert(captures.size == 1 , " expected exactly one capture" )
733
-
734
- // Find the module accessor.
735
- val outer = trgSym.originalOwner
736
- val name = enteringPhase(currentRun.typerPhase)(trgSym.unexpandedName)
737
-
738
- val modAccessor = outer.info.members.lookupModule(name)
739
- val receiver = captures.head
740
- if (isJSType(outer)) {
741
- genApplyJSClassMethod(receiver, modAccessor, Nil )
742
- } else {
743
- genApplyMethodMaybeStatically(receiver, modAccessor, Nil )
744
- }
745
- }
746
- } else {
747
- js.This ()(encodeClassType(trgSym))
748
- }
749
- }
750
-
751
780
// Pass previous arguments to defaultGetter
752
781
val defaultGetterArgs = previousArgsValues(defaultGetter.tpe.params.size)
753
782
0 commit comments