aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/core/SymDenotations.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2014-12-18 15:39:55 +0100
committerMartin Odersky <odersky@gmail.com>2014-12-18 15:43:22 +0100
commit223fa2bea328fc53f87d6f9d0c28c67545e831af (patch)
tree0bfffb4a2168df6527779d4d97a87f7309ee333c /src/dotty/tools/dotc/core/SymDenotations.scala
parente0bf1758ac32d69cf97d28f449cc0400755e3914 (diff)
downloaddotty-223fa2bea328fc53f87d6f9d0c28c67545e831af.tar.gz
dotty-223fa2bea328fc53f87d6f9d0c28c67545e831af.tar.bz2
dotty-223fa2bea328fc53f87d6f9d0c28c67545e831af.zip
More careful usage of unforced decls in classes.
1) Rename `decls` to `unforcedDecls` to make it clear that it is danegrous to use. 2) Prefer `info.decls` over `unforcedDecls`. This fixes the problem reported in #305 where the primary constructor was not found.
Diffstat (limited to 'src/dotty/tools/dotc/core/SymDenotations.scala')
-rw-r--r--src/dotty/tools/dotc/core/SymDenotations.scala30
1 files changed, 19 insertions, 11 deletions
diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala
index eccdcbfb9..224b65b43 100644
--- a/src/dotty/tools/dotc/core/SymDenotations.scala
+++ b/src/dotty/tools/dotc/core/SymDenotations.scala
@@ -45,7 +45,7 @@ trait SymDenotations { this: Context =>
val owner = denot.owner.denot
stillValid(owner) && (
!owner.isClass
- || (owner.decls.lookupAll(denot.name) contains denot.symbol)
+ || (owner.unforcedDecls.lookupAll(denot.name) contains denot.symbol)
|| denot.isSelfSym
)
} catch {
@@ -234,12 +234,20 @@ object SymDenotations {
final def ensureCompleted()(implicit ctx: Context): Unit = info
/** The symbols defined in this class or object.
+ * Careful! This coes not force the type, so is compilation order dependent.
+ * This method should be used only in the following circumstances:
+ *
+ * 1. When accessing type parameters or type parameter accessors (both are entered before
+ * completion).
+ * 2. When obtaining the current scope in order to enter, rename or delete something there.
+ * 3. When playing it safe in order not to raise CylicReferences, e.g. for printing things
+ * or taking more efficient shortcuts (e.g. the stillValid test).
*/
- final def decls(implicit ctx: Context): Scope = myInfo match {
+ final def unforcedDecls(implicit ctx: Context): Scope = myInfo match {
case cinfo: LazyType =>
val knownDecls = cinfo.decls
if (knownDecls ne EmptyScope) knownDecls
- else { completeFrom(cinfo); decls } // complete-once
+ else { completeFrom(cinfo); unforcedDecls } // complete-once
case _ => info.decls
}
@@ -251,7 +259,7 @@ object SymDenotations {
*/
final def preDecls(implicit ctx: Context): MutableScope = myInfo match {
case pinfo: SymbolLoaders # PackageLoader => pinfo.preDecls
- case _ => decls.asInstanceOf[MutableScope]
+ case _ => unforcedDecls.asInstanceOf[MutableScope]
}
// ------ Names ----------------------------------------------
@@ -997,7 +1005,7 @@ object SymDenotations {
def computeTypeParams = {
if (ctx.erasedTypes || is(Module)) Nil // fast return for modules to avoid scanning package decls
else if (this ne initial) initial.asSymDenotation.typeParams
- else decls.filter(sym =>
+ else unforcedDecls.filter(sym =>
(sym is TypeParam) && sym.owner == symbol).asInstanceOf[List[TypeSymbol]]
}
if (myTypeParams == null) myTypeParams = computeTypeParams
@@ -1228,7 +1236,7 @@ object SymDenotations {
def enter(sym: Symbol, scope: Scope = EmptyScope)(implicit ctx: Context): Unit = {
val mscope = scope match {
case scope: MutableScope => scope
- case _ => decls.asInstanceOf[MutableScope]
+ case _ => unforcedDecls.asInstanceOf[MutableScope]
}
if (this is PackageClass) {
val entry = mscope.lookupEntry(sym.name)
@@ -1258,7 +1266,7 @@ object SymDenotations {
*/
def replace(prev: Symbol, replacement: Symbol)(implicit ctx: Context): Unit = {
require(!(this is Frozen))
- decls.asInstanceOf[MutableScope].replace(prev, replacement)
+ unforcedDecls.asInstanceOf[MutableScope].replace(prev, replacement)
if (myMemberCache != null)
myMemberCache invalidate replacement.name
}
@@ -1281,7 +1289,7 @@ object SymDenotations {
* have existing symbols.
*/
final def membersNamed(name: Name)(implicit ctx: Context): PreDenotation = {
- val privates = decls.denotsNamed(name, selectPrivate)
+ val privates = info.decls.denotsNamed(name, selectPrivate)
privates union nonPrivateMembersNamed(name).filterDisjoint(privates)
}
@@ -1311,7 +1319,7 @@ object SymDenotations {
(memberFingerPrint contains name)) {
Stats.record("computeNPMembersNamed after fingerprint")
ensureCompleted()
- val ownDenots = decls.denotsNamed(name, selectNonPrivate)
+ val ownDenots = info.decls.denotsNamed(name, selectNonPrivate)
if (debugTrace) // DEBUG
println(s"$this.member($name), ownDenots = $ownDenots")
def collect(denots: PreDenotation, parents: List[TypeRef]): PreDenotation = parents match {
@@ -1458,14 +1466,14 @@ object SymDenotations {
override def primaryConstructor(implicit ctx: Context): Symbol = {
val cname = if (this is ImplClass) nme.IMPLCLASS_CONSTRUCTOR else nme.CONSTRUCTOR
- decls.denotsNamed(cname).last.symbol // denotsNamed returns Symbols in reverse order of occurrence
+ info.decls.denotsNamed(cname).last.symbol // denotsNamed returns Symbols in reverse order of occurrence
}
/** The parameter accessors of this class. Term and type accessors,
* getters and setters are all returned int his list
*/
def paramAccessors(implicit ctx: Context): List[Symbol] =
- decls.filter(_ is ParamAccessor).toList
+ unforcedDecls.filter(_ is ParamAccessor).toList
/** If this class has the same `decls` scope reference in `phase` and
* `phase.next`, install a new denotation with a cloned scope in `phase.next`.