aboutsummaryrefslogtreecommitdiff
path: root/compiler
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2017-04-02 11:43:03 +0200
committerMartin Odersky <odersky@gmail.com>2017-04-11 09:33:12 +0200
commit264211f6b7129923c01c2e3c402b157685d64b1f (patch)
tree8d60f112df5ad8d34d98766fe340802bde1bcd07 /compiler
parenta7ee8dc999f415dbbed9c4e60bf4ade1cf8a94eb (diff)
downloaddotty-264211f6b7129923c01c2e3c402b157685d64b1f.tar.gz
dotty-264211f6b7129923c01c2e3c402b157685d64b1f.tar.bz2
dotty-264211f6b7129923c01c2e3c402b157685d64b1f.zip
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`.
Diffstat (limited to 'compiler')
-rw-r--r--compiler/src/dotty/tools/dotc/core/Definitions.scala21
-rw-r--r--compiler/src/dotty/tools/dotc/core/Scopes.scala44
-rw-r--r--compiler/src/dotty/tools/dotc/core/SymbolLoaders.scala22
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 = {