From 264211f6b7129923c01c2e3c402b157685d64b1f Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sun, 2 Apr 2017 11:43:03 +0200 Subject: Scope refactoring Since we now have separate package-scopes, it's easier to have them take into account the special role played by the scala package. So we can drop the funky logic of `makeScalaSpecial`. --- .../src/dotty/tools/dotc/core/Definitions.scala | 21 +---------- compiler/src/dotty/tools/dotc/core/Scopes.scala | 44 ++++------------------ .../src/dotty/tools/dotc/core/SymbolLoaders.scala | 22 +++++++++++ 3 files changed, 31 insertions(+), 56 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/core/Definitions.scala b/compiler/src/dotty/tools/dotc/core/Definitions.scala index 8925724fd..c7b1538c7 100644 --- a/compiler/src/dotty/tools/dotc/core/Definitions.scala +++ b/compiler/src/dotty/tools/dotc/core/Definitions.scala @@ -108,7 +108,7 @@ class Definitions { * def apply(implicit $x0: T0, ..., $x{N_1}: T{N-1}): R * } */ - private def newFunctionNTrait(name: TypeName) = { + def newFunctionNTrait(name: TypeName) = { val completer = new LazyType { def complete(denot: SymDenotation)(implicit ctx: Context): Unit = { val cls = denot.asClass.classSymbol @@ -932,23 +932,6 @@ class Definitions { // ----- Initialization --------------------------------------------------- - /** Give the scala package a scope where a FunctionN trait is automatically - * added when someone looks for it. - */ - private def makeScalaSpecial()(implicit ctx: Context) = { - val oldInfo = ScalaPackageClass.classInfo - val oldDecls = oldInfo.decls - 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) - newScopeEntry(newFunctionNTrait(name.asTypeName)) - else res - } - } - ScalaPackageClass.info = oldInfo.derivedClassInfo(decls = newDecls) - } - /** Lists core classes that don't have underlying bytecode, but are synthesized on-the-fly in every reflection universe */ lazy val syntheticScalaClasses = List( AnyClass, @@ -976,8 +959,6 @@ class Definitions { def init()(implicit ctx: Context) = { this.ctx = ctx if (!_isInitialized) { - makeScalaSpecial() - // force initialization of every symbol that is synthesized or hijacked by the compiler val forced = syntheticCoreClasses ++ syntheticCoreMethods ++ ScalaValueClasses() diff --git a/compiler/src/dotty/tools/dotc/core/Scopes.scala b/compiler/src/dotty/tools/dotc/core/Scopes.scala index 9e6be7651..c256e7071 100644 --- a/compiler/src/dotty/tools/dotc/core/Scopes.scala +++ b/compiler/src/dotty/tools/dotc/core/Scopes.scala @@ -32,7 +32,7 @@ object Scopes { * This value must be a power of two, so that the index of an element can * be computed as element.hashCode & (hashTable.length - 1) */ - private final val MinHash = 8 + final val MinHashedScopeSize = 8 /** The maximal permissible number of recursions when creating * a hashtable @@ -144,11 +144,6 @@ 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 @@ -163,7 +158,7 @@ object Scopes { /** 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. + ensureCapacity(MinHashedScopeSize)(ctx) // WTH? it seems the implicit is not in scope for a secondary constructor call. } def this() = this(null, 0, 0) @@ -205,8 +200,8 @@ 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(normalize(name), sym, this) + ensureCapacity(if (hashTable ne null) hashTable.length else MinHashedScopeSize) + val e = new ScopeEntry(name, sym, this) e.prev = lastEntry lastEntry = e if (hashTable ne null) enterInHash(e) @@ -242,7 +237,7 @@ object Scopes { enter(sym) } - protected def ensureCapacity(tableSize: Int)(implicit ctx: Context): Unit = + private def ensureCapacity(tableSize: Int)(implicit ctx: Context): Unit = if (size >= tableSize * FillFactor) createHash(tableSize * 2) private def createHash(tableSize: Int)(implicit ctx: Context): Unit = @@ -318,16 +313,15 @@ 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(normalized.hashCode & (hashTable.length - 1)) - while ((e ne null) && e.name != normalized) { + e = hashTable(name.hashCode & (hashTable.length - 1)) + while ((e ne null) && e.name != name) { e = e.tail } } else { e = lastEntry - while ((e ne null) && e.name != normalized) { + while ((e ne null) && e.name != name) { e = e.prev } } @@ -403,25 +397,6 @@ object Scopes { } } - /** 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 protected def normalize(name: Name) = name.mangled - } - /** Create a new scope */ def newScope: MutableScope = new MutableScope() @@ -435,9 +410,6 @@ object Scopes { scope } - /** Create new scope for the members of package `pkg` */ - def newPackageScope(pkgClass: Symbol): MutableScope = new PackageScope() - /** Transform scope of members of `owner` using operation `op` * This is overridden by the reflective compiler to avoid creating new scopes for packages */ diff --git a/compiler/src/dotty/tools/dotc/core/SymbolLoaders.scala b/compiler/src/dotty/tools/dotc/core/SymbolLoaders.scala index ad0d02fa8..168908ced 100644 --- a/compiler/src/dotty/tools/dotc/core/SymbolLoaders.scala +++ b/compiler/src/dotty/tools/dotc/core/SymbolLoaders.scala @@ -148,6 +148,28 @@ class SymbolLoaders { override def sourceModule(implicit ctx: Context) = _sourceModule def description = "package loader " + classpath.name + /** The scope of a package. This is different from a normal scope + * in three aspects: + * + * 1. Names of scope entries are kept in mangled form. + * 2. Some function types in the `scala` package are synthesized. + */ + final class PackageScope extends MutableScope { + override def newScopeEntry(name: Name, sym: Symbol)(implicit ctx: Context): ScopeEntry = + super.newScopeEntry(name.mangled, sym) + + override def lookupEntry(name: Name)(implicit ctx: Context): ScopeEntry = { + val e = super.lookupEntry(name.mangled) + if (e == null && + _sourceModule.name == nme.scala_ && _sourceModule == defn.ScalaPackageVal && + name.isTypeName && name.isSyntheticFunction) + newScopeEntry(defn.newFunctionNTrait(name.asTypeName)) + else e + } + + override def newScopeLikeThis() = new PackageScope + } + private[core] val currentDecls: MutableScope = new PackageScope() def doComplete(root: SymDenotation)(implicit ctx: Context): Unit = { -- cgit v1.2.3