summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDavid MacIver <david.maciver@gmail.com>2008-11-09 17:55:15 +0000
committerDavid MacIver <david.maciver@gmail.com>2008-11-09 17:55:15 +0000
commitcdbd7d9a019483ff94a479f1031592f721f2c44c (patch)
tree8c9fa1ced26e676acfa8258946907c448798cb0c /src
parent151a01cd3e166026eaaba5ec4de815266eeada6f (diff)
downloadscala-cdbd7d9a019483ff94a479f1031592f721f2c44c.tar.gz
scala-cdbd7d9a019483ff94a479f1031592f721f2c44c.tar.bz2
scala-cdbd7d9a019483ff94a479f1031592f721f2c44c.zip
General tidying from paul (mostly concerning us...
General tidying from paul (mostly concerning use of setType).
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/matching/MatchUtil.scala3
-rw-r--r--src/compiler/scala/tools/nsc/matching/ParallelMatching.scala125
-rw-r--r--src/compiler/scala/tools/nsc/matching/PatternNodes.scala29
3 files changed, 63 insertions, 94 deletions
diff --git a/src/compiler/scala/tools/nsc/matching/MatchUtil.scala b/src/compiler/scala/tools/nsc/matching/MatchUtil.scala
index f2d209233a..529e217cec 100644
--- a/src/compiler/scala/tools/nsc/matching/MatchUtil.scala
+++ b/src/compiler/scala/tools/nsc/matching/MatchUtil.scala
@@ -10,7 +10,8 @@ object MatchUtil
{
import collection.mutable.ListBuffer
- def impossible: Nothing = throw new RuntimeException("this never happens")
+ def impossible: Nothing = abort("this never happens")
+ def abort(msg: String): Nothing = throw new RuntimeException(msg)
object Implicits {
implicit def listPlusOps[T](xs: List[T]) = new ListPlus(xs)
diff --git a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
index cac426c67a..263e1b6ba4 100644
--- a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
+++ b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
@@ -58,8 +58,8 @@ trait ParallelMatching {
case _ => false;
}
- (isSameType(scrutinee.tpe.widen, definitions.IntClass.tpe) ||
- isSameType(scrutinee.tpe.widen, definitions.CharClass.tpe)) &&
+ ((scrutinee.tpe.widen =:= definitions.IntClass.tpe) ||
+ (scrutinee.tpe.widen =:= definitions.CharClass.tpe)) &&
column.init.forall(simpleSwitchCandidate) && {
val last = column.last;
// TODO: This needs to also allow the case that the last is a compatible
@@ -234,7 +234,7 @@ trait ParallelMatching {
class MixUnapply(val scrutinee: Symbol, val column: List[Tree], val rest: Rep)(implicit rep: RepFactory)
extends RuleApplication(rep) {
val (vs, unapp) = strip(column.head)
- lazy val ua @ UnApply(app @ Apply(fn, appargs), args) = unapp
+ lazy val ua @ UnApply(app @ Apply(fxn, appargs), args) = unapp
def newVarCapture(pos:Position,tpe:Type)(implicit theOwner:Symbol) = {
val v = newVar(pos,tpe)
@@ -246,19 +246,19 @@ trait ParallelMatching {
final def getTransition(implicit theOwner: Symbol): (Tree, List[Tree], Rep, Option[Rep]) = {
object sameUnapplyCall {
def unapply(t: Tree) = t match {
- case UnApply(Apply(fn1,_), differentArgs) if (fn.symbol == fn1.symbol) && fn.equalsStructure(fn1) =>
+ case UnApply(Apply(fn1,_), differentArgs) if (fxn.symbol == fn1.symbol) && fxn.equalsStructure(fn1) =>
Some(differentArgs)
case _ =>
None
}
}
val ures = newVarCapture(ua.pos, app.tpe)
- val rhs = Apply(fn, mkIdent(scrutinee) :: appargs.tail) setType ures.tpe
+ val rhs = Apply(fxn, mkIdent(scrutinee) :: appargs.tail) setType ures.tpe
val uacall = typedValDef(ures, rhs)
- val zipped = column.zip(rest.row)
- val nrowsOther = zipped.tail.flatMap { case (pat, r) =>
- strip2(pat) match { case sameUnapplyCall(_) => Nil ; case _ => List(r.insert(pat)) }
- }
+ val zipped = column zip rest.row
+ val nrowsOther = zipped.tail flatMap
+ { case (Strip2(sameUnapplyCall(_)), _) => Nil ; case (pat, r) => List(r.insert(pat)) }
+
val nrepFail =
if (nrowsOther.isEmpty) None
else Some(rep.make(scrutinee::rest.temp, nrowsOther))
@@ -267,8 +267,8 @@ trait ParallelMatching {
(uacall, vdefs, rep.make(ntemps ::: scrutinee :: rest.temp, nrows), nrepFail)
def mkNewRows(sameFilter: (List[Tree]) => List[Tree], defaultTrees: List[Tree]) =
- for ((pat, r) <- zipped) yield strip2(pat) match {
- case sameUnapplyCall(args) => r.insert2(sameFilter(args) ::: List(EmptyTree), r.subst.add(strip1(pat), scrutinee))
+ for ((pat @ Strip(vs, p), r) <- zipped) yield p match {
+ case sameUnapplyCall(args) => r.insert2(sameFilter(args) ::: List(EmptyTree), r.subst.add(vs, scrutinee))
case _ => r.insert(defaultTrees ::: List(pat))
}
@@ -292,7 +292,7 @@ trait ParallelMatching {
for ((vtpe, i) <- ts.zip((1 to ts.size).toList)) yield {
val vchild = newVarCapture(ua.pos, vtpe)
val accSym = definitions.productProj(uresGet, i)
- val rhs = typer.typed(Apply(Select(mkIdent(uresGet), accSym), Nil))
+ val rhs = typer.typed(Code.fn(mkIdent(uresGet), accSym))
(typedValDef(vchild, rhs), vchild)
})
@@ -350,12 +350,7 @@ trait ParallelMatching {
def getTransition(implicit theOwner: Symbol): (Tree => Tree => Tree, Rep, Rep) = {
assert(isSubType(scrutinee.tpe, column.head.tpe), "problem "+scrutinee.tpe+" not <: "+column.head.tpe)
- val treeAsSeq =
- if (!isSubType(scrutinee.tpe, column.head.tpe))
- typer.typed(gen.mkAsInstanceOf(mkIdent(scrutinee), column.head.tpe, true))
- else
- mkIdent(scrutinee)
-
+ val treeAsSeq = mkIdent(scrutinee) // scrutinee.tpe <:< column.head.tpe confirmed by assertion
val av @ ArrayValue(_, xs) = column.head
val ys = if (isRightIgnoring(av)) xs.init else xs
val vs = ys map(y => newVar(strip2(y).pos, elementType))
@@ -398,7 +393,7 @@ trait ParallelMatching {
// in principle, we could optimize more, but variable binding gets complicated (@todo use finite state methods instead)
override def getSubPatterns(minlen:Int, x:Tree) = x match {
case av @ ArrayValue(_,xs) if (!isRightIgnoring(av) && xs.length == minlen) => // Seq(p1,...,pN)
- Some(xs ::: gen.mkAttributedRef(definitions.NilModule) :: EmptyTree :: Nil)
+ Some(xs ::: gen.mkNil :: EmptyTree :: Nil)
case av @ ArrayValue(_,xs) if ( isRightIgnoring(av) && xs.length-1 == minlen) => // Seq(p1,...,pN,_*)
Some( removeStar(xs) ::: EmptyTree :: Nil)
case av @ ArrayValue(_,xs) if ( isRightIgnoring(av) && xs.length-1 < minlen) => // Seq(p1..,pJ,_*) J < N
@@ -422,7 +417,6 @@ trait ParallelMatching {
class MixEquals(val scrutinee: Symbol, val column: List[Tree], val rest: Rep)(implicit rep: RepFactory) extends RuleApplication(rep) {
/** condition (to be used in IF), success and failure Rep */
final def getTransition(implicit theOwner: Symbol): (Tree, Rep, Symbol, Rep) = {
- val nmatrix = rest
val vlue = (column.head.tpe: @unchecked) match {
case TypeRef(_,_,List(SingleType(pre,sym))) => gen.mkAttributedRef(pre,sym)
case TypeRef(_,_,List(PseudoType(o))) => o.duplicate
@@ -438,7 +432,7 @@ trait ParallelMatching {
val nsucc = rep.make(scrutinee :: rest.temp, nsuccRow)
val nfail = repWithoutHead(column, rest)
- (typer.typed(Equals(mkIdent(scrutinee) setType scrutinee.tpe, vlue)), nsucc, fLabel, nfail)
+ (typer.typed(Equals(mkIdent(scrutinee), vlue)), nsucc, fLabel, nfail)
}
final def tree(implicit theOwner: Symbol, failTree: Tree) = {
@@ -446,20 +440,14 @@ trait ParallelMatching {
val cond2 = typer.typed( rep.handleOuter(cond) )
val fail = typer.typed( repToTree(frep) )
fLabel setInfo MethodType(Nil, fail.tpe)
- val succ = repToTree(srep)
- typer.typed( If(cond2, succ, LabelDef(fLabel, Nil, fail)) )
+
+ typer.typed( If(cond2, repToTree(srep), LabelDef(fLabel, Nil, fail)) )
}
}
/** mixture rule for type tests
**/
class MixTypes(val scrutinee: Symbol, val column: List[Tree], val rest: Rep)(implicit rep: RepFactory) extends RuleApplication(rep) {
- // TODO: this flag is never examined
- val isExhaustive = !scrutinee.tpe.typeSymbol.hasFlag(Flags.SEALED) || {
- val tpes = column.map(x => x.tpe.typeSymbol)
- scrutinee.tpe.typeSymbol.children.forall(sym => tpes.contains(sym))
- }
-
private val headPatternType = strip2(column.head) match {
case p @ (_:Ident | _:Select) => singleType(p.symbol.tpe.prefix, p.symbol) //should be singleton object
case __UnApply(_,argtpe,_) => argtpe
@@ -573,11 +561,7 @@ trait ParallelMatching {
final def tree(implicit theOwner: Symbol, failTree: Tree): Tree = {
val (casted, srep, frep) = this.getTransition
- val condUntyped = condition(casted.tpe, this.scrutinee)
- var cond = rep.handleOuter(typer.typed { condUntyped })
- if (needsOuterTest(casted.tpe, this.scrutinee.tpe, theOwner)) { // @todo merge into def condition
- cond = addOuterCondition(cond, casted.tpe, mkIdent(this.scrutinee), rep.handleOuter)
- }
+ val cond = condition(casted.tpe, this.scrutinee)
val succ = repToTree(srep)
val fail = frep.map(repToTree) getOrElse failTree
@@ -586,7 +570,7 @@ trait ParallelMatching {
val caseTemps = (if (!srep.temp.isEmpty && srep.temp.head == casted) srep.temp.tail else srep.temp).zip(cfa)
var vdefs = for ((tmp, accessorMethod) <- caseTemps) yield {
- val untypedAccess = Apply(Select(mkIdent(casted), accessorMethod), Nil)
+ val untypedAccess = Code.fn(mkIdent(casted), accessorMethod)
val typedAccess = typer.typed(untypedAccess)
typedValDef(tmp, typedAccess)
}
@@ -737,7 +721,7 @@ trait ParallelMatching {
(strippedPat: @unchecked) match {
case p @ Alternative(ps) =>
DBG("Alternative") ; opat
- case typat @ Typed(p, tpt) if strip2(p).isInstanceOf[UnApply]=>
+ case typat @ Typed(p @ Strip2(_: UnApply), tpt) =>
DBG("Typed")
if (temp(j).tpe <:< tpt.tpe) makeBind(vs, p) else opat
@@ -746,15 +730,12 @@ trait ParallelMatching {
case o @ Ident(n) => // n != nme.WILDCARD
DBG("Ident")
val tpe = equalsCheck(o)
- val p = Ident(nme.WILDCARD) setType tpe
- val q = Typed(p, TypeTree(tpe)) setType tpe
- makeBind(vs, q) setType tpe
+ makeBind(vs, Typed(mk_(tpe), TypeTree(tpe)) setType tpe)
case o @ Select(stor,_) =>
DBG("Select")
val stpe = equalsCheck(o)
- val p = Ident(nme.WILDCARD) setType stpe
- makeBind(vs, Typed(p, TypeTree(stpe)) setType stpe) setType stpe
+ makeBind(vs, Typed(mk_(stpe), TypeTree(stpe)) setType stpe)
case UnApply(Apply(TypeApply(sel @ Select(stor, nme.unapplySeq), List(tptArg)),_),ArrayValue(_,xs)::Nil)
if (stor.symbol eq definitions.ListModule) =>
@@ -773,7 +754,7 @@ trait ParallelMatching {
case ua @ UnApply(Apply(fn, _), _) =>
DBG("Unapply(Apply())")
val MethodType(List(argtpe, _*), _) = fn.tpe
- val npat = if (temp(j).tpe <:< argtpe) ua else Typed(ua, TypeTree(argtpe)).setType(argtpe)
+ val npat = if (temp(j).tpe <:< argtpe) ua else Typed(ua, TypeTree(argtpe)) setType argtpe
makeBind(vs, npat) setType argtpe
case o @ Apply(fn, Nil) if !isCaseClass(o.tpe) || /*see t301*/ !Apply_Value.unapply(o).isEmpty =>
@@ -789,8 +770,7 @@ trait ParallelMatching {
case o: Ident => equalsCheck(o)
}
val ttst = typeRef(NoPrefix, definitions.EqualsPatternClass, List(stpe))
- val p = Ident(nme.WILDCARD) setType ttst
- makeBind(vs, Typed(p, TypeTree(stpe)) setType ttst)
+ makeBind(vs, Typed(mk_(ttst), TypeTree(stpe)) setType ttst)
case Apply_Value(pre, sym) =>
DBG("Apply_Value")
@@ -824,7 +804,7 @@ trait ParallelMatching {
val Row(opats, subst, g, bx) = xx
val indexOfAlternative = opats.findIndexOf(isAlternative)
if (indexOfAlternative != -1) unchanged = false
- val pats: List[Tree] = opats.zipWithIndex.map { case (opat, j) => classifyPat(opat, j) }
+ val pats: List[Tree] = List.map2(opats, opats.indices)(classifyPat)
if (indexOfAlternative == -1) List(xx.replace(pats))
else {
@@ -833,7 +813,6 @@ trait ParallelMatching {
}
}
- // if (unchanged) RepImpl(temp, row).init
if (unchanged) Rep(temp, row).init else make(temp, row) // recursive call
}
}
@@ -980,51 +959,45 @@ trait ParallelMatching {
/** returns the condition in "if (cond) k1 else k2"
*/
- final def condition(tpe: Type, scrut: Symbol)(implicit typer : Typer): Tree = {
+ final def condition(tpe: Type, scrut: Symbol)(implicit typer: Typer, theOwner: Symbol, rep: RepFactory): Tree = {
assert(scrut ne NoSymbol)
- condition(tpe, mkIdent(scrut))
+ val cond = rep.handleOuter(typer.typed(condition(tpe, mkIdent(scrut))))
+
+ if (!needsOuterTest(tpe, scrut.tpe, theOwner)) cond
+ else addOuterCondition(cond, tpe, mkIdent(scrut), rep.handleOuter)
}
final def condition(tpe: Type, scrutineeTree: Tree)(implicit typer : Typer): Tree = {
assert((tpe ne NoType) && (scrutineeTree.tpe ne NoType))
+ lazy val equalsRef = Equals(gen.mkAttributedRef(tpe.termSymbol), scrutineeTree)
+ lazy val isInst = gen.mkIsInstanceOf(scrutineeTree, tpe)
+ def isAnyRef(t: Type) = t <:< definitions.AnyRefClass.tpe
tpe match {
case _: SingletonType if !tpe.isInstanceOf[ConstantType] =>
- lazy val equalsRef = Equals(gen.mkAttributedRef(tpe.termSymbol), scrutineeTree)
- if (tpe.termSymbol.isModule) equalsRef // object
- else if (tpe.prefix ne NoPrefix) typer.typed(gen.mkIsInstanceOf(scrutineeTree, tpe))
- else typer.typed(equalsRef)
-
+ if (tpe.termSymbol.isModule) equalsRef // object
+ else if (tpe.prefix ne NoPrefix) typer.typed(isInst)
+ else typer.typed(equalsRef)
case ct: ConstantType => ct.value match { // constant
- case v @ Constant(null) if scrutineeTree.tpe <:< definitions.AnyRefClass.tpe => Eq(scrutineeTree, Literal(v))
- case v => Equals(scrutineeTree, Literal(v))
+ case v @ Constant(null) if isAnyRef(scrutineeTree.tpe) => Eq(scrutineeTree, Literal(v))
+ case v => Equals(scrutineeTree, Literal(v))
}
- case _ if scrutineeTree.tpe <:< tpe && tpe <:< definitions.AnyRefClass.tpe =>
- NotNull(scrutineeTree)
- case _ =>
- gen.mkIsInstanceOf(scrutineeTree, tpe)
+ case _ if scrutineeTree.tpe <:< tpe && isAnyRef(tpe) => NotNull(scrutineeTree)
+ case _ => gen.mkIsInstanceOf(scrutineeTree, tpe)
}
}
/** adds a test comparing the dynamic outer to the static outer */
final def addOuterCondition(cond:Tree, tpe2test: Type, scrutinee: Tree, handleOuter: Tree=>Tree) = {
- val TypeRef(prefix,_,_) = tpe2test
- assert(prefix ne NoPrefix)
- var theRef = prefix match {
- case ThisType(clazz) => gen.mkAttributedThis(clazz)
- case _ => gen.mkAttributedRef(prefix.prefix, prefix.termSymbol)
+ val theRef = handleOuter(tpe2test match {
+ case TypeRef(NoPrefix, _, _) => abort("assertion failed: NoPrefix")
+ case TypeRef(ThisType(clazz), _, _) => gen.mkAttributedThis(clazz)
+ case TypeRef(prefix, _, _) => gen.mkAttributedRef(prefix.prefix, prefix.termSymbol)
+ })
+
+ outerAccessor(tpe2test.typeSymbol) match {
+ case NoSymbol => if (settings.debug.value) cunit.warning(scrutinee.pos, "no outer acc for "+tpe2test.typeSymbol) ; cond
+ case outerAcc => And(cond, Eq(Code.fn(gen.mkAsInstanceOf(scrutinee, tpe2test, true), outerAcc), theRef))
}
- // needs explicitouter treatment
- theRef = handleOuter(theRef)
-
- val outerAcc = outerAccessor(tpe2test.typeSymbol)
- if (outerAcc == NoSymbol) {
- if (settings.debug.value) cunit.warning(scrutinee.pos, "no outer acc for "+tpe2test.typeSymbol)
- cond
- } else
- And(cond,
- Eq(Apply(Select(
- gen.mkAsInstanceOf(scrutinee, tpe2test, true), outerAcc), Nil), theRef))
}
-
}
diff --git a/src/compiler/scala/tools/nsc/matching/PatternNodes.scala b/src/compiler/scala/tools/nsc/matching/PatternNodes.scala
index f7dc879c5d..6b78770af0 100644
--- a/src/compiler/scala/tools/nsc/matching/PatternNodes.scala
+++ b/src/compiler/scala/tools/nsc/matching/PatternNodes.scala
@@ -22,10 +22,8 @@ trait PatternNodes { self: transform.ExplicitOuter =>
if (vs eq Nil) pat else Bind(vs.head, makeBind(vs.tail, pat)) setType pat.tpe
def normalizedListPattern(pats:List[Tree], tptArg:Type): Tree = pats match {
- case Nil => gen.mkAttributedRef(definitions.NilModule)
- case (sp @ Strip(_, _: Star)) :: xs => makeBind(definedVars(sp), Ident(nme.WILDCARD) setType sp.tpe)
- // case sp::xs if strip2(sp).isInstanceOf[Star] =>
- // makeBind(definedVars(sp), Ident(nme.WILDCARD) setType sp.tpe)
+ case Nil => gen.mkNil
+ case (sp @ Strip(_, _: Star)) :: xs => makeBind(definedVars(sp), mk_(sp.tpe))
case x::xs =>
var resType: Type = null;
val consType: Type = definitions.ConsClass.primaryConstructor.tpe match {
@@ -35,7 +33,7 @@ trait PatternNodes { self: transform.ExplicitOuter =>
MethodType(List(tptArg, listType), resType)
}
- Apply(TypeTree(consType),List(x,normalizedListPattern(xs,tptArg))).setType(resType)
+ Apply(TypeTree(consType), List(x,normalizedListPattern(xs,tptArg))) setType resType
}
object Apply_Value {
@@ -50,11 +48,11 @@ trait PatternNodes { self: transform.ExplicitOuter =>
}
object __UnApply {
- def unapply(x:Tree) = strip(x) match {
- case (vs, UnApply(Apply(fn, _), args)) =>
+ def unapply(x: Tree) = x match {
+ case Strip(vs, UnApply(Apply(fn, _), args)) =>
val argtpe = fn.tpe.asInstanceOf[MethodType].paramTypes.head
- Some(Tuple3(vs,argtpe,args))
- case _ => None
+ Some((vs, argtpe, args))
+ case _ => None
}
}
@@ -64,9 +62,8 @@ trait PatternNodes { self: transform.ExplicitOuter =>
* test, it is returned as is.
*/
def patternType_wrtEquals(pattpe:Type) = pattpe match {
- case TypeRef(_,sym,arg::Nil) if sym eq definitions.EqualsPatternClass =>
- arg
- case x => x
+ case TypeRef(_, sym, arg::Nil) if sym eq definitions.EqualsPatternClass => arg
+ case _ => pattpe
}
/** returns if pattern can be considered a no-op test ??for expected type?? */
@@ -85,15 +82,13 @@ trait PatternNodes { self: transform.ExplicitOuter =>
*/
final def strip(x: Tree): (Set[Symbol], Tree) = x match {
case b @ Bind(_,pat) => val (vs, p) = strip(pat); (vs + b.symbol, p)
- case z => (emptySymbolSet, z)
+ case _ => (emptySymbolSet, x)
}
-
final def strip1(x: Tree): Set[Symbol] = strip(x)._1
final def strip2(x: Tree): Tree = strip(x)._2;
- object Strip {
- def unapply(x: Tree): Option[(Set[Symbol], Tree)] = Some(strip(x))
- }
+ object Strip { def unapply(x: Tree): Option[(Set[Symbol], Tree)] = Some(strip(x)) }
+ object Strip2 { def unapply(x: Tree): Option[Tree] = Some(strip2(x)) }
final def isCaseClass(tpe: Type): Boolean =
tpe.typeSymbol hasFlag Flags.CASE