aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/core/Scopes.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2014-11-03 10:30:13 +0100
committerMartin Odersky <odersky@gmail.com>2014-11-09 19:08:59 +0100
commitb8b06825fe575d7a6750874299cb356da99f5bc6 (patch)
tree73d510f3501cab3f29ae338d99155c5eb287ee74 /src/dotty/tools/dotc/core/Scopes.scala
parent97080a8b5dda38d50ff288dd60c92a06a04dd75a (diff)
downloaddotty-b8b06825fe575d7a6750874299cb356da99f5bc6.tar.gz
dotty-b8b06825fe575d7a6750874299cb356da99f5bc6.tar.bz2
dotty-b8b06825fe575d7a6750874299cb356da99f5bc6.zip
Make cloneScope less forcefull.
Motivation: Avoid needless forcing of symbols in scope. This is a problem when cloneScope is called in TreeTransforms.
Diffstat (limited to 'src/dotty/tools/dotc/core/Scopes.scala')
-rw-r--r--src/dotty/tools/dotc/core/Scopes.scala31
1 files changed, 25 insertions, 6 deletions
diff --git a/src/dotty/tools/dotc/core/Scopes.scala b/src/dotty/tools/dotc/core/Scopes.scala
index 494a26f7e..09bdca196 100644
--- a/src/dotty/tools/dotc/core/Scopes.scala
+++ b/src/dotty/tools/dotc/core/Scopes.scala
@@ -20,7 +20,7 @@ import printing.Printer
import util.common._
import util.DotClass
import SymDenotations.NoDenotation
-import collection.mutable.ListBuffer
+import collection.mutable
object Scopes {
@@ -172,12 +172,27 @@ object Scopes {
*/
private var elemsCache: List[Symbol] = null
- def cloneScope(implicit ctx: Context): MutableScope = newScopeWith(this.toList: _*)
+ /** Clone scope, taking care not to force the denotations of any symbols in the scope.
+ */
+ def cloneScope(implicit ctx: Context): MutableScope = {
+ val entries = new mutable.ArrayBuffer[ScopeEntry]
+ var e = lastEntry
+ while ((e ne null) && e.owner == this) {
+ entries += e
+ e = e.prev
+ }
+ val scope = newScope
+ for (i <- entries.length - 1 to 0 by -1) {
+ val e = entries(i)
+ scope.newScopeEntry(e.name, e.sym)
+ }
+ scope
+ }
- /** create and enter a scope entry */
- protected def newScopeEntry(sym: Symbol)(implicit ctx: Context): ScopeEntry = {
+ /** 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(sym.name, sym, this)
+ val e = new ScopeEntry(name, sym, this)
e.prev = lastEntry
lastEntry = e
if (hashTable ne null) enterInHash(e)
@@ -186,6 +201,10 @@ object Scopes {
e
}
+ /** create and enter a scope entry */
+ protected def newScopeEntry(sym: Symbol)(implicit ctx: Context): ScopeEntry =
+ newScopeEntry(sym.name, sym)
+
private def enterInHash(e: ScopeEntry)(implicit ctx: Context): Unit = {
val idx = e.name.hashCode & (hashTable.length - 1)
e.tail = hashTable(idx)
@@ -325,7 +344,7 @@ object Scopes {
}
override def implicitDecls(implicit ctx: Context): List[TermRef] = {
- var irefs = new ListBuffer[TermRef]
+ var irefs = new mutable.ListBuffer[TermRef]
var e = lastEntry
while (e ne null) {
if (e.sym is Implicit) {