aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/core/SymDenotations.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2014-02-07 13:19:58 +0100
committerMartin Odersky <odersky@gmail.com>2014-02-07 13:19:58 +0100
commit5bed5bdd1bb377e9a177a2be635b391bfc0f168e (patch)
tree155c964126b4b74aa5e0c61d4f9997c2efedbf76 /src/dotty/tools/dotc/core/SymDenotations.scala
parent5f5a01c4f74a40eb6d387b83302da2d3c413969b (diff)
downloaddotty-5bed5bdd1bb377e9a177a2be635b391bfc0f168e.tar.gz
dotty-5bed5bdd1bb377e9a177a2be635b391bfc0f168e.tar.bz2
dotty-5bed5bdd1bb377e9a177a2be635b391bfc0f168e.zip
Replace open package module logic by special member lookups in a package class.
Rather than fiddling with scopes, which can lead to race conditions, we now special case member lookup and mamber name filters in ClassDenotations that represent packages.
Diffstat (limited to 'src/dotty/tools/dotc/core/SymDenotations.scala')
-rw-r--r--src/dotty/tools/dotc/core/SymDenotations.scala51
1 files changed, 49 insertions, 2 deletions
diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala
index 5278a08d2..7b9d4cd48 100644
--- a/src/dotty/tools/dotc/core/SymDenotations.scala
+++ b/src/dotty/tools/dotc/core/SymDenotations.scala
@@ -29,7 +29,9 @@ trait SymDenotations { this: Context =>
initInfo: Type,
initPrivateWithin: Symbol = NoSymbol)(implicit ctx: Context): SymDenotation = {
val result =
- if (symbol.isClass) new ClassDenotation(symbol, owner, name, initFlags, initInfo, initPrivateWithin)
+ if (symbol.isClass)
+ if (initFlags is Package) new PackageClassDenotation(symbol, owner, name, initFlags, initInfo, initPrivateWithin)
+ else new ClassDenotation(symbol, owner, name, initFlags, initInfo, initPrivateWithin)
else new SymDenotation(symbol, owner, name, initFlags, initInfo, initPrivateWithin)
result.validFor = stablePeriod
result
@@ -983,7 +985,7 @@ object SymDenotations {
} else computeNPMembersNamed(name)
}
- private def computeNPMembersNamed(name: Name)(implicit ctx: Context): PreDenotation = /*>|>*/ Stats.track("computeNPMembersNamed") /*<|<*/ {
+ private[core] def computeNPMembersNamed(name: Name)(implicit ctx: Context): PreDenotation = /*>|>*/ Stats.track("computeNPMembersNamed") /*<|<*/ {
if (!classSymbol.hasChildren ||
!Config.useFingerPrints ||
(memberFingerPrint contains name)) {
@@ -1124,6 +1126,51 @@ object SymDenotations {
}
}
+ /** The denotation of a package class.
+ * It overrides ClassDenotation to take account of package objects when looking for members
+ */
+ class PackageClassDenotation private[SymDenotations] (
+ symbol: Symbol,
+ ownerIfExists: Symbol,
+ name: Name,
+ initFlags: FlagSet,
+ initInfo: Type,
+ initPrivateWithin: Symbol = NoSymbol)
+ extends ClassDenotation(symbol, ownerIfExists, name, initFlags, initInfo, initPrivateWithin) {
+
+ private[this] var packageObjCache: SymDenotation = _
+ private[this] var packageObjRunId: RunId = NoRunId
+
+ /** The package object in this class, of one exists */
+ def packageObj(implicit ctx: Context): SymDenotation = {
+ if (packageObjRunId != ctx.runId) {
+ packageObjRunId = ctx.runId
+ packageObjCache = NoDenotation // break cycle in case we are looking for package object itself
+ packageObjCache = findMember(nme.PACKAGE, thisType, EmptyFlags).asSymDenotation
+ }
+ packageObjCache
+ }
+
+ /** Look first for members in package; if none are found look in package object */
+ override def computeNPMembersNamed(name: Name)(implicit ctx: Context): PreDenotation = {
+ val denots = super.computeNPMembersNamed(name)
+ if (denots.exists) denots
+ else packageObj.moduleClass.denot match {
+ case pcls: ClassDenotation => pcls.computeNPMembersNamed(name)
+ case _ => denots
+ }
+ }
+
+ /** The union of the member names of the package and the package object */
+ override def memberNames(keepOnly: NameFilter)(implicit ctx: Context): Set[Name] = {
+ val ownNames = super.memberNames(keepOnly)
+ packageObj.moduleClass.denot match {
+ case pcls: ClassDenotation => ownNames union pcls.memberNames(keepOnly)
+ case _ => ownNames
+ }
+ }
+ }
+
object NoDenotation extends SymDenotation(
NoSymbol, NoSymbol, "<none>".toTermName, Permanent, NoType) {
override def exists = false