From bd992dd3158f192fd391605a6b51e1c23e09171d Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sat, 1 Apr 2017 19:28:42 +0200 Subject: Fix and activate package scopes Prevviously they were actually unused. --- .../src/dotty/tools/dotc/core/Definitions.scala | 2 +- compiler/src/dotty/tools/dotc/core/Scopes.scala | 42 ++++++++++++++++------ compiler/src/dotty/tools/dotc/core/StdNames.scala | 1 - .../src/dotty/tools/dotc/core/SymbolLoaders.scala | 2 +- 4 files changed, 33 insertions(+), 14 deletions(-) (limited to 'compiler/src/dotty/tools/dotc') diff --git a/compiler/src/dotty/tools/dotc/core/Definitions.scala b/compiler/src/dotty/tools/dotc/core/Definitions.scala index d4d652d6b..8925724fd 100644 --- a/compiler/src/dotty/tools/dotc/core/Definitions.scala +++ b/compiler/src/dotty/tools/dotc/core/Definitions.scala @@ -938,7 +938,7 @@ class Definitions { private def makeScalaSpecial()(implicit ctx: Context) = { val oldInfo = ScalaPackageClass.classInfo val oldDecls = oldInfo.decls - val newDecls = new MutableScope(oldDecls) { + val newDecls = new PackageScope(oldDecls) { override def lookupEntry(name: Name)(implicit ctx: Context): ScopeEntry = { val res = super.lookupEntry(name) if (res == null && name.isTypeName && name.isSyntheticFunction) diff --git a/compiler/src/dotty/tools/dotc/core/Scopes.scala b/compiler/src/dotty/tools/dotc/core/Scopes.scala index 023fe35c5..9e6be7651 100644 --- a/compiler/src/dotty/tools/dotc/core/Scopes.scala +++ b/compiler/src/dotty/tools/dotc/core/Scopes.scala @@ -144,6 +144,11 @@ object Scopes { final def toText(printer: Printer): Text = printer.toText(this) def checkConsistent()(implicit ctx: Context) = () + + /** Hook for transforming a name before it is used in a lookup or creation. + * Used to mangle names in package scopes. + */ + protected def normalize(name: Name): Name = name } /** A subclass of Scope that defines methods for entering and @@ -155,6 +160,7 @@ object Scopes { class MutableScope protected[Scopes](initElems: ScopeEntry, initSize: Int, val nestingLevel: Int = 0) extends Scope { + /** Scope shares elements with `base` */ protected[Scopes] def this(base: Scope)(implicit ctx: Context) = { this(base.lastEntry, base.size, base.nestingLevel + 1) ensureCapacity(MinHash)(ctx) // WTH? it seems the implicit is not in scope for a secondary constructor call. @@ -178,6 +184,8 @@ object Scopes { */ private var elemsCache: List[Symbol] = null + protected def newScopeLikeThis() = new MutableScope() + /** Clone scope, taking care not to force the denotations of any symbols in the scope. */ def cloneScope(implicit ctx: Context): MutableScope = { @@ -187,7 +195,7 @@ object Scopes { entries += e e = e.prev } - val scope = newScope + val scope = newScopeLikeThis() for (i <- entries.length - 1 to 0 by -1) { val e = entries(i) scope.newScopeEntry(e.name, e.sym) @@ -198,7 +206,7 @@ object Scopes { /** create and enter a scope entry with given name and symbol */ protected def newScopeEntry(name: Name, sym: Symbol)(implicit ctx: Context): ScopeEntry = { ensureCapacity(if (hashTable ne null) hashTable.length else MinHash) - val e = new ScopeEntry(name, sym, this) + val e = new ScopeEntry(normalize(name), sym, this) e.prev = lastEntry lastEntry = e if (hashTable ne null) enterInHash(e) @@ -234,7 +242,7 @@ object Scopes { enter(sym) } - private def ensureCapacity(tableSize: Int)(implicit ctx: Context): Unit = + protected def ensureCapacity(tableSize: Int)(implicit ctx: Context): Unit = if (size >= tableSize * FillFactor) createHash(tableSize * 2) private def createHash(tableSize: Int)(implicit ctx: Context): Unit = @@ -310,15 +318,16 @@ object Scopes { /** Lookup a symbol entry matching given name. */ override def lookupEntry(name: Name)(implicit ctx: Context): ScopeEntry = { + val normalized = normalize(name) var e: ScopeEntry = null if (hashTable ne null) { - e = hashTable(name.hashCode & (hashTable.length - 1)) - while ((e ne null) && e.name != name) { + e = hashTable(normalized.hashCode & (hashTable.length - 1)) + while ((e ne null) && e.name != normalized) { e = e.tail } } else { e = lastEntry - while ((e ne null) && e.name != name) { + while ((e ne null) && e.name != normalized) { e = e.prev } } @@ -394,12 +403,23 @@ object Scopes { } } - class PackageScope extends MutableScope { - override final def newScopeEntry(name: Name, sym: Symbol)(implicit ctx: Context): ScopeEntry = - super.newScopeEntry(name.mangled, sym) + /** The scope of a package. This is different from a normal scope + * in that names of scope entries are kept in mangled form. + */ + class PackageScope protected[Scopes](initElems: ScopeEntry, initSize: Int, nestingLevel: Int) + extends MutableScope(initElems, initSize, nestingLevel) { + + /** Scope shares elements with `base` */ + def this(base: Scope)(implicit ctx: Context) = { + this(base.lastEntry, base.size, base.nestingLevel + 1) + ensureCapacity(MinHash)(ctx) // WTH? it seems the implicit is not in scope for a secondary constructor call. + } + + def this() = this(null, 0, 0) + + override def newScopeLikeThis() = new PackageScope() - override final def lookupEntry(name: Name)(implicit ctx: Context): ScopeEntry = - super.lookupEntry(name.mangled) + override protected def normalize(name: Name) = name.mangled } /** Create a new scope */ diff --git a/compiler/src/dotty/tools/dotc/core/StdNames.scala b/compiler/src/dotty/tools/dotc/core/StdNames.scala index 815940eb0..9272c32ed 100644 --- a/compiler/src/dotty/tools/dotc/core/StdNames.scala +++ b/compiler/src/dotty/tools/dotc/core/StdNames.scala @@ -454,7 +454,6 @@ object StdNames { val ne: N = "ne" val newFreeTerm: N = "newFreeTerm" val newFreeType: N = "newFreeType" - val newNestedSymbol: N = "newNestedSymbol" val newScopeWith: N = "newScopeWith" val next: N = "next" val nmeNewTermName: N = "newTermName" diff --git a/compiler/src/dotty/tools/dotc/core/SymbolLoaders.scala b/compiler/src/dotty/tools/dotc/core/SymbolLoaders.scala index 75deb8bb5..ad0d02fa8 100644 --- a/compiler/src/dotty/tools/dotc/core/SymbolLoaders.scala +++ b/compiler/src/dotty/tools/dotc/core/SymbolLoaders.scala @@ -148,7 +148,7 @@ class SymbolLoaders { override def sourceModule(implicit ctx: Context) = _sourceModule def description = "package loader " + classpath.name - private[core] val currentDecls: MutableScope = newScope + private[core] val currentDecls: MutableScope = new PackageScope() def doComplete(root: SymDenotation)(implicit ctx: Context): Unit = { assert(root is PackageClass, root) -- cgit v1.2.3