aboutsummaryrefslogtreecommitdiff
path: root/compiler/src/dotty/tools/dotc/core/Scopes.scala
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/src/dotty/tools/dotc/core/Scopes.scala')
-rw-r--r--compiler/src/dotty/tools/dotc/core/Scopes.scala73
1 files changed, 44 insertions, 29 deletions
diff --git a/compiler/src/dotty/tools/dotc/core/Scopes.scala b/compiler/src/dotty/tools/dotc/core/Scopes.scala
index 6090079e5..205798474 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
@@ -60,7 +60,7 @@ object Scopes {
* or to delete them. These methods are provided by subclass
* MutableScope.
*/
- abstract class Scope extends DotClass with printing.Showable with Iterable[Symbol] {
+ abstract class Scope extends DotClass with printing.Showable {
/** The last scope-entry from which all others are reachable via `prev` */
private[dotc] def lastEntry: ScopeEntry
@@ -76,18 +76,37 @@ object Scopes {
/** The symbols in this scope in the order they were entered;
* inherited from outer ones first.
*/
- def toList: List[Symbol]
+ def toList(implicit ctx: Context): List[Symbol]
/** Return all symbols as an iterator in the order they were entered in this scope.
*/
- def iterator: Iterator[Symbol] = toList.iterator
+ def iterator(implicit ctx: Context): Iterator[Symbol] = toList.iterator
+
+ /** Is the scope empty? */
+ def isEmpty: Boolean = lastEntry eq null
+
+ def foreach[U](p: Symbol => U)(implicit ctx: Context): Unit = toList foreach p
+
+ def filter(p: Symbol => Boolean)(implicit ctx: Context): List[Symbol] = {
+ ensureComplete()
+ var syms: List[Symbol] = Nil
+ var e = lastEntry
+ while ((e ne null) && e.owner == this) {
+ val sym = e.sym
+ if (p(sym)) syms = sym :: syms
+ e = e.prev
+ }
+ syms
+ }
+
+ def find(p: Symbol => Boolean)(implicit ctx: Context): Symbol = filter(p) match {
+ case sym :: _ => sym
+ case _ => NoSymbol
+ }
/** Returns a new mutable scope with the same content as this one. */
def cloneScope(implicit ctx: Context): MutableScope
- /** Is the scope empty? */
- override def isEmpty: Boolean = lastEntry eq null
-
/** Lookup a symbol entry matching given name. */
def lookupEntry(name: Name)(implicit ctx: Context): ScopeEntry
@@ -144,6 +163,12 @@ object Scopes {
final def toText(printer: Printer): Text = printer.toText(this)
def checkConsistent()(implicit ctx: Context) = ()
+
+ /** Ensure that all elements of this scope have been entered.
+ * Overridden by SymbolLoaders.PackageLoader#PackageScope, where it
+ * makes sure that all names with `$`'s have been added.
+ */
+ protected def ensureComplete()(implicit ctx: Context): Unit = ()
}
/** A subclass of Scope that defines methods for entering and
@@ -155,9 +180,10 @@ 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.
+ ensureCapacity(MinHashedScopeSize)(ctx) // WTH? it seems the implicit is not in scope for a secondary constructor call.
}
def this() = this(null, 0, 0)
@@ -178,6 +204,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 +215,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)
@@ -197,7 +225,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)
+ ensureCapacity(if (hashTable ne null) hashTable.length else MinHashedScopeSize)
val e = new ScopeEntry(name, sym, this)
e.prev = lastEntry
lastEntry = e
@@ -338,8 +366,9 @@ object Scopes {
/** Returns all symbols as a list in the order they were entered in this scope.
* Does _not_ include the elements of inherited scopes.
*/
- override final def toList: List[Symbol] = {
+ override final def toList(implicit ctx: Context): List[Symbol] = {
if (elemsCache eq null) {
+ ensureComplete()
elemsCache = Nil
var e = lastEntry
while ((e ne null) && e.owner == this) {
@@ -351,6 +380,7 @@ object Scopes {
}
override def implicitDecls(implicit ctx: Context): List[TermRef] = {
+ ensureComplete()
var irefs = new mutable.ListBuffer[TermRef]
var e = lastEntry
while (e ne null) {
@@ -365,25 +395,13 @@ object Scopes {
/** Vanilla scope - symbols are stored in declaration order.
*/
- final def sorted: List[Symbol] = toList
-
- override def foreach[U](p: Symbol => U): Unit = toList foreach p
-
- override def filter(p: Symbol => Boolean): List[Symbol] = {
- var syms: List[Symbol] = Nil
- var e = lastEntry
- while ((e ne null) && e.owner == this) {
- val sym = e.sym
- if (p(sym)) syms = sym :: syms
- e = e.prev
- }
- syms
- }
+ final def sorted(implicit ctx: Context): List[Symbol] = toList
override def openForMutations: MutableScope = this
/** Check that all symbols in this scope are in their correct hashtable buckets. */
override def checkConsistent()(implicit ctx: Context) = {
+ ensureComplete()
var e = lastEntry
while (e != null) {
var e1 = lookupEntry(e.name)
@@ -407,9 +425,6 @@ object Scopes {
scope
}
- /** Create new scope for the members of package `pkg` */
- def newPackageScope(pkgClass: Symbol): MutableScope = newScope
-
/** Transform scope of members of `owner` using operation `op`
* This is overridden by the reflective compiler to avoid creating new scopes for packages
*/
@@ -425,7 +440,7 @@ object Scopes {
override private[dotc] def lastEntry = null
override def size = 0
override def nestingLevel = 0
- override def toList = Nil
+ override def toList(implicit ctx: Context) = Nil
override def cloneScope(implicit ctx: Context): MutableScope = unsupported("cloneScope")
override def lookupEntry(name: Name)(implicit ctx: Context): ScopeEntry = null
override def lookupNextEntry(entry: ScopeEntry)(implicit ctx: Context): ScopeEntry = null