Skip to content

Commit 5c230e2

Browse files
committed
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`.
1 parent 19431fb commit 5c230e2

File tree

3 files changed

+31
-56
lines changed

3 files changed

+31
-56
lines changed

compiler/src/dotty/tools/dotc/core/Definitions.scala

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ class Definitions {
108108
* def apply(implicit $x0: T0, ..., $x{N_1}: T{N-1}): R
109109
* }
110110
*/
111-
private def newFunctionNTrait(name: TypeName) = {
111+
def newFunctionNTrait(name: TypeName) = {
112112
val completer = new LazyType {
113113
def complete(denot: SymDenotation)(implicit ctx: Context): Unit = {
114114
val cls = denot.asClass.classSymbol
@@ -928,23 +928,6 @@ class Definitions {
928928

929929
// ----- Initialization ---------------------------------------------------
930930

931-
/** Give the scala package a scope where a FunctionN trait is automatically
932-
* added when someone looks for it.
933-
*/
934-
private def makeScalaSpecial()(implicit ctx: Context) = {
935-
val oldInfo = ScalaPackageClass.classInfo
936-
val oldDecls = oldInfo.decls
937-
val newDecls = new PackageScope(oldDecls) {
938-
override def lookupEntry(name: Name)(implicit ctx: Context): ScopeEntry = {
939-
val res = super.lookupEntry(name)
940-
if (res == null && name.isTypeName && name.isSyntheticFunction)
941-
newScopeEntry(newFunctionNTrait(name.asTypeName))
942-
else res
943-
}
944-
}
945-
ScalaPackageClass.info = oldInfo.derivedClassInfo(decls = newDecls)
946-
}
947-
948931
/** Lists core classes that don't have underlying bytecode, but are synthesized on-the-fly in every reflection universe */
949932
lazy val syntheticScalaClasses = List(
950933
AnyClass,
@@ -972,8 +955,6 @@ class Definitions {
972955
def init()(implicit ctx: Context) = {
973956
this.ctx = ctx
974957
if (!_isInitialized) {
975-
makeScalaSpecial()
976-
977958
// force initialization of every symbol that is synthesized or hijacked by the compiler
978959
val forced = syntheticCoreClasses ++ syntheticCoreMethods ++ ScalaValueClasses()
979960

compiler/src/dotty/tools/dotc/core/Scopes.scala

Lines changed: 8 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ object Scopes {
3232
* This value must be a power of two, so that the index of an element can
3333
* be computed as element.hashCode & (hashTable.length - 1)
3434
*/
35-
private final val MinHash = 8
35+
final val MinHashedScopeSize = 8
3636

3737
/** The maximal permissible number of recursions when creating
3838
* a hashtable
@@ -144,11 +144,6 @@ object Scopes {
144144
final def toText(printer: Printer): Text = printer.toText(this)
145145

146146
def checkConsistent()(implicit ctx: Context) = ()
147-
148-
/** Hook for transforming a name before it is used in a lookup or creation.
149-
* Used to mangle names in package scopes.
150-
*/
151-
protected def normalize(name: Name): Name = name
152147
}
153148

154149
/** A subclass of Scope that defines methods for entering and
@@ -163,7 +158,7 @@ object Scopes {
163158
/** Scope shares elements with `base` */
164159
protected[Scopes] def this(base: Scope)(implicit ctx: Context) = {
165160
this(base.lastEntry, base.size, base.nestingLevel + 1)
166-
ensureCapacity(MinHash)(ctx) // WTH? it seems the implicit is not in scope for a secondary constructor call.
161+
ensureCapacity(MinHashedScopeSize)(ctx) // WTH? it seems the implicit is not in scope for a secondary constructor call.
167162
}
168163

169164
def this() = this(null, 0, 0)
@@ -205,8 +200,8 @@ object Scopes {
205200

206201
/** create and enter a scope entry with given name and symbol */
207202
protected def newScopeEntry(name: Name, sym: Symbol)(implicit ctx: Context): ScopeEntry = {
208-
ensureCapacity(if (hashTable ne null) hashTable.length else MinHash)
209-
val e = new ScopeEntry(normalize(name), sym, this)
203+
ensureCapacity(if (hashTable ne null) hashTable.length else MinHashedScopeSize)
204+
val e = new ScopeEntry(name, sym, this)
210205
e.prev = lastEntry
211206
lastEntry = e
212207
if (hashTable ne null) enterInHash(e)
@@ -242,7 +237,7 @@ object Scopes {
242237
enter(sym)
243238
}
244239

245-
protected def ensureCapacity(tableSize: Int)(implicit ctx: Context): Unit =
240+
private def ensureCapacity(tableSize: Int)(implicit ctx: Context): Unit =
246241
if (size >= tableSize * FillFactor) createHash(tableSize * 2)
247242

248243
private def createHash(tableSize: Int)(implicit ctx: Context): Unit =
@@ -318,16 +313,15 @@ object Scopes {
318313
/** Lookup a symbol entry matching given name.
319314
*/
320315
override def lookupEntry(name: Name)(implicit ctx: Context): ScopeEntry = {
321-
val normalized = normalize(name)
322316
var e: ScopeEntry = null
323317
if (hashTable ne null) {
324-
e = hashTable(normalized.hashCode & (hashTable.length - 1))
325-
while ((e ne null) && e.name != normalized) {
318+
e = hashTable(name.hashCode & (hashTable.length - 1))
319+
while ((e ne null) && e.name != name) {
326320
e = e.tail
327321
}
328322
} else {
329323
e = lastEntry
330-
while ((e ne null) && e.name != normalized) {
324+
while ((e ne null) && e.name != name) {
331325
e = e.prev
332326
}
333327
}
@@ -403,25 +397,6 @@ object Scopes {
403397
}
404398
}
405399

406-
/** The scope of a package. This is different from a normal scope
407-
* in that names of scope entries are kept in mangled form.
408-
*/
409-
class PackageScope protected[Scopes](initElems: ScopeEntry, initSize: Int, nestingLevel: Int)
410-
extends MutableScope(initElems, initSize, nestingLevel) {
411-
412-
/** Scope shares elements with `base` */
413-
def this(base: Scope)(implicit ctx: Context) = {
414-
this(base.lastEntry, base.size, base.nestingLevel + 1)
415-
ensureCapacity(MinHash)(ctx) // WTH? it seems the implicit is not in scope for a secondary constructor call.
416-
}
417-
418-
def this() = this(null, 0, 0)
419-
420-
override def newScopeLikeThis() = new PackageScope()
421-
422-
override protected def normalize(name: Name) = name.mangled
423-
}
424-
425400
/** Create a new scope */
426401
def newScope: MutableScope = new MutableScope()
427402

@@ -435,9 +410,6 @@ object Scopes {
435410
scope
436411
}
437412

438-
/** Create new scope for the members of package `pkg` */
439-
def newPackageScope(pkgClass: Symbol): MutableScope = new PackageScope()
440-
441413
/** Transform scope of members of `owner` using operation `op`
442414
* This is overridden by the reflective compiler to avoid creating new scopes for packages
443415
*/

compiler/src/dotty/tools/dotc/core/SymbolLoaders.scala

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,28 @@ class SymbolLoaders {
148148
override def sourceModule(implicit ctx: Context) = _sourceModule
149149
def description = "package loader " + classpath.name
150150

151+
/** The scope of a package. This is different from a normal scope
152+
* in three aspects:
153+
*
154+
* 1. Names of scope entries are kept in mangled form.
155+
* 2. Some function types in the `scala` package are synthesized.
156+
*/
157+
final class PackageScope extends MutableScope {
158+
override def newScopeEntry(name: Name, sym: Symbol)(implicit ctx: Context): ScopeEntry =
159+
super.newScopeEntry(name.mangled, sym)
160+
161+
override def lookupEntry(name: Name)(implicit ctx: Context): ScopeEntry = {
162+
val e = super.lookupEntry(name.mangled)
163+
if (e == null &&
164+
_sourceModule.name == nme.scala_ && _sourceModule == defn.ScalaPackageVal &&
165+
name.isTypeName && name.isSyntheticFunction)
166+
newScopeEntry(defn.newFunctionNTrait(name.asTypeName))
167+
else e
168+
}
169+
170+
override def newScopeLikeThis() = new PackageScope
171+
}
172+
151173
private[core] val currentDecls: MutableScope = new PackageScope()
152174

153175
def doComplete(root: SymDenotation)(implicit ctx: Context): Unit = {

0 commit comments

Comments
 (0)