@@ -974,7 +974,6 @@ class Namer { typer: Typer =>
974
974
975
975
/** The forwarders defined by export `exp` */
976
976
private def exportForwarders (exp : Export )(using Context ): List [tpd.MemberDef ] =
977
- val SKIP = " (skip)" // A string indicating that no forwarders for this kind of symbol are emitted
978
977
val buf = new mutable.ListBuffer [tpd.MemberDef ]
979
978
val Export (expr, selectors) = exp
980
979
if expr.isEmpty then
@@ -986,19 +985,22 @@ class Namer { typer: Typer =>
986
985
lazy val wildcardBound = importBound(selectors, isGiven = false )
987
986
lazy val givenBound = importBound(selectors, isGiven = true )
988
987
989
- def whyNoForwarder (mbr : SingleDenotation ): String = {
988
+ def canForward (mbr : SingleDenotation ): CanForward = {
989
+ import CanForward .*
990
990
val sym = mbr.symbol
991
- if (! sym.isAccessibleFrom(path.tpe)) " is not accessible"
992
- else if (sym.isConstructor || sym.is(ModuleClass ) || sym.is(Bridge ) || sym.is(ConstructorProxy )) SKIP
993
- else if (cls.derivesFrom(sym.owner) &&
994
- (sym.owner == cls || ! sym.is(Deferred ))) i " is already a member of $cls"
995
- else if (sym.is(Override ))
991
+ if ! sym.isAccessibleFrom(path.tpe) then
992
+ No (" is not accessible" )
993
+ else if sym.isConstructor || sym.is(ModuleClass ) || sym.is(Bridge ) || sym.is(ConstructorProxy ) then
994
+ Skip
995
+ else if cls.derivesFrom(sym.owner) && (sym.owner == cls || ! sym.is(Deferred )) then
996
+ No (i " is already a member of $cls" )
997
+ else if sym.is(Override ) then
996
998
sym.allOverriddenSymbols.find(
997
- other => cls.derivesFrom(other.owner) && ! other.is(Deferred )) match {
998
- case Some (other) => i " overrides ${other.showLocated} , which is already a member of $cls "
999
- case None => " "
1000
- }
1001
- else " "
999
+ other => cls.derivesFrom(other.owner) && ! other.is(Deferred )
1000
+ ) match
1001
+ case Some (other) => No ( i " overrides ${other.showLocated} , which is already a member of $cls " )
1002
+ case None => Yes
1003
+ else Yes
1002
1004
}
1003
1005
1004
1006
/** Add a forwarder with name `alias` or its type name equivalent to `mbr`,
@@ -1021,7 +1023,7 @@ class Namer { typer: Typer =>
1021
1023
case _ =>
1022
1024
acc.reverse ::: prefss
1023
1025
1024
- if whyNoForwarder (mbr) == " " then
1026
+ if canForward (mbr) == CanForward . Yes then
1025
1027
val sym = mbr.symbol
1026
1028
val forwarder =
1027
1029
if mbr.isType then
@@ -1038,7 +1040,7 @@ class Namer { typer: Typer =>
1038
1040
// a parameterized class, say `C[X]` the alias will read `type C = d.C`. We currently do
1039
1041
// allow such type aliases. If we forbid them at some point (requiring the referred type to be
1040
1042
// fully applied), we'd have to change the scheme here as well.
1041
- else {
1043
+ else
1042
1044
def refersToPrivate (tp : Type ): Boolean = tp match
1043
1045
case tp : TermRef => tp.termSymbol.is(Private ) || refersToPrivate(tp.prefix)
1044
1046
case _ => false
@@ -1051,16 +1053,17 @@ class Namer { typer: Typer =>
1051
1053
if sym.is(ExtensionMethod ) then mbrFlags |= ExtensionMethod
1052
1054
val forwarderName = checkNoConflict(alias, isPrivate = false , span)
1053
1055
newSymbol(cls, forwarderName, mbrFlags, mbrInfo, coord = span)
1054
- }
1056
+
1055
1057
forwarder.info = avoidPrivateLeaks(forwarder)
1056
1058
forwarder.addAnnotations(sym.annotations)
1059
+
1057
1060
val forwarderDef =
1058
1061
if (forwarder.isType) tpd.TypeDef (forwarder.asType)
1059
1062
else {
1060
1063
import tpd ._
1061
1064
val ref = path.select(sym.asTerm)
1062
1065
val ddef = tpd.DefDef (forwarder.asTerm, prefss =>
1063
- ref.appliedToArgss(adaptForwarderParams(Nil , sym.info, prefss))
1066
+ ref.appliedToArgss(adaptForwarderParams(Nil , sym.info, prefss))
1064
1067
)
1065
1068
if forwarder.isInlineMethod then
1066
1069
PrepareInlineable .registerInlineInfo(forwarder, ddef.rhs)
@@ -1070,18 +1073,15 @@ class Namer { typer: Typer =>
1070
1073
buf += forwarderDef.withSpan(span)
1071
1074
end addForwarder
1072
1075
1073
- def addForwardersNamed (name : TermName , alias : TermName , span : Span ): Unit = {
1076
+ def addForwardersNamed (name : TermName , alias : TermName , span : Span ): Unit =
1074
1077
val size = buf.size
1075
1078
val mbrs = List (name, name.toTypeName).flatMap(path.tpe.member(_).alternatives)
1076
1079
mbrs.foreach(addForwarder(alias, _, span))
1077
- if (buf.size == size) {
1078
- val reason = mbrs.map(whyNoForwarder).dropWhile(_ == SKIP ) match {
1079
- case Nil => " "
1080
- case why :: _ => i " \n $path. $name cannot be exported because it $why"
1081
- }
1080
+ if buf.size == size then
1081
+ val reason = mbrs.map(canForward).collect {
1082
+ case CanForward .No (whyNot) => i " \n $path. $name cannot be exported because it $whyNot"
1083
+ }.headOption.getOrElse(" " )
1082
1084
report.error(i """ no eligible member $name at $path$reason""" , ctx.source.atSpan(span))
1083
- }
1084
- }
1085
1085
1086
1086
def addWildcardForwardersNamed (name : TermName , span : Span ): Unit =
1087
1087
List (name, name.toTypeName)
@@ -1357,6 +1357,12 @@ class Namer { typer: Typer =>
1357
1357
}
1358
1358
}
1359
1359
1360
+ /** Possible actions to perform when deciding on a forwarder for a member */
1361
+ private enum CanForward :
1362
+ case Yes
1363
+ case No (whyNot : String )
1364
+ case Skip // for members that have never forwarders
1365
+
1360
1366
class SuspendCompleter extends LazyType , SymbolLoaders .SecondCompleter {
1361
1367
1362
1368
final override def complete (denot : SymDenotation )(using Context ): Unit =
0 commit comments