summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2009-10-13 21:43:06 +0000
committerPaul Phillips <paulp@improving.org>2009-10-13 21:43:06 +0000
commit447c7aed6748cab91809db84d92ce1fdf0401d89 (patch)
treebd80509bce759de5b9539907137ca46f9f4b6e95 /src/compiler
parentbb817a67b99253662f42f788555a3617310a52a0 (diff)
downloadscala-447c7aed6748cab91809db84d92ce1fdf0401d89.tar.gz
scala-447c7aed6748cab91809db84d92ce1fdf0401d89.tar.bz2
scala-447c7aed6748cab91809db84d92ce1fdf0401d89.zip
Yet more tracing code.
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/scala/tools/nsc/matching/MatchSupport.scala28
-rw-r--r--src/compiler/scala/tools/nsc/matching/Matrix.scala3
-rw-r--r--src/compiler/scala/tools/nsc/matching/ParallelMatching.scala39
-rw-r--r--src/compiler/scala/tools/nsc/matching/PatternBindings.scala15
-rw-r--r--src/compiler/scala/tools/nsc/matching/Patterns.scala25
5 files changed, 81 insertions, 29 deletions
diff --git a/src/compiler/scala/tools/nsc/matching/MatchSupport.scala b/src/compiler/scala/tools/nsc/matching/MatchSupport.scala
index 927079bedc..ddd3c7b71b 100644
--- a/src/compiler/scala/tools/nsc/matching/MatchSupport.scala
+++ b/src/compiler/scala/tools/nsc/matching/MatchSupport.scala
@@ -182,6 +182,22 @@ trait MatchSupport extends ast.TreeDSL
case _ => List(t)
}
+ def printLogicalOr(t1: (Tree, Boolean), t2: (Tree, Boolean)) =
+ printLogicalOp(t1, t2, "||")
+
+ def printLogicalAnd(t1: (Tree, Boolean), t2: (Tree, Boolean)) =
+ printLogicalOp(t1, t2, "&&")
+
+ def printLogicalOp(t1: (Tree, Boolean), t2: (Tree, Boolean), op: String) = {
+ def maybenot(tvalue: Boolean) = if (tvalue) "" else "!"
+
+ printRow(List(t1._1, t2._1),
+ " %s(" format maybenot(t1._2),
+ ") %s %s(".format(op, maybenot(t2._2)),
+ ")"
+ )
+ }
+
override def printRaw(tree: Tree): Unit = {
// routing supercalls through this for debugging ease
def s() = super.printRaw(tree)
@@ -224,8 +240,18 @@ trait MatchSupport extends ast.TreeDSL
// We get a lot of this stuff
case If( IsTrue(), x, _) => printRaw(x)
case If(IsFalse(), _, x) => printRaw(x)
+
+ case If(cond, IsTrue(), elsep) =>
+ printLogicalOr(cond -> true, elsep -> true)
+
case If(cond, IsFalse(), elsep) =>
- printRow(List(cond, elsep), " !(", ") && (", ") ")
+ printLogicalAnd(cond -> false, elsep -> true)
+
+ case If(cond, thenp, IsTrue()) =>
+ printLogicalOr(cond -> false, thenp -> true)
+
+ case If(cond, thenp, IsFalse()) =>
+ printLogicalAnd(cond -> true, thenp -> true)
// If thenp or elsep has only one statement, it doesn't need more than one line.
case If(cond, thenp, elsep) =>
diff --git a/src/compiler/scala/tools/nsc/matching/Matrix.scala b/src/compiler/scala/tools/nsc/matching/Matrix.scala
index c489955e5e..188a639b97 100644
--- a/src/compiler/scala/tools/nsc/matching/Matrix.scala
+++ b/src/compiler/scala/tools/nsc/matching/Matrix.scala
@@ -132,6 +132,7 @@ trait Matrix extends MatrixAdditions {
(t, PatternVarGroup(ts))
}
+ def isEmpty = pvs.isEmpty
def size = pvs.size
def head = pvs.head
def ::(t: PatternVar) = PatternVarGroup(t :: pvs)
@@ -143,6 +144,8 @@ trait Matrix extends MatrixAdditions {
def indices = pvs.indices
def map[T](f: PatternVar => T) = pvs map f
def filter(p: PatternVar => Boolean) = PatternVarGroup(pvs filter p)
+
+ override def toString() = pp(pvs)
}
/** Every temporary variable allocated is put in a PatternVar.
diff --git a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
index 02e6afdb4e..6c8c2c5956 100644
--- a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
+++ b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
@@ -72,6 +72,7 @@ trait ParallelMatching extends ast.TreeDSL
/** the injection here handles alternatives and unapply type tests */
final def make(tvars: PatternVarGroup, row1: List[Row]): Rep = {
+ // TRACE("make(%s%s)", pp(tvars.pvs, 1, true), pp(row1, 1, true))
def classifyPat(opat: Pattern, j: Int): Pattern = opat simplify tvars(j)
val rows = row1 flatMap (_ expandAlternatives classifyPat)
@@ -188,7 +189,15 @@ trait ParallelMatching extends ast.TreeDSL
// Any unapply - returns Some(true) if a type test is needed before the unapply can
// be called (e.g. def unapply(x: Foo) = { ... } but our scrutinee is type Any.)
object AnyUnapply {
- def unapply(x: Tree): Option[Boolean] = condOpt(x) { case UnapplyParamType(tpe) => !(scrut.tpe <:< tpe) }
+ def unapply(x: Tree): Option[Boolean] = condOpt(x) {
+ case UnapplyParamType(tpe) => !(scrut.tpe <:< tpe)
+ }
+ }
+
+ object TypedUnapply {
+ def unapply(x: Tree): Option[Boolean] = condOpt(x) {
+ case Typed(UnapplyParamType(tpe), tpt) => !(tpt.tpe <:< tpe)
+ }
}
def mkRule(rest: Rep): RuleApplication = {
@@ -196,6 +205,7 @@ trait ParallelMatching extends ast.TreeDSL
case x if isEquals(x.tpe) => new MixEquals(this, rest)
case x: ArrayValue => new MixSequence(this, rest)
case AnyUnapply(false) => new MixUnapply(this, rest, false)
+ // case TypedUnapply(needsTest) =>
case _ =>
isPatternSwitch(scrut, ps) match {
case Some(x) => new MixLiteralInts(x, rest)
@@ -609,9 +619,10 @@ trait ParallelMatching extends ast.TreeDSL
/*** States, Rows, Etc. ***/
case class Row(pats: List[Pattern], subst: Bindings, guard: Guard, bx: Int) {
- private def substpp = if (subst.get().isEmpty) "" else "(free = %s)".format(pp(subst.get()))
+ private def nobindings = subst.get().isEmpty
+ private def bindstr = if (nobindings) "" else pp(subst)
if (pats exists (p => !p.isDefault))
- traceCategory("Row", "%s%s", pats, substpp)
+ traceCategory("Row", "%s%s", pats, bindstr)
/** Extracts the 'i'th pattern. */
def extractColumn(i: Int) = {
@@ -644,7 +655,10 @@ trait ParallelMatching extends ast.TreeDSL
if (others.isEmpty) List(copy(pats = ps))
else extractBindings(others.head) map (x => replaceAt(ps.size, x))
}
- override def toString() = pp(bx -> (pats, subst))
+ override def toString() = {
+ val bs = if (nobindings) "" else "\n" + bindstr
+ "Row(%d)(%s%s)".format(bx, pp(pats), bs)
+ }
}
object ExpandedMatrix {
@@ -657,9 +671,13 @@ trait ParallelMatching extends ast.TreeDSL
require(rows.size == targets.size)
override def toString() = {
- def rprint(r: Row) = "Row %d: %d pats, %d bound".format(r.bx, r.pats.size, r.subst.get().size)
- def tprint(t: FinalState) = "%s (free = %s)".format(t.body, pp(t.freeVars))
- val xs = rows zip targets map { case (r,t) => rprint(r) -> tprint(t) }
+ def vprint(vs: List[Any]) = if (vs.isEmpty) "" else ": %s".format(pp(vs))
+ def rprint(r: Row) = pp(r)
+ def tprint(t: FinalState) =
+ if (t.freeVars.isEmpty) " ==> %s".format(pp(t.body))
+ else " ==>\n %s".format(pp(t.freeVars -> t.body))
+
+ val xs = rows zip targets map { case (r,t) => rprint(r) + tprint(t) }
val ppstr = pp(xs, newlines = true)
"ExpandedMatrix(%d rows)".format(rows.size) + ppstr
@@ -769,7 +787,7 @@ trait ParallelMatching extends ast.TreeDSL
}
/** Converts this to a tree - recursively acquires subreps. */
- final def toTree(): Tree = typer typed this.applyRule()
+ final def toTree(): Tree = tracing("toTree", typer typed applyRule())
/** The VariableRule. */
private def variable() = {
@@ -793,9 +811,10 @@ trait ParallelMatching extends ast.TreeDSL
else if (others.isEmpty) variable.tree()
else mixture.tree()
+ def ppn(x: Any) = pp(x, newlines = true)
override def toString() =
- if (tvars.size == 0) "Rep(%d) = %s".format(rows.size, pp(rows))
- else "Rep(%dx%d)\n %s\n %s".format(tvars.size, rows.size, pp(tvars), pp(rows))
+ if (tvars.size == 0) "Rep(%d) = %s".format(rows.size, ppn(rows))
+ else "Rep(%dx%d)%s%s".format(tvars.size, rows.size, ppn(tvars), ppn(rows))
}
val NoRep = Rep(Nil, Nil)
diff --git a/src/compiler/scala/tools/nsc/matching/PatternBindings.scala b/src/compiler/scala/tools/nsc/matching/PatternBindings.scala
index 7132b5d883..4d789a6c00 100644
--- a/src/compiler/scala/tools/nsc/matching/PatternBindings.scala
+++ b/src/compiler/scala/tools/nsc/matching/PatternBindings.scala
@@ -50,13 +50,14 @@ trait PatternBindings extends ast.TreeDSL
// bound variables beneath them return a list of said patterns for flatMapping.
def subpatternsForVars: List[Pattern] = Nil
- // This is what calls subpatternsForVars.
- // XXX reverse?
- def deepBoundVariables: List[Symbol] = deepstrip(boundTree)
- // (boundVariables ::: otherBoundVariables).reverse
-
private def shallowBoundVariables = strip(boundTree)
private def otherBoundVariables = subpatternsForVars flatMap (_.deepBoundVariables)
+
+ def deepBoundVariables: List[Symbol] = shallowBoundVariables ::: otherBoundVariables
+ // An indiscriminate deep search would be:
+ //
+ // def deepBoundVariables = deepstrip(boundTree)
+
lazy val boundVariables = {
val res = shallowBoundVariables
val deep = deepBoundVariables
@@ -142,7 +143,9 @@ trait PatternBindings extends ast.TreeDSL
new Bindings(newBindings ++ vlist)
}
- override def toString() = pp(vlist)
+ override def toString() =
+ if (vlist.isEmpty) "No Bindings"
+ else "%d Bindings(%s)".format(vlist.size, pp(vlist))
}
val NoBinding: Bindings = new Bindings(Nil)
diff --git a/src/compiler/scala/tools/nsc/matching/Patterns.scala b/src/compiler/scala/tools/nsc/matching/Patterns.scala
index 184054bc04..df05a02b2a 100644
--- a/src/compiler/scala/tools/nsc/matching/Patterns.scala
+++ b/src/compiler/scala/tools/nsc/matching/Patterns.scala
@@ -95,7 +95,8 @@ trait Patterns extends ast.TreeDSL {
// 8.1.4 (c)
case class StableIdPattern(tree: Select) extends SelectPattern {
def select = tree
- override def description = "StableId(%s)".format(pathSegments.mkString(" . "))
+ override def description = "StableId(%s)".format(printableSegments.mkString(" . "))
+ private def printableSegments = pathSegments filterNot (_.toString == "$iw")
}
// 8.1.4 (d)
case class ObjectPattern(tree: Apply) extends ApplyPattern { // NamePattern?
@@ -129,7 +130,6 @@ trait Patterns extends ast.TreeDSL {
}
// 8.1.6
case class TuplePattern(tree: Apply) extends ApplyPattern {
- override def necessaryType = ProductRootClass.tpe
// XXX todo
// override def irrefutableFor(tpe: Type) = false
}
@@ -260,6 +260,7 @@ trait Patterns extends ast.TreeDSL {
// 8.1.8 (c)
case class StarPattern(tree: Star) extends Pattern {
val Star(elem) = tree
+ override def description = "*"
}
// 8.1.9
@@ -316,7 +317,6 @@ trait Patterns extends ast.TreeDSL {
def unapply(other: Any): Option[(Tree, List[Symbol])] = other match {
case x: Tree => unapply(Pattern(x))
case x: Pattern => Some((x.tree, x.boundVariables))
- // case x: Pattern => Some((x.tree, x.deepBoundVariables))
case _ => None
}
}
@@ -404,6 +404,7 @@ trait Patterns extends ast.TreeDSL {
def name: Name
override def sufficientType = tpe.narrow
override def simplify(pv: PatternVar) = this.rebindToEqualsCheck()
+ override def description = name.toString()
}
sealed trait UnapplyPattern extends Pattern {
@@ -463,10 +464,10 @@ trait Patterns extends ast.TreeDSL {
// what type could a scrutinee have which would automatically indicate a match?
// (nullness and guards will still be checked.)
- def sufficientType = NothingClass.tpe
- // XXX a more plausible default is:
- //
- // def sufficientType = tpe.narrow
+ def sufficientType = tpe
+
+ // XXX have to determine if this can be made useful beyond an extractor barrier.
+ // Default sufficient type might be NothingClass.tpe, tpe.narrow, ...
// the subpatterns for this pattern (at the moment, that means constructor arguments)
def subpatterns(pm: MatchMatrix#PatternMatch): List[Pattern] = pm.dummies
@@ -511,17 +512,17 @@ trait Patterns extends ast.TreeDSL {
)
/** Standard methods **/
- def copy(tree: Tree = this.tree): Pattern =
- if (boundTree eq tree) Pattern(tree)
- else Pattern(tree) withBoundTree boundTree.asInstanceOf[Bind]
-
override def equals(other: Any) = other match {
case x: Pattern => this.boundTree == x.boundTree
case _ => super.equals(other)
}
override def hashCode() = boundTree.hashCode()
def description = super.toString()
- final override def toString() = "%s %s".format(description, isSequence)
+ final override def toString() = {
+ if (boundVariables.isEmpty) description
+ else "%s @ (%s)".format(boundVariables.mkString(", "), description)
+ }
+ def toTypeString() = "%s <: x <: %s".format(necessaryType, sufficientType)
}
/*** Extractors ***/