diff options
author | Martin Odersky <odersky@gmail.com> | 2007-03-14 17:26:47 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2007-03-14 17:26:47 +0000 |
commit | 611228e4e8a546caa5b161295070755b6d535995 (patch) | |
tree | 6fba7460adcf995ca427e421bb02fd524e465037 | |
parent | e8540b5d784102174da77ea485253288b30dac90 (diff) | |
download | scala-611228e4e8a546caa5b161295070755b6d535995.tar.gz scala-611228e4e8a546caa5b161295070755b6d535995.tar.bz2 scala-611228e4e8a546caa5b161295070755b6d535995.zip |
fixed bug 1001
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/Types.scala | 29 |
1 files changed, 26 insertions, 3 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala index 3f82afde11..d368ff37f5 100644 --- a/src/compiler/scala/tools/nsc/symtab/Types.scala +++ b/src/compiler/scala/tools/nsc/symtab/Types.scala @@ -7,7 +7,7 @@ package scala.tools.nsc.symtab import compat.Platform.currentTime -import scala.collection.mutable.ListBuffer +import scala.collection.mutable.{ListBuffer, HashMap} import scala.tools.nsc.util.{HashSet, Position} import Flags._ @@ -55,6 +55,13 @@ trait Types requires SymbolTable { val emptyTypeArray = new Array[Type](0) + /** A map from lists to compound types that have the given list as parents. + * This is used to avoid duplication in the computation of closure and baseClasses. + * It makes use of the fact that these two operations depend only on the parents, + * not on the refinement. + */ + var intersectionWitness = new HashMap[List[Type], Type] + /** The base class for all types */ abstract class Type { @@ -763,7 +770,7 @@ trait Types requires SymbolTable { closurePeriod = currentPeriod if (!isValidForBaseClasses(period)) { closureCache = null - closureCache = computeClosure + closureCache = memo[Array[Type], Type](computeClosure, modifyClosure(symbol.tpe)) closureDepthCache = maxDepth(closureCache) } //Console.println("closure(" + symbol + ") = " + List.fromArray(closureCache));//DEBUG @@ -807,7 +814,7 @@ trait Types requires SymbolTable { baseClassesPeriod = currentPeriod if (!isValidForBaseClasses(period)) { baseClassesCache = null - baseClassesCache = computeBaseClasses + baseClassesCache = memo[List[Symbol], Symbol](computeBaseClasses, x => symbol :: x.baseClasses.tail) } } if (baseClassesCache eq null) @@ -815,6 +822,14 @@ trait Types requires SymbolTable { baseClassesCache } + def memo[A <: Seq[B], B](op1: => A, op2: Type => A) = intersectionWitness get parents match { + case Some(w) => + if (w eq this) op1 else op2(w) + case None => + intersectionWitness(parents) = this + op1 + } + override def baseType(sym: Symbol): Type = { val index = closurePos(sym) if (index >= 0) closure(index) else NoType @@ -2342,6 +2357,14 @@ trait Types requires SymbolTable { cl1 } + private def modifyClosure(tp: Type)(other: Type): Array[Type] = { + val cl = other.closure + val cl1 = new Array[Type](cl.length) + cl1(0) = tp + Array.copy(cl, 1, cl1, 1, cl.length-1) + cl1 + } + /** like map2, but returns list `xs' itself - instead of a copy - if function * <code>f</code> maps all elements to themselves. */ |