From b94874635483b2864aabd86140e51e7bdd916b40 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Wed, 23 Oct 2013 12:34:45 +0200 Subject: Caching asSeenFrom on denotations. The last asSeenFrom on a SingleDenotation is cached. Also, correction of effectiveOwner in SymDenotation, which needs to understand that module classes now end in a "$". --- src/dotty/tools/dotc/core/Denotations.scala | 23 ++++++++++++++++++++--- src/dotty/tools/dotc/core/StdNames.scala | 1 + src/dotty/tools/dotc/core/SymDenotations.scala | 12 ++++++++---- 3 files changed, 29 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/dotty/tools/dotc/core/Denotations.scala b/src/dotty/tools/dotc/core/Denotations.scala index bc2d1a41e..045f74300 100644 --- a/src/dotty/tools/dotc/core/Denotations.scala +++ b/src/dotty/tools/dotc/core/Denotations.scala @@ -552,7 +552,9 @@ object Denotations { } final def dropUniqueRefsIn(denots: PreDenotation): SingleDenotation = if (hasUniqueSym && denots.containsSym(symbol)) NoDenotation else this - def asSeenFrom(pre: Type)(implicit ctx: Context): SingleDenotation = { + + type AsSeenFromResult = SingleDenotation + protected def computeAsSeenFrom(pre: Type)(implicit ctx: Context): SingleDenotation = { val owner = this match { case thisd: SymDenotation => thisd.owner case _ => if (symbol.exists) symbol.owner else NoSymbol @@ -633,8 +635,22 @@ object Denotations { */ def dropUniqueRefsIn(denots: PreDenotation): PreDenotation + private var cachedPrefix: Type = _ + private var cachedAsSeenFrom: AsSeenFromResult = _ + private var validAsSeenFrom: Period = Nowhere + type AsSeenFromResult <: PreDenotation + /** The denotation with info(s) as seen from prefix type */ - def asSeenFrom(pre: Type)(implicit ctx: Context): PreDenotation + final def asSeenFrom(pre: Type)(implicit ctx: Context): AsSeenFromResult = { + if ((cachedPrefix ne pre) || ctx.period != validAsSeenFrom) { + cachedAsSeenFrom = computeAsSeenFrom(pre) + cachedPrefix = pre + validAsSeenFrom = ctx.period + } + cachedAsSeenFrom + } + + protected def computeAsSeenFrom(pre: Type)(implicit ctx: Context): AsSeenFromResult /** The union of two groups. */ def union(that: PreDenotation) = @@ -662,7 +678,8 @@ object Denotations { derivedUnion(denots1.filterExcluded(excluded), denots2.filterExcluded(excluded)) def dropUniqueRefsIn(denots: PreDenotation): PreDenotation = derivedUnion(denots1.dropUniqueRefsIn(denots), denots2.dropUniqueRefsIn(denots)) - def asSeenFrom(pre: Type)(implicit ctx: Context): PreDenotation = + type AsSeenFromResult = PreDenotation + protected def computeAsSeenFrom(pre: Type)(implicit ctx: Context): PreDenotation = derivedUnion(denots1.asSeenFrom(pre), denots2.asSeenFrom(pre)) private def derivedUnion(denots1: PreDenotation, denots2: PreDenotation) = if ((denots1 eq this.denots1) && (denots2 eq this.denots2)) this diff --git a/src/dotty/tools/dotc/core/StdNames.scala b/src/dotty/tools/dotc/core/StdNames.scala index b5f776e13..e10758810 100644 --- a/src/dotty/tools/dotc/core/StdNames.scala +++ b/src/dotty/tools/dotc/core/StdNames.scala @@ -110,6 +110,7 @@ object StdNames { val NAME_JOIN: N = NameTransformer.NAME_JOIN_STRING val USCORE_PARAM_PREFIX: N = "_$" val PACKAGE: N = "package" + val PACKAGE_CLS: N = "package$" val PROTECTED_PREFIX: N = "protected$" val PROTECTED_SET_PREFIX: N = PROTECTED_PREFIX + "set" val ROOT: N = "" diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala index 9142e3185..ab58ec3b0 100644 --- a/src/dotty/tools/dotc/core/SymDenotations.scala +++ b/src/dotty/tools/dotc/core/SymDenotations.scala @@ -258,8 +258,10 @@ object SymDenotations { initial.asSymDenotation.name startsWith tpnme.ANON_CLASS /** Is this symbol a package object or its module class? */ - def isPackageObject(implicit ctx: Context): Boolean = - (name.toTermName == nme.PACKAGEkw) && (owner is Package) && (this is Module) + def isPackageObject(implicit ctx: Context): Boolean = { + val poName = if (isType) nme.PACKAGE_CLS else nme.PACKAGE + (name.toTermName == poName) && (owner is Package) && (this is Module) + } /** Is this symbol an abstract type? */ final def isAbstractType = isType && (this is Deferred) @@ -956,7 +958,9 @@ object SymDenotations { } else NoDenotation override final def findMember(name: Name, pre: Type, excluded: FlagSet)(implicit ctx: Context): Denotation = - membersNamed(name).filterExcluded(excluded).asSeenFrom(pre).toDenot(pre) + //ctx.typeComparer.traceIndented(s"($this).findMember($name, $pre)") { // DEBUG + membersNamed(name).filterExcluded(excluded).asSeenFrom(pre).toDenot(pre) + //} private[this] var baseTypeCache: java.util.HashMap[CachedType, Type] = null private[this] var baseTypeValid: RunId = NoRunId @@ -1064,7 +1068,7 @@ object SymDenotations { override def isTerm = false override def isType = false override def owner: Symbol = throw new AssertionError("NoDenotation.owner") - override def asSeenFrom(pre: Type)(implicit ctx: Context): SingleDenotation = this + override def computeAsSeenFrom(pre: Type)(implicit ctx: Context): SingleDenotation = this validFor = Period.allInRun(NoRunId) // will be brought forward automatically } -- cgit v1.2.3