summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid MacIver <david.maciver@gmail.com>2008-11-05 22:52:51 +0000
committerDavid MacIver <david.maciver@gmail.com>2008-11-05 22:52:51 +0000
commitacebf671acacbe401118a3cd6e5d9942ace6f77c (patch)
treef3e00981684280e8138f3c758cef0b1a25ec6352
parent83f3eb7f58727d2c2f31c2e5d2e88dec5dab7756 (diff)
downloadscala-acebf671acacbe401118a3cd6e5d9942ace6f77c.tar.gz
scala-acebf671acacbe401118a3cd6e5d9942ace6f77c.tar.bz2
scala-acebf671acacbe401118a3cd6e5d9942ace6f77c.zip
Flattening the hierarchy in parallel matching a...
Flattening the hierarchy in parallel matching a bit. (Courtesy of Paul).
-rw-r--r--src/compiler/scala/tools/nsc/matching/ParallelMatching.scala144
1 files changed, 61 insertions, 83 deletions
diff --git a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
index baa849d928..efe917cb2e 100644
--- a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
+++ b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
@@ -604,22 +604,7 @@ trait ParallelMatching {
def replace(hs: List[Tree]) = Row(hs, subst, guard, bx) // replaces pattern list
}
- object Rep {
- type RepType = Product2[List[Symbol], List[Row]]
- final def unapply(x:Rep)(implicit rep:RepFactory): Option[RepType] =
- if (x.isInstanceOf[rep.RepImpl]) Some(x.asInstanceOf[RepType]) else None
- }
-
class RepFactory(val handleOuter: Tree => Tree)(implicit val typer : Typer) {
- case class RepImpl(val temp:List[Symbol], val row:List[Row]) extends Rep with Rep.RepType {
- (row.find { case Row(pats, _, _, _) => temp.length != pats.length }) match {
- case Some(row) => assert(false, "temp == "+temp+" row.pats == "+row.pat);
- case _ =>
- }
- def _1 = temp
- def _2 = row
- }
-
var vss: List[List[Symbol]] = _
var labels: Array[Symbol] = new Array[Symbol](4)
var targets: List[Tree] = _
@@ -842,85 +827,78 @@ trait ParallelMatching {
}
}
- if (unchanged) RepImpl(temp, row).init
- else this.make(temp, row) // recursive call
+ // if (unchanged) RepImpl(temp, row).init
+ if (unchanged) Rep(temp, row).init else make(temp, row) // recursive call
}
}
- abstract class Rep {
- val temp: List[Symbol]
- val row: List[Row]
-
- final def init: this.type = {
- val setsToCombine: List[(Int, immutable.Set[Symbol])] =
- for {
- (sym, i) <- temp.zipWithIndex
- if sym hasFlag Flags.MUTABLE // indicates that have not yet checked exhaustivity
- if !(sym hasFlag Flags.TRANS_FLAG) // indicates @unchecked
- if sym.tpe.typeSymbol hasFlag Flags.SEALED
- } yield {
- sym resetFlag Flags.MUTABLE
- // this should enumerate all cases... however, also the superclass is taken if it is not abstract
- def candidates(tpesym: Symbol): immutable.Set[Symbol] = {
- def countCandidates(x: Symbol) = if (x hasFlag Flags.ABSTRACT) candidates(x) else candidates(x) + x
- if (tpesym hasFlag Flags.SEALED) tpesym.children.flatMap(countCandidates)
- else emptySymbolSet
- }
- (i, candidates(sym.tpe.typeSymbol))
- } // .reverse ? XXX
-
- if (setsToCombine.isEmpty) return this
-
- // computes cartesian product, keeps indices available
- def combine(colcom: List[(Int, Set[Symbol])]): List[List[(Int, Symbol)]] = colcom match {
- case Nil => Nil
- case (i,syms)::Nil => syms.toList.map { sym => List((i,sym)) }
- case (i,syms)::cs => for (s <- syms.toList; rest <- combine(cs)) yield (i,s) :: rest
+ case class Rep(val temp: List[Symbol], val row: List[Row]) {
+ private def setsToCombine: List[(Int, immutable.Set[Symbol])] = for {
+ (sym, i) <- temp.zipWithIndex
+ if sym hasFlag Flags.MUTABLE // indicates that have not yet checked exhaustivity
+ if !(sym hasFlag Flags.TRANS_FLAG) // indicates @unchecked
+ if sym.tpe.typeSymbol hasFlag Flags.SEALED
+ } yield {
+ sym resetFlag Flags.MUTABLE
+ // this should enumerate all cases... however, also the superclass is taken if it is not abstract
+ def candidates(tpesym: Symbol): immutable.Set[Symbol] = {
+ def countCandidates(x: Symbol) = if (x hasFlag Flags.ABSTRACT) candidates(x) else candidates(x) + x
+ if (tpesym hasFlag Flags.SEALED) tpesym.children.flatMap(countCandidates)
+ else emptySymbolSet
}
+ (i, candidates(sym.tpe.typeSymbol))
+ } // .reverse ? XXX
+
+ // computes cartesian product, keeps indices available
+ private def combine(colcom: List[(Int, Set[Symbol])]): List[List[(Int, Symbol)]] = colcom match {
+ case Nil => Nil
+ case (i,syms)::Nil => syms.toList.map { sym => List((i,sym)) }
+ case (i,syms)::cs => for (s <- syms.toList; rest <- combine(cs)) yield (i,s) :: rest
+ }
- val allcomb = combine(setsToCombine)
-
- /** returns true if pattern vector pats covers a type symbols "combination"
- * @param pats pattern vector
- * @param comb pairs of (column index, type symbol)
- */
- def covers(pats: List[Tree], comb: List[(Int, Symbol)]) = {
- val results = for ((i, sym) <- comb ; val p = strip2(pats(i))) yield p match {
- case _ if isDefaultPattern(p) => true
- case _: UnApply | _: ArrayValue => true
- case _ =>
- val ptpe = patternType_wrtEquals(p.tpe)
- val symtpe =
- if ((sym hasFlag Flags.MODULE) && (sym.linkedModuleOfClass ne NoSymbol))
- singleType(sym.tpe.prefix, sym.linkedModuleOfClass) // e.g. None, Nil
- else sym.tpe
-
- (ptpe.typeSymbol == sym) ||
- (symtpe <:< ptpe) ||
- (symtpe.parents.exists(_.typeSymbol eq ptpe.typeSymbol)) || // e.g. Some[Int] <: Option[&b]
- (ptpe.prefix.memberType(sym) <:< ptpe) // outer, see combinator.lexical.Scanner
- }
- results.forall(_ == true)
+ /** returns true if pattern vector pats covers a type symbols "combination"
+ * @param pats pattern vector
+ * @param comb pairs of (column index, type symbol)
+ */
+ private def covers(pats: List[Tree], comb: List[(Int, Symbol)]) = {
+ val results = for ((i, sym) <- comb ; val p = strip2(pats(i))) yield p match {
+ case _ if isDefaultPattern(p) => true
+ case _: UnApply | _: ArrayValue => true
+ case _ =>
+ val ptpe = patternType_wrtEquals(p.tpe)
+ val symtpe =
+ if ((sym hasFlag Flags.MODULE) && (sym.linkedModuleOfClass ne NoSymbol))
+ singleType(sym.tpe.prefix, sym.linkedModuleOfClass) // e.g. None, Nil
+ else sym.tpe
+
+ (ptpe.typeSymbol == sym) ||
+ (symtpe <:< ptpe) ||
+ (symtpe.parents.exists(_.typeSymbol eq ptpe.typeSymbol)) || // e.g. Some[Int] <: Option[&b]
+ (ptpe.prefix.memberType(sym) <:< ptpe) // outer, see combinator.lexical.Scanner
}
+ results.forall(_ == true)
+ }
- def comboCovers(combo: List[(Int, Symbol)]) = row exists { r => (r.guard eq EmptyTree) && covers(r.pat, combo) }
+ private def comboCovers(combo: List[(Int, Symbol)]) = row exists { r => (r.guard eq EmptyTree) && covers(r.pat, combo) }
- if (!(allcomb forall comboCovers)) {
- def mkMissingStr(xs: List[(Int, Symbol)], i: Int) = xs.find(_._1 == i) match {
- case None => pad("*")
- case Some(pair) => pad(pair._2.name.toString)
- }
+ def init: this.type = {
+ combine(setsToCombine) match {
+ case allcomb if (!(allcomb forall comboCovers)) => // not exhaustive
+ def mkMissingStr(xs: List[(Int, Symbol)], i: Int) = xs.find(_._1 == i) match {
+ case None => pad("*")
+ case Some(pair) => pad(pair._2.name.toString)
+ }
- val missingCombos =
- (for (open <- allcomb ; if row.forall(r => !covers(r.pat, open))) yield
- "missing combination " +
- (for (i <- 0 until temp.length) yield
- mkMissingStr(open, i)).mkString + "\n").mkString
+ val missingCombos =
+ (for (open <- allcomb ; if row.forall(r => !covers(r.pat, open))) yield
+ "missing combination " +
+ (for (i <- 0 until temp.length) yield
+ mkMissingStr(open, i)).mkString + "\n").mkString
- cunit.warning(temp.head.pos, "match is not exhaustive!\n" + missingCombos)
+ cunit.warning(temp.head.pos, "match is not exhaustive!\n" + missingCombos)
+ case _ =>
}
-
- return this
+ this
}
/* internal representation is (temp:List[Symbol], row:List[Row])