aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/core/Types.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2014-02-22 13:40:37 +0100
committerMartin Odersky <odersky@gmail.com>2014-02-24 18:56:48 +0100
commitc673f2dc2be0e055bd08522f6e91ff704dc43e93 (patch)
tree348a0808e9226b0fb0e1680bff3fbd8e53493371 /src/dotty/tools/dotc/core/Types.scala
parent691bae22c373bc72ad77cdd1968c35a445c34437 (diff)
downloaddotty-c673f2dc2be0e055bd08522f6e91ff704dc43e93.tar.gz
dotty-c673f2dc2be0e055bd08522f6e91ff704dc43e93.tar.bz2
dotty-c673f2dc2be0e055bd08522f6e91ff704dc43e93.zip
Performance improvements: Changes to TypeAccumulators and variances.
Diffstat (limited to 'src/dotty/tools/dotc/core/Types.scala')
-rw-r--r--src/dotty/tools/dotc/core/Types.scala76
1 files changed, 44 insertions, 32 deletions
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala
index b15068d81..c1d3de582 100644
--- a/src/dotty/tools/dotc/core/Types.scala
+++ b/src/dotty/tools/dotc/core/Types.scala
@@ -838,18 +838,7 @@ object Types {
* 0 means: mixed or non-variant occurrences
*/
def variances(include: TypeVar => Boolean)(implicit ctx: Context): VarianceMap = track("variances") {
- val accu = new TypeAccumulator[VarianceMap] {
- def apply(vmap: VarianceMap, t: Type): VarianceMap = t match {
- case t: TypeVar if !t.isInstantiated && include(t) =>
- val v = vmap(t)
- if (v == null) vmap.updated(t, variance)
- else if (v == variance) vmap
- else vmap.updated(t, 0)
- case _ =>
- foldOver(vmap, t)
- }
- }
- accu(SimpleMap.Empty, this)
+ ctx.addVariances(SimpleMap.Empty, this, +1, include, null)
}
/** A simplified version of this type which is equivalent wrt =:= to this type.
@@ -2089,7 +2078,7 @@ object Types {
// ----- TypeMaps --------------------------------------------------------------------
- abstract class TypeMap(implicit ctx: Context) extends (Type => Type) { thisMap =>
+ abstract class TypeMap(implicit protected val ctx: Context) extends (Type => Type) { thisMap =>
protected def stopAtStatic = true
@@ -2110,6 +2099,20 @@ object Types {
case tp: RefinedType =>
tp.derivedRefinedType(this(tp.parent), tp.refinedName, this(tp.refinedInfo))
+ case tp @ TypeBounds(lo, hi) =>
+ if (lo eq hi) {
+ val saved = variance
+ variance = variance * tp.variance
+ val lo1 = this(lo)
+ variance = saved
+ tp.derivedTypeAlias(lo1)
+ } else {
+ variance = -variance
+ val lo1 = this(lo)
+ variance = -variance
+ tp.derivedTypeBounds(lo1, this(hi))
+ }
+
case tp @ MethodType(pnames, ptypes) =>
variance = -variance
val ptypes1 = ptypes mapConserve this
@@ -2129,20 +2132,6 @@ object Types {
case tp @ SuperType(thistp, supertp) =>
tp.derivedSuperType(this(thistp), this(supertp))
- case tp @ TypeBounds(lo, hi) =>
- if (lo eq hi) {
- val saved = variance
- variance = variance * tp.variance
- val lo1 = this(lo)
- variance = saved
- tp.derivedTypeAlias(lo1)
- } else {
- variance = -variance
- val lo1 = this(lo)
- variance = -variance
- tp.derivedTypeBounds(lo1, this(hi))
- }
-
case tp: ClassInfo =>
mapClassInfo(tp)
@@ -2213,7 +2202,10 @@ object Types {
// ----- TypeAccumulators ----------------------------------------------------
- abstract class TypeAccumulator[T](implicit ctx: Context) extends ((T, Type) => T) {
+ abstract class TypeAccumulator[T](implicit protected val ctx: Context) extends ((T, Type) => T) {
+
+ protected def stopAtStatic = true
+
def apply(x: T, tp: Type): T
protected def applyToAnnot(x: T, annot: Annotation): T = x // don't go into annotations
@@ -2222,11 +2214,14 @@ object Types {
def foldOver(x: T, tp: Type): T = tp match {
case tp: TypeRef =>
- val tp1 = tp.lookupRefined(tp.prefix, tp.name)
- this(x, if (tp1.exists) tp1 else tp.prefix)
-
+ if (stopAtStatic && tp.symbol.isStatic) x
+ else {
+ val tp1 = tp.lookupRefined(tp.prefix, tp.name)
+ this(x, if (tp1.exists) tp1 else tp.prefix)
+ }
case tp: TermRef =>
- this(x, tp.prefix)
+ if (stopAtStatic && tp.symbol.isStatic) x
+ else this(x, tp.prefix)
case _: ThisType
| _: BoundType
@@ -2235,6 +2230,21 @@ object Types {
case tp: RefinedType =>
this(this(x, tp.parent), tp.refinedInfo)
+ case bounds @ TypeBounds(lo, hi) =>
+ if (lo eq hi) {
+ val saved = variance
+ variance = variance * bounds.variance
+ val result = this(x, lo)
+ variance = saved
+ result
+ }
+ else {
+ variance = -variance
+ val y = this(x, lo)
+ variance = -variance
+ this(y, hi)
+ }
+
case tp @ MethodType(pnames, ptypes) =>
variance = -variance
val y = foldOver(x, ptypes)
@@ -2296,10 +2306,12 @@ object Types {
}
class ExistsAccumulator(p: Type => Boolean)(implicit ctx: Context) extends TypeAccumulator[Boolean] {
+ override def stopAtStatic = false
def apply(x: Boolean, tp: Type) = x || p(tp) || foldOver(x, tp)
}
class NamedPartsAccumulator(p: NamedType => Boolean)(implicit ctx: Context) extends TypeAccumulator[mutable.Set[NamedType]] {
+ override def stopAtStatic = false
def maybeAdd(x: mutable.Set[NamedType], tp: NamedType) = if (p(tp)) x += tp else x
val seen: mutable.Set[Type] = mutable.Set()
def apply(x: mutable.Set[NamedType], tp: Type): mutable.Set[NamedType] =