summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2009-10-13 17:49:36 +0000
committerPaul Phillips <paulp@improving.org>2009-10-13 17:49:36 +0000
commitbb817a67b99253662f42f788555a3617310a52a0 (patch)
tree8c61363d0f4c5df172f5473c990ca61cdc6ca80b
parent5bfb4e7a569f779c5d0b06bb5c22bae515314033 (diff)
downloadscala-bb817a67b99253662f42f788555a3617310a52a0.tar.gz
scala-bb817a67b99253662f42f788555a3617310a52a0.tar.bz2
scala-bb817a67b99253662f42f788555a3617310a52a0.zip
Yet more code for scrutinizing the pattern matc...
Yet more code for scrutinizing the pattern matcher, and a couple minor duplication/dead-code cleanups seen elsewhere.
-rw-r--r--src/compiler/scala/tools/nsc/matching/MatchSupport.scala16
-rw-r--r--src/compiler/scala/tools/nsc/matching/MatrixAdditions.scala34
-rw-r--r--src/compiler/scala/tools/nsc/matching/ParallelMatching.scala1
-rw-r--r--src/compiler/scala/tools/nsc/matching/Patterns.scala46
-rw-r--r--src/compiler/scala/tools/nsc/matching/TransMatcher.scala8
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Types.scala13
-rw-r--r--src/compiler/scala/tools/nsc/transform/Erasure.scala3
7 files changed, 70 insertions, 51 deletions
diff --git a/src/compiler/scala/tools/nsc/matching/MatchSupport.scala b/src/compiler/scala/tools/nsc/matching/MatchSupport.scala
index 499523bc1a..927079bedc 100644
--- a/src/compiler/scala/tools/nsc/matching/MatchSupport.scala
+++ b/src/compiler/scala/tools/nsc/matching/MatchSupport.scala
@@ -111,6 +111,9 @@ trait MatchSupport extends ast.TreeDSL
object compactTreePrinter extends CompactTreePrinter
+ // def treeChildrenString(t: Tree): String =
+ // nodeToString(t)
+
def treeToCompactString(t: Tree): String = {
val buffer = new StringWriter()
val printer = compactTreePrinter.create(new PrintWriter(buffer))
@@ -181,10 +184,7 @@ trait MatchSupport extends ast.TreeDSL
override def printRaw(tree: Tree): Unit = {
// routing supercalls through this for debugging ease
- def s() = {
- // Console.println("toSuper: " + tree.getClass)
- super.printRaw(tree)
- }
+ def s() = super.printRaw(tree)
tree match {
// labels used for jumps - does not map to valid scala code
@@ -202,8 +202,6 @@ trait MatchSupport extends ast.TreeDSL
case _ => s()
}
- // case Select(Select(_, x), y) if x.toString == "this" =>
- // print(symName(tree, y))
// target.unary_! ==> !target
case Select(qualifier, name) =>
val n = symName(tree, name)
@@ -223,6 +221,12 @@ trait MatchSupport extends ast.TreeDSL
case _ => s()
}
+ // We get a lot of this stuff
+ case If( IsTrue(), x, _) => printRaw(x)
+ case If(IsFalse(), _, x) => printRaw(x)
+ case If(cond, IsFalse(), elsep) =>
+ printRow(List(cond, elsep), " !(", ") && (", ") ")
+
// If thenp or elsep has only one statement, it doesn't need more than one line.
case If(cond, thenp, elsep) =>
printRow(List(cond), "if (", "", ") ")
diff --git a/src/compiler/scala/tools/nsc/matching/MatrixAdditions.scala b/src/compiler/scala/tools/nsc/matching/MatrixAdditions.scala
index e542e1ab11..4a1a423b7f 100644
--- a/src/compiler/scala/tools/nsc/matching/MatrixAdditions.scala
+++ b/src/compiler/scala/tools/nsc/matching/MatrixAdditions.scala
@@ -20,6 +20,22 @@ trait MatrixAdditions extends ast.TreeDSL
import CODE._
import Debug._
+ // Extractors which can spot pure true/false expressions
+ // even through the haze of braces
+ abstract class SeeThroughBlocks[T] {
+ protected def unapplyImpl(x: Tree): T
+ def unapply(x: Tree): T = x match {
+ case Block(Nil, expr) => unapply(expr)
+ case _ => unapplyImpl(x)
+ }
+ }
+ object IsTrue extends SeeThroughBlocks[Boolean] {
+ protected def unapplyImpl(x: Tree): Boolean = x equalsStructure TRUE
+ }
+ object IsFalse extends SeeThroughBlocks[Boolean] {
+ protected def unapplyImpl(x: Tree): Boolean = x equalsStructure FALSE
+ }
+
/** The Squeezer, responsible for all the squeezing.
*/
private[matching] trait Squeezer {
@@ -28,10 +44,9 @@ trait MatrixAdditions extends ast.TreeDSL
def squeezedBlockPVs(pvs: List[PatternVar], exp: Tree): Tree =
squeezedBlock(pvs map (_.valDef), exp)
- def squeezedBlock(vds: List[Tree], exp: Tree): Tree = tracing("squeezed",
+ def squeezedBlock(vds: List[Tree], exp: Tree): Tree =
if (settings_squeeze) Block(Nil, squeezedBlock1(vds, exp))
else Block(vds, exp)
- )
private def squeezedBlock1(vds: List[Tree], exp: Tree): Tree = {
class RefTraverser(sym: Symbol) extends Traverser {
@@ -96,21 +111,6 @@ trait MatrixAdditions extends ast.TreeDSL
import self.context._
final def optimize(tree: Tree): Tree = {
- // Extractors which can spot pure true/false expressions
- // even through the haze of braces
- abstract class SeeThroughBlocks[T] {
- protected def unapplyImpl(x: Tree): T
- def unapply(x: Tree): T = x match {
- case Block(Nil, expr) => unapply(expr)
- case _ => unapplyImpl(x)
- }
- }
- object IsTrue extends SeeThroughBlocks[Boolean] {
- protected def unapplyImpl(x: Tree): Boolean = x equalsStructure TRUE
- }
- object IsFalse extends SeeThroughBlocks[Boolean] {
- protected def unapplyImpl(x: Tree): Boolean = x equalsStructure FALSE
- }
object lxtt extends Transformer {
override def transform(tree: Tree): Tree = tree match {
case blck @ Block(vdefs, ld @ LabelDef(name, params, body)) =>
diff --git a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
index 7d5850ac27..02e6afdb4e 100644
--- a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
+++ b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
@@ -27,7 +27,6 @@ trait ParallelMatching extends ast.TreeDSL
import global.{ typer => _, _ }
import definitions.{ AnyRefClass, IntClass, BooleanClass, getProductArgs, productProj }
- import treeInfo.{ isStar }
import CODE._
import Types._
import Debug._
diff --git a/src/compiler/scala/tools/nsc/matching/Patterns.scala b/src/compiler/scala/tools/nsc/matching/Patterns.scala
index 54733e2eea..184054bc04 100644
--- a/src/compiler/scala/tools/nsc/matching/Patterns.scala
+++ b/src/compiler/scala/tools/nsc/matching/Patterns.scala
@@ -49,7 +49,7 @@ trait Patterns extends ast.TreeDSL {
val tree = EmptyTree
override def irrefutableFor(tpe: Type) = true
override def isDefault = true
- override def toString() = "_"
+ override def description = "_"
}
// 8.1.2
@@ -63,7 +63,7 @@ trait Patterns extends ast.TreeDSL {
case ExtractorPattern(ua) if pv.sym.tpe <:< tpt.tpe => this rebindTo expr
case _ => this
}
- override def toString() = "%s: %s".format(Pattern(expr), tpt)
+ override def description = "%s: %s".format(Pattern(expr), tpt)
}
// 8.1.3
@@ -72,7 +72,7 @@ trait Patterns extends ast.TreeDSL {
def isSwitchable = cond(const.tag) { case ByteTag | ShortTag | IntTag | CharTag => true }
def intValue = const.intValue
- override def toString() = if (value == null) "null" else value.toString()
+ override def description = if (value == null) "null" else value.toString()
}
// 8.1.4 (a)
@@ -82,7 +82,7 @@ trait Patterns extends ast.TreeDSL {
override def sufficientType = Pattern(ident).equalsCheck
override def simplify(pv: PatternVar) = this.rebindToObjectCheck()
- override def toString() = "Id(%s)".format(name)
+ override def description = "Id(%s)".format(name)
}
// 8.1.4 (b)
case class ApplySelectPattern(tree: Apply) extends ApplyPattern with SelectPattern {
@@ -90,12 +90,12 @@ trait Patterns extends ast.TreeDSL {
override def sufficientType = mkSingletonFromQualifier
override def simplify(pv: PatternVar) = this.rebindToObjectCheck()
- override def toString() = "SelectApply(%s)".format(name)
+ override def description = "SelectApply(%s)".format(name)
}
// 8.1.4 (c)
case class StableIdPattern(tree: Select) extends SelectPattern {
def select = tree
- override def toString() = "StableId(%s)".format(pathSegments.mkString(" . "))
+ override def description = "StableId(%s)".format(pathSegments.mkString(" . "))
}
// 8.1.4 (d)
case class ObjectPattern(tree: Apply) extends ApplyPattern { // NamePattern?
@@ -103,7 +103,7 @@ trait Patterns extends ast.TreeDSL {
override def sufficientType = tpe.narrow
override def simplify(pv: PatternVar) = this.rebindToObjectCheck()
- override def toString() = "Object(%s)".format(fn)
+ override def description = "Object(%s)".format(fn)
}
// 8.1.4 (e)
case class SimpleIdPattern(tree: Ident) extends NamePattern {
@@ -122,7 +122,7 @@ trait Patterns extends ast.TreeDSL {
if (args.isEmpty) this rebindToEmpty tree.tpe
else this
- override def toString() = "Constructor(%s)".format(toPats(args).mkString(", "))
+ override def description = "Constructor(%s)".format(toPats(args).mkString(", "))
// XXX todo
// override def irrefutableFor(tpe: Type) = false
@@ -147,7 +147,7 @@ trait Patterns extends ast.TreeDSL {
if (pv.sym.tpe <:< arg.tpe) this
else this rebindTo uaTyped
- override def toString() = "Unapply(f: %s => %s)".format(necessaryType, fn.tpe.resultType)
+ override def description = "Unapply(f: %s => %s)".format(necessaryType, fn.tpe.resultType)
}
// 8.1.8 (unapplySeq calls)
@@ -181,7 +181,7 @@ trait Patterns extends ast.TreeDSL {
pv.sym setFlag Flags.TRANS_FLAG
this rebindTo elems.foldRight(gen.mkNil)(listFolder)
}
- override def toString() = "UnapplySeq(%s)".format(elems)
+ override def description = "UnapplySeq(%s)".format(elems)
}
// 8.1.8 (b) (literal ArrayValues)
@@ -193,7 +193,6 @@ trait Patterns extends ast.TreeDSL {
override def subpatternsForVars: List[Pattern] = elemPatterns
- def hasStar = elems.nonEmpty && (cond(lastPattern) { case _: StarPattern => true })
def nonStarLength = nonStarPatterns.length
def isAllDefaults = nonStarPatterns forall (_.isDefault)
@@ -244,7 +243,7 @@ trait Patterns extends ast.TreeDSL {
false
}
}
- override def toString() = "Sequence(%s)".format(elems)
+ override def description = "Sequence(%s)".format(elems)
}
// 8.1.8 (b)
@@ -271,7 +270,7 @@ trait Patterns extends ast.TreeDSL {
private lazy val Alternative(subtrees) = tree
private def alts = subtrees map Pattern.apply
// override def subpatterns(pmatch: PatternMatch) = subtrees map Pattern.apply
- override def toString() = "Alts(%s)".format(alts mkString " | ")
+ override def description = "Alts(%s)".format(alts mkString " | ")
}
// 8.1.11
@@ -482,6 +481,24 @@ trait Patterns extends ast.TreeDSL {
def isCaseClass = tpe.typeSymbol hasFlag Flags.CASE
def isObject = isSymValid && prefix.isStable // XXX not entire logic
+ def unadorn(x: Tree): Tree = x match {
+ case Typed(expr, _) => unadorn(expr)
+ case Bind(_, x) => unadorn(x)
+ case _ => x
+ }
+
+ private def isStar(x: Tree) = cond(unadorn(x)) { case Star(_) => true }
+ private def endsStar(xs: List[Tree]) = xs.nonEmpty && isStar(xs.last)
+
+ def isSequence = cond(unadorn(tree)) {
+ case Sequence(xs) => true
+ case ArrayValue(tpt, xs) => true
+ }
+ def hasStar = cond(unadorn(tree)) {
+ case Sequence(xs) if endsStar(xs) => true
+ case ArrayValue(_, xs) if endsStar(xs) => true
+ }
+
def setType(tpe: Type): this.type = {
tree setType tpe
this
@@ -503,9 +520,10 @@ trait Patterns extends ast.TreeDSL {
case _ => super.equals(other)
}
override def hashCode() = boundTree.hashCode()
+ def description = super.toString()
+ final override def toString() = "%s %s".format(description, isSequence)
}
-
/*** Extractors ***/
object UnapplyParamType {
diff --git a/src/compiler/scala/tools/nsc/matching/TransMatcher.scala b/src/compiler/scala/tools/nsc/matching/TransMatcher.scala
index 4244b13f6a..b47ebccfa9 100644
--- a/src/compiler/scala/tools/nsc/matching/TransMatcher.scala
+++ b/src/compiler/scala/tools/nsc/matching/TransMatcher.scala
@@ -58,7 +58,7 @@ trait TransMatcher extends ast.TreeDSL {
// For x match { ... we start with a single root
def singleMatch(): MatrixInit = {
val v = copyVar(selector, isChecked)
- tracing("root(s)", context.MatrixInit(List(v), cases, matchError(v.ident)))
+ context.MatrixInit(List(v), cases, matchError(v.ident))
}
// For (x, y, z) match { ... we start with multiple roots, called tpXX.
@@ -67,14 +67,14 @@ trait TransMatcher extends ast.TreeDSL {
val vs = args zip rootTypes map { case (arg, tpe) => copyVar(arg, isChecked, tpe, "tp") }
def merror = matchError(treeCopy.Apply(app, fn, vs map (_.ident)))
- tracing("root(s)", context.MatrixInit(vs, cases, merror))
+ context.MatrixInit(vs, cases, merror)
}
// sets up top level variables and algorithm input
- val matrixInit = selector match {
+ val matrixInit = tracing("matrixInit", selector match {
case app @ Apply(fn, _) if isTupleType(selector.tpe) && doApply(fn) => tupleMatch(app)
case _ => singleMatch()
- }
+ })
val matrix = new MatchMatrix(context) { lazy val data = matrixInit }
val rep = matrix.expansion // expands casedefs and assigns name
diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala
index 1c6c04b2bc..1765536d8d 100644
--- a/src/compiler/scala/tools/nsc/symtab/Types.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Types.scala
@@ -2706,10 +2706,13 @@ A type's typeSymbol should never be inspected directly.
eparams
}
+ // note: it's important to write the two tests in this order,
+ // as only typeParams forces the classfile to be read. See #400
+ private def isRawIfWithoutArgs(sym: Symbol) =
+ !sym.typeParams.isEmpty && sym.hasFlag(JAVA)
+
def isRaw(sym: Symbol, args: List[Type]) =
- !phase.erasedTypes && !sym.typeParams.isEmpty && sym.hasFlag(JAVA) && args.isEmpty
- // note: it's important to write the two first tests in this order,
- // as only typeParams forces the classfile to be read. See #400
+ !phase.erasedTypes && isRawIfWithoutArgs(sym) && args.isEmpty
/** Is type tp a ``raw type''? */
def isRawType(tp: Type) = tp match {
@@ -2727,9 +2730,7 @@ A type's typeSymbol should never be inspected directly.
*/
object rawToExistential extends TypeMap {
def apply(tp: Type): Type = tp match {
- case TypeRef(pre, sym, List()) if !sym.typeParams.isEmpty && sym.hasFlag(JAVA) =>
- // note: it's important to write the two tests in this order,
- // as only typeParams forces the classfile to be read. See #400
+ case TypeRef(pre, sym, List()) if isRawIfWithoutArgs(sym) =>
val eparams = typeParamsToExistentials(sym, sym.typeParams)
existentialAbstraction(eparams, TypeRef(pre, sym, eparams map (_.tpe)))
case _ =>
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala
index a5f764952f..43a743ea3b 100644
--- a/src/compiler/scala/tools/nsc/transform/Erasure.scala
+++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala
@@ -384,9 +384,6 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer with ast.
}
}
- private def isSeqClass(sym: Symbol) =
- (SeqClass isNonBottomSubClass sym) && (sym != ObjectClass)
-
/** The symbol which is called by a bridge;
* @pre phase > erasure
*/