diff options
author | Martin Odersky <odersky@gmail.com> | 2014-11-03 10:30:13 +0100 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2014-11-09 19:08:59 +0100 |
commit | b8b06825fe575d7a6750874299cb356da99f5bc6 (patch) | |
tree | 73d510f3501cab3f29ae338d99155c5eb287ee74 /src/dotty/tools/dotc/core/Scopes.scala | |
parent | 97080a8b5dda38d50ff288dd60c92a06a04dd75a (diff) | |
download | dotty-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.scala | 31 |
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) { |