@@ -18,6 +18,7 @@ import config.Config
18
18
import reporting .diagnostic .Message
19
19
import reporting .diagnostic .messages .BadSymbolicReference
20
20
import reporting .trace
21
+ import collection .mutable
21
22
22
23
import scala .annotation .internal .sharable
23
24
@@ -518,12 +519,8 @@ object SymDenotations {
518
519
name == tpnme.REFINE_CLASS
519
520
520
521
/** 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 )
527
524
528
525
/** Is this symbol an abstract type? */
529
526
final def isAbstractType (implicit ctx : Context ): Boolean = this is DeferredType
@@ -762,9 +759,7 @@ object SymDenotations {
762
759
( ! (this is Local )
763
760
|| (owner is ImplClass ) // allow private local accesses to impl class members
764
761
|| isCorrectThisType(pre)
765
- ) &&
766
- (! (this .is(Private ) && owner.is(Package )) ||
767
- owner == ctx.owner.enclosingPackageClass)
762
+ )
768
763
|| (this is Protected ) &&
769
764
( superAccess
770
765
|| pre.isInstanceOf [ThisType ]
@@ -1684,9 +1679,9 @@ object SymDenotations {
1684
1679
val denots1 = collect(denots, ps)
1685
1680
p.classSymbol.denot match {
1686
1681
case parentd : ClassDenotation =>
1687
- denots1 union
1682
+ denots1. union(
1688
1683
parentd.nonPrivateMembersNamed(name)
1689
- .mapInherited(ownDenots, denots1, thisType)
1684
+ .mapInherited(ownDenots, denots1, thisType) )
1690
1685
case _ =>
1691
1686
denots1
1692
1687
}
@@ -1944,54 +1939,81 @@ object SymDenotations {
1944
1939
initPrivateWithin : Symbol )
1945
1940
extends ClassDenotation (symbol, ownerIfExists, name, initFlags, initInfo, initPrivateWithin) {
1946
1941
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
+ }
1956
1959
}
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
+ }
1958
1975
}
1959
1976
1960
1977
/** Looks in both the package object and the package for members. The precise algorithm
1961
1978
* is as follows:
1962
1979
*
1963
1980
* 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 .
1966
1983
*
1967
1984
* The reason for the special treatment of the scala package is that if we
1968
1985
* complete it too early, we freeze its superclass Any, so that no members can
1969
1986
* be entered in it. As a consequence, there should be no entry in the scala package
1970
1987
* object that hides a class or object in the scala package of the same name, because
1971
1988
* the behavior would then be unintuitive for such members.
1972
1989
*/
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
1986
1999
}
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
+ }
1987
2007
1988
2008
/** The union of the member names of the package and the package object */
1989
2009
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
1994
2015
}
2016
+ recur(packageObjs, super .memberNames(keepOnly))
1995
2017
}
1996
2018
1997
2019
/** If another symbol with the same name is entered, unlink it,
@@ -2003,7 +2025,7 @@ object SymDenotations {
2003
2025
if (entry != null ) {
2004
2026
if (entry.sym == sym) return false
2005
2027
mscope.unlink(entry)
2006
- if (sym.name == nme. PACKAGE ) packageObjRunId = NoRunId
2028
+ if (sym.name.isPackageObjectName) packageObjsRunId = NoRunId
2007
2029
}
2008
2030
true
2009
2031
}
@@ -2353,5 +2375,7 @@ object SymDenotations {
2353
2375
def baseClasses : List [ClassSymbol ] = classes
2354
2376
}
2355
2377
2378
+ private val packageTypeName = ModuleClassName (nme.PACKAGE ).toTypeName
2379
+
2356
2380
@ sharable private [this ] var indent = 0 // for completions printing
2357
2381
}
0 commit comments