@@ -18,6 +18,7 @@ import config.Config
1818import reporting .diagnostic .Message
1919import reporting .diagnostic .messages .BadSymbolicReference
2020import reporting .trace
21+ import collection .mutable
2122
2223import scala .annotation .internal .sharable
2324
@@ -518,12 +519,8 @@ object SymDenotations {
518519 name == tpnme.REFINE_CLASS
519520
520521 /** Is this symbol a package object or its module class? */
521- def isPackageObject (implicit ctx : Context ): Boolean = {
522- val nameMatches =
523- if (isType) name == tpnme.PACKAGE .moduleClassName
524- else name == nme.PACKAGE
525- nameMatches && (owner is Package ) && (this is Module )
526- }
522+ def isPackageObject (implicit ctx : Context ): Boolean =
523+ name.isPackageObjectName && (owner is Package ) && (this is Module )
527524
528525 /** Is this symbol an abstract type? */
529526 final def isAbstractType (implicit ctx : Context ): Boolean = this is DeferredType
@@ -762,9 +759,7 @@ object SymDenotations {
762759 ( ! (this is Local )
763760 || (owner is ImplClass ) // allow private local accesses to impl class members
764761 || isCorrectThisType(pre)
765- ) &&
766- (! (this .is(Private ) && owner.is(Package )) ||
767- owner == ctx.owner.enclosingPackageClass)
762+ )
768763 || (this is Protected ) &&
769764 ( superAccess
770765 || pre.isInstanceOf [ThisType ]
@@ -1684,9 +1679,9 @@ object SymDenotations {
16841679 val denots1 = collect(denots, ps)
16851680 p.classSymbol.denot match {
16861681 case parentd : ClassDenotation =>
1687- denots1 union
1682+ denots1. union(
16881683 parentd.nonPrivateMembersNamed(name)
1689- .mapInherited(ownDenots, denots1, thisType)
1684+ .mapInherited(ownDenots, denots1, thisType) )
16901685 case _ =>
16911686 denots1
16921687 }
@@ -1944,54 +1939,81 @@ object SymDenotations {
19441939 initPrivateWithin : Symbol )
19451940 extends ClassDenotation (symbol, ownerIfExists, name, initFlags, initInfo, initPrivateWithin) {
19461941
1947- private [this ] var packageObjCache : SymDenotation = _
1948- private [this ] var packageObjRunId : RunId = NoRunId
1949-
1950- /** The package object in this class, of one exists */
1951- def packageObj (implicit ctx : Context ): SymDenotation = {
1952- if (packageObjRunId != ctx.runId) {
1953- packageObjRunId = ctx.runId
1954- packageObjCache = NoDenotation // break cycle in case we are looking for package object itself
1955- packageObjCache = findMember(nme.PACKAGE , thisType, EmptyFlagConjunction , EmptyFlags ).asSymDenotation
1942+ private [this ] var packageObjsCache : List [ClassDenotation ] = _
1943+ private [this ] var packageObjsRunId : RunId = NoRunId
1944+
1945+ /** The package objects in this class */
1946+ def packageObjs (implicit ctx : Context ): List [ClassDenotation ] = {
1947+ if (packageObjsRunId != ctx.runId) {
1948+ packageObjsRunId = ctx.runId
1949+ packageObjsCache = Nil // break cycle in case we are looking for package object itself
1950+ packageObjsCache = {
1951+ val pkgObjBuf = new mutable.ListBuffer [ClassDenotation ]
1952+ for (sym <- info.decls) { // don't use filter, since that loads classes with `$`s in their name
1953+ val denot = sym.lastKnownDenotation // don't use `sym.denot`, as this brings forward classes too early
1954+ if (denot.isType && denot.name.isPackageObjectName)
1955+ pkgObjBuf += sym.asClass.classDenot
1956+ }
1957+ pkgObjBuf.toList
1958+ }
19561959 }
1957- packageObjCache
1960+ packageObjsCache
1961+ }
1962+
1963+ /** The package object (as a term symbol) in this package that might contain
1964+ * `sym` as a member.
1965+ */
1966+ def packageObjFor (sym : Symbol )(implicit ctx : Context ): Symbol = {
1967+ val owner = sym.maybeOwner
1968+ if (owner.is(Package )) NoSymbol
1969+ else if (owner.isPackageObject) owner.sourceModule
1970+ else // owner could be class inherited by package object (until package object inheritance is removed)
1971+ packageObjs.find(_.name == packageTypeName) match {
1972+ case Some (pobj) => pobj.sourceModule
1973+ case _ => NoSymbol
1974+ }
19581975 }
19591976
19601977 /** Looks in both the package object and the package for members. The precise algorithm
19611978 * is as follows:
19621979 *
19631980 * If this is the scala package look in the package first, and if nothing is found
1964- * there, look in the package object second. Otherwise, look in the package object
1965- * first, and if nothing is found there, in the package second .
1981+ * there, look in the package object second. Otherwise, look in the both the package object
1982+ * and the package and form a union of the results .
19661983 *
19671984 * The reason for the special treatment of the scala package is that if we
19681985 * complete it too early, we freeze its superclass Any, so that no members can
19691986 * be entered in it. As a consequence, there should be no entry in the scala package
19701987 * object that hides a class or object in the scala package of the same name, because
19711988 * the behavior would then be unintuitive for such members.
19721989 */
1973- override def computeNPMembersNamed (name : Name )(implicit ctx : Context ): PreDenotation =
1974- packageObj.moduleClass.denot match {
1975- case pcls : ClassDenotation if ! pcls.isCompleting =>
1976- if (symbol eq defn.ScalaPackageClass ) {
1977- val denots = super .computeNPMembersNamed(name)
1978- if (denots.exists) denots else pcls.computeNPMembersNamed(name)
1979- }
1980- else {
1981- val denots = pcls.computeNPMembersNamed(name)
1982- if (denots.exists) denots else super .computeNPMembersNamed(name)
1983- }
1984- case _ =>
1985- super .computeNPMembersNamed(name)
1990+ override def computeNPMembersNamed (name : Name )(implicit ctx : Context ): PreDenotation = {
1991+ def recur (pobjs : List [ClassDenotation ], acc : PreDenotation ): PreDenotation = pobjs match {
1992+ case pcls :: pobjs1 =>
1993+ if (pcls.isCompleting) recur(pobjs1, acc)
1994+ else recur(pobjs1, acc.union(pcls.computeNPMembersNamed(name)))
1995+ case nil =>
1996+ val directMembers = super .computeNPMembersNamed(name)
1997+ if (acc.exists) acc.union(directMembers.filterWithPredicate(! _.symbol.isAbsent))
1998+ else directMembers
19861999 }
2000+ if (symbol `eq` defn.ScalaPackageClass ) {
2001+ val denots = super .computeNPMembersNamed(name)
2002+ if (denots.exists) denots
2003+ else recur(packageObjs, NoDenotation )
2004+ }
2005+ else recur(packageObjs, NoDenotation )
2006+ }
19872007
19882008 /** The union of the member names of the package and the package object */
19892009 override def memberNames (keepOnly : NameFilter )(implicit onBehalf : MemberNames , ctx : Context ): Set [Name ] = {
1990- val ownNames = super .memberNames(keepOnly)
1991- packageObj.moduleClass.denot match {
1992- case pcls : ClassDenotation => ownNames union pcls.memberNames(keepOnly)
1993- case _ => ownNames
2010+ def recur (pobjs : List [ClassDenotation ], acc : Set [Name ]): Set [Name ] = pobjs match {
2011+ case pcls :: pobjs1 =>
2012+ recur(pobjs1, acc.union(pcls.memberNames(keepOnly)))
2013+ case nil =>
2014+ acc
19942015 }
2016+ recur(packageObjs, super .memberNames(keepOnly))
19952017 }
19962018
19972019 /** If another symbol with the same name is entered, unlink it,
@@ -2003,7 +2025,7 @@ object SymDenotations {
20032025 if (entry != null ) {
20042026 if (entry.sym == sym) return false
20052027 mscope.unlink(entry)
2006- if (sym.name == nme. PACKAGE ) packageObjRunId = NoRunId
2028+ if (sym.name.isPackageObjectName) packageObjsRunId = NoRunId
20072029 }
20082030 true
20092031 }
@@ -2353,5 +2375,7 @@ object SymDenotations {
23532375 def baseClasses : List [ClassSymbol ] = classes
23542376 }
23552377
2378+ private val packageTypeName = ModuleClassName (nme.PACKAGE ).toTypeName
2379+
23562380 @ sharable private [this ] var indent = 0 // for completions printing
23572381}
0 commit comments