summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2009-10-11 00:32:19 +0000
committerPaul Phillips <paulp@improving.org>2009-10-11 00:32:19 +0000
commit8a45a5570ed0f091f3501fbfcc4c7dcb9f1c6a99 (patch)
treea504dcd76032307d23b187fe73e94c3ed98a0275 /src/compiler
parent1c4ad55d6f4d1d7ef53b1cd1253f877021472fc4 (diff)
downloadscala-8a45a5570ed0f091f3501fbfcc4c7dcb9f1c6a99.tar.gz
scala-8a45a5570ed0f091f3501fbfcc4c7dcb9f1c6a99.tar.bz2
scala-8a45a5570ed0f091f3501fbfcc4c7dcb9f1c6a99.zip
Improving tracing output, and more code organiz...
Improving tracing output, and more code organization to hide the uninteresting bits.
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/scala/tools/nsc/matching/MatchSupport.scala113
-rw-r--r--src/compiler/scala/tools/nsc/matching/Matrix.scala11
-rw-r--r--src/compiler/scala/tools/nsc/matching/ParallelMatching.scala40
-rw-r--r--src/compiler/scala/tools/nsc/matching/PatternBindings.scala4
-rw-r--r--src/compiler/scala/tools/nsc/matching/Patterns.scala38
-rw-r--r--src/compiler/scala/tools/nsc/matching/TransMatcher.scala104
-rw-r--r--src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala26
7 files changed, 185 insertions, 151 deletions
diff --git a/src/compiler/scala/tools/nsc/matching/MatchSupport.scala b/src/compiler/scala/tools/nsc/matching/MatchSupport.scala
index 8ae98d30a4..a768f675d5 100644
--- a/src/compiler/scala/tools/nsc/matching/MatchSupport.scala
+++ b/src/compiler/scala/tools/nsc/matching/MatchSupport.scala
@@ -7,6 +7,8 @@ package scala.tools.nsc
package matching
import transform.ExplicitOuter
+import ast.{ TreePrinters, Trees }
+import java.io.{ StringWriter, PrintWriter }
/** Ancillary bits of ParallelMatching which are better off
* out of the way.
@@ -73,10 +75,12 @@ trait MatchSupport extends ast.TreeDSL
// pretty print for debugging
def pp(x: Any): String = pp(x, false)
def pp(x: Any, newlines: Boolean): String = {
- def clean(s: String): String = s.replaceAll("""java\.lang\.""", "")
+ def clean(s: String): String =
+ s . replaceAll("""java\.lang\.""", "")
+ . replaceAll("""\$iw\.""", "")
val elems: List[Any] = x match {
- case x: String => return clean(x)
+ case x: String => return x
case xs: List[_] => xs
case x: Tuple2[_,_] => return pp(x._1) + " -> " + pp(x._2)
case x => return pp(x.toString)
@@ -88,7 +92,7 @@ trait MatchSupport extends ast.TreeDSL
else xs2.mkString("(", ", ", ")")
}
- pplist(elems)
+ clean(pplist(elems))
}
def ifDebug(body: => Unit): Unit = { if (settings.debug.value) body }
@@ -139,5 +143,106 @@ trait MatchSupport extends ast.TreeDSL
/** Drops the 'i'th element of a list.
*/
- def dropIndex[T](xs: List[T], n: Int) = (xs take n) ::: (xs drop (n + 1))
+ def dropIndex[T](xs: List[T], n: Int) = {
+ val (l1, l2) = xs splitAt n
+ l1 ::: (l2 drop 1)
+ }
+
+ /** Extract the nth element of a list and return it and the remainder.
+ */
+ def extractIndex[T](xs: List[T], n: Int): (T, List[T]) =
+ (xs(n), dropIndex(xs, n))
+
+ /** A tree printer which is stingier about vertical whitespace and unnecessary
+ * punctuation than the standard one.
+ */
+
+ // lazy val compactTreePrinter = compactTreePrinters.create()
+
+ class CompactTreePrinter extends {
+ val trees: global.type = global
+ } with TreePrinters {
+ import trees._
+
+ override def create(writer: PrintWriter): TreePrinter = new TreePrinter(writer) {
+ // drill down through Blocks and pull out the real statements.
+ def allStatements(t: Tree): List[Tree] = t match {
+ case Block(stmts, expr) => (stmts flatMap allStatements) ::: List(expr)
+ case _ => List(t)
+ }
+
+ override def printRaw(tree: Tree): Unit = {
+ // routing supercalls through this for debugging ease
+ def s() = {
+ // Console.println("toSuper: " + tree.getClass)
+ super.printRaw(tree)
+ }
+
+ tree match {
+ // labels used for jumps - does not map to valid scala code
+ case LabelDef(name, params, rhs) =>
+ print("labeldef %s(%s) = ".format(name, params mkString ","))
+ printRaw(rhs)
+
+ // target.method(arg) ==> target method arg
+ case Apply(Select(target, method), List(arg)) =>
+ (target, arg) match {
+ case (_: Ident, _: Literal | _: Ident) =>
+ printRaw(target)
+ print(" %s " format symName(tree, method))
+ printRaw(arg)
+ 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)
+ if (n startsWith "unary_") {
+ print(n drop 6)
+ print(qualifier)
+ }
+ else s()
+
+ // target.toString() ==> target.toString
+ case Apply(fn, Nil) => printRaw(fn)
+
+ // if a Block only continues one actual statement, just print it.
+ case Block(stats, expr) =>
+ allStatements(tree) match {
+ case List(x) => printRow(List(x), "", ";", "")
+ case _ => s()
+ }
+
+ // 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 (", "", ") ")
+
+ def ifIndented(x: Tree) = {
+ indent ; println ; printRaw(x) ; undent
+ }
+
+ indent ; println ;
+ allStatements(thenp) match {
+ case List(x: If) => ifIndented(x)
+ case List(x) => printRaw(x)
+ case _ => printRaw(thenp)
+ }
+ undent ; println ;
+ val elseStmts = allStatements(elsep)
+ if (!elseStmts.isEmpty) {
+ print("else")
+ indent ; println
+ elseStmts match {
+ case List(x) => printRaw(x)
+ case xs => printRaw(elsep)
+ }
+ undent ; println
+ }
+ case _ => s()
+ }
+ }
+ }
+ }
}
diff --git a/src/compiler/scala/tools/nsc/matching/Matrix.scala b/src/compiler/scala/tools/nsc/matching/Matrix.scala
index 631f517ab7..6d9f6a099b 100644
--- a/src/compiler/scala/tools/nsc/matching/Matrix.scala
+++ b/src/compiler/scala/tools/nsc/matching/Matrix.scala
@@ -99,6 +99,8 @@ trait Matrix extends MatrixAdditions {
class PatternVar(val lhs: Symbol, val rhs: Tree) {
lazy val ident = ID(lhs)
lazy val valDef = typedValDef(lhs, rhs)
+
+ override def toString() = "%s: %s = %s".format(lhs, lhs.info, rhs)
}
/** Given a tree, creates a new synthetic variable of the same type
@@ -114,7 +116,7 @@ trait Matrix extends MatrixAdditions {
val name = newName(root.pos, label)
val sym = newVar(root.pos, tpe, flags(checked), name)
- new PatternVar(sym, root)
+ tracing("copy", new PatternVar(sym, root))
}
/** The rhs is expressed as a function of the lhs. */
@@ -122,7 +124,7 @@ trait Matrix extends MatrixAdditions {
val lhs = newVar(owner.pos, tpe, flags(checked))
val rhs = f(lhs)
- new PatternVar(lhs, rhs)
+ tracing("create", new PatternVar(lhs, rhs))
}
private def newVar(
@@ -133,10 +135,7 @@ trait Matrix extends MatrixAdditions {
{
val n: Name = if (name == null) newName(pos, "temp") else name
// careful: pos has special meaning
- val res = owner.newVariable(pos, n) setInfo tpe setFlag (0L /: flags)(_|_)
-
- traceCategory("newVar", "%s: %s", res, tpe)
- res
+ owner.newVariable(pos, n) setInfo tpe setFlag (0L /: flags)(_|_)
}
def typedValDef(x: Symbol, rhs: Tree) =
diff --git a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
index 54ad0354da..801bdd3d19 100644
--- a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
+++ b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala
@@ -34,7 +34,6 @@ trait ParallelMatching extends ast.TreeDSL
import Flags.{ TRANS_FLAG }
/** Transition **/
- def isRightIgnoring(t: Tree) = cond(unbind(t)) { case ArrayValue(_, xs) if !xs.isEmpty => isStar(xs.last) }
def toPats(xs: List[Tree]): List[Pattern] = xs map Pattern.apply
/** The umbrella matrix class. **/
@@ -72,6 +71,19 @@ trait ParallelMatching extends ast.TreeDSL
else target.getLabelBody(idents, patternValDefs)
}
+ // make(tvars, rows)
+ // make(scrut.sym :: rest.tvars, xs).toTree
+ // make(rest.tvars, newRows ::: defaultRows)
+ // make(r.tvars, r.rows map (x => x rebind bindVars(tag, x.subst)))
+ // make(rest.tvars, defaultRows).toTree
+ // make(ntemps ::: scrut.sym :: rest.tvars, rows).toTree
+ // make(List(vs map (_.lhs), symList, rest.tvars).flatten, nrows.flatten)
+ // make(scrut.sym :: rest.tvars, frows.flatten).toTree
+ // make(scrut.sym :: rest.tvars, rows).toTree
+ // make(subtestVars ::: casted.accessorVars ::: rest.tvars, newRows)
+ // make(tvars, rows.tail)
+ // make(_tvars, _rows)
+
/** the injection here handles alternatives and unapply type tests */
final def make(tvars: List[Symbol], row1: List[Row]): Rep = {
def classifyPat(opat: Pattern, j: Int): Pattern = opat simplify tvars(j)
@@ -450,7 +462,7 @@ trait ParallelMatching extends ast.TreeDSL
case (false, false) => toPats(xs) ::: List(NoPattern)
})
}
- else if (pivot.hasStar && isRightIgnoring(av) && xs.length-1 < pivotLen)
+ else if (pivot.hasStar && sp.hasStar && xs.length-1 < pivotLen)
Some(emptyPatterns(pivotLen + 1) ::: List(x))
else
defaults // XXX
@@ -574,7 +586,7 @@ trait ParallelMatching extends ast.TreeDSL
(pattern match {
case Pattern(LIT(null), _) if !(p =:= s) => (None, None, pass) // (1)
case x if isObjectTest => (NoPattern, dummy, None) // (2)
- case Pattern(Typed(pp @ Pattern(_: UnApply, _), _), _) if sMatchesP => (Pattern(pp), dummy, None) // (3)
+ // case Pattern(Typed(pp @ Pattern(_: UnApply, _), _), _) if sMatchesP => (Pattern(pp), dummy, None) // (3)
case Pattern(Typed(pp, _), _) if sMatchesP => (alts(Pattern(pp), pattern), dummy, None) // (4)
case Pattern(_: UnApply, _) => (NoPattern, dummy, pass)
case x if !x.isDefault && sMatchesP => (alts(NoPattern, pattern), subs, None)
@@ -649,6 +661,12 @@ trait ParallelMatching extends ast.TreeDSL
/** Drops the 'i'th pattern */
def drop(i: Int) = copy(pats = dropIndex(pats, i))
+ /** Extracts the nth pattern. */
+ def extractColumn(i: Int) = {
+ val (x, xs) = extractIndex(pats, i)
+ (x, copy(pats = xs))
+ }
+
/** Replaces the 'i'th pattern with the argument. */
def replaceAt(i: Int, p: Pattern) = {
val newps = (pats take i) ::: p :: (pats drop (i + 1))
@@ -773,16 +791,18 @@ trait ParallelMatching extends ast.TreeDSL
/** Cut out the column containing the non-default pattern. */
class Cut(index: Int) {
/** The first two separate out the 'i'th pattern in each row from the remainder. */
- private val _column = rows map (_ pats index)
- private val _rows = rows map (_ drop index)
+ private val (_column, _rows) =
+ List.unzip(rows map (_ extractColumn index))
/** Now the 'i'th tvar is separated out and used as a new Scrutinee. */
- private val _sym = tvars(index)
- private val _tvars = dropIndex(tvars, index)
- private val _scrut = new Scrutinee(_sym)
+ private val (_sym, _tvars) =
+ extractIndex(tvars, index)
+
+ /** The non-default pattern (others.head) replaces the column head. */
+ private val (_ncol, _nrep) =
+ (others.head :: _column.tail, make(_tvars, _rows))
- /** The first non-default pattern (others.head) takes the place of _column's head. */
- def mix = MixtureRule(_scrut, others.head :: _column.tail, make(_tvars, _rows))
+ def mix = MixtureRule(new Scrutinee(_sym), _ncol, _nrep)
}
/** Converts this to a tree - recursively acquires subreps. */
diff --git a/src/compiler/scala/tools/nsc/matching/PatternBindings.scala b/src/compiler/scala/tools/nsc/matching/PatternBindings.scala
index de622b91a2..6c44cde880 100644
--- a/src/compiler/scala/tools/nsc/matching/PatternBindings.scala
+++ b/src/compiler/scala/tools/nsc/matching/PatternBindings.scala
@@ -134,7 +134,9 @@ trait PatternBindings extends ast.TreeDSL
}
class Bindings(private val vlist: List[Binding]) extends Function1[Symbol, Option[Ident]] {
- traceCategory("Bindings", this.toString)
+ if (!vlist.isEmpty)
+ traceCategory("Bindings", this.toString)
+
def vmap(v: Symbol): Option[Binding] = vlist find (_.pvar eq v)
// filters the given list down to those defined in these bindings
diff --git a/src/compiler/scala/tools/nsc/matching/Patterns.scala b/src/compiler/scala/tools/nsc/matching/Patterns.scala
index 647d6c92d8..75b13c2d32 100644
--- a/src/compiler/scala/tools/nsc/matching/Patterns.scala
+++ b/src/compiler/scala/tools/nsc/matching/Patterns.scala
@@ -187,17 +187,17 @@ trait Patterns extends ast.TreeDSL {
lazy val ArrayValue(elemtpt, elems) = tree
lazy val elemPatterns = toPats(elems)
lazy val nonStarPatterns = if (hasStar) elemPatterns.init else elemPatterns
- private def starPattern = elemPatterns.last
+ private def lastPattern = elemPatterns.last
override def subpatternsForVars: List[Pattern] = elemPatterns
- def hasStar = isRightIgnoring(tree)
+ def hasStar = elems.nonEmpty && (cond(lastPattern) { case _: StarPattern => true })
def nonStarLength = nonStarPatterns.length
def isAllDefaults = nonStarPatterns forall (_.isDefault)
def rebindStar(seqType: Type): List[Pattern] = {
require(hasStar)
- nonStarPatterns ::: List(starPattern rebindTo WILD(seqType))
+ nonStarPatterns ::: List(lastPattern rebindTo WILD(seqType))
}
// optimization to avoid trying to match if length makes it impossible
@@ -503,20 +503,20 @@ trait Patterns extends ast.TreeDSL {
}
}
- object SeqStarSubPatterns {
- def removeStar(xs: List[Tree], seqType: Type): List[Pattern] = {
- val ps = toPats(xs)
- ps.init ::: List(ps.last rebindToType seqType)
- }
-
- def unapply(x: Pattern)(implicit min: Int, seqType: Type): Option[List[Pattern]] = x.tree match {
- case av @ ArrayValue(_, xs) =>
- if (!isRightIgnoring(av) && xs.length == min) Some(toPats(xs ::: List(gen.mkNil, EmptyTree))) // Seq(p1,...,pN)
- else if ( isRightIgnoring(av) && xs.length-1 == min) Some(removeStar(xs, seqType) ::: List(NoPattern)) // Seq(p1,...,pN,_*)
- else if ( isRightIgnoring(av) && xs.length-1 < min) Some(emptyPatterns(min + 1) ::: List(x)) // Seq(p1..,pJ,_*) J < N
- else None
- case _ =>
- if (x.isDefault) Some(emptyPatterns(min + 1 + 1)) else None
- }
- }
+ // object SeqStarSubPatterns {
+ // def removeStar(xs: List[Tree], seqType: Type): List[Pattern] = {
+ // val ps = toPats(xs)
+ // ps.init ::: List(ps.last rebindToType seqType)
+ // }
+ //
+ // def unapply(x: Pattern)(implicit min: Int, seqType: Type): Option[List[Pattern]] = x.tree match {
+ // case av @ ArrayValue(_, xs) =>
+ // if (!isRightIgnoring(av) && xs.length == min) Some(toPats(xs ::: List(gen.mkNil, EmptyTree))) // Seq(p1,...,pN)
+ // else if ( isRightIgnoring(av) && xs.length-1 == min) Some(removeStar(xs, seqType) ::: List(NoPattern)) // Seq(p1,...,pN,_*)
+ // else if ( isRightIgnoring(av) && xs.length-1 < min) Some(emptyPatterns(min + 1) ::: List(x)) // Seq(p1..,pJ,_*) J < N
+ // else None
+ // case _ =>
+ // if (x.isDefault) Some(emptyPatterns(min + 1 + 1)) else None
+ // }
+ // }
} \ No newline at end of file
diff --git a/src/compiler/scala/tools/nsc/matching/TransMatcher.scala b/src/compiler/scala/tools/nsc/matching/TransMatcher.scala
index b73acb8004..2fb162a059 100644
--- a/src/compiler/scala/tools/nsc/matching/TransMatcher.scala
+++ b/src/compiler/scala/tools/nsc/matching/TransMatcher.scala
@@ -18,13 +18,14 @@ import scala.util.NameTransformer.decode
*
* @author Burak Emir
*/
-trait TransMatcher extends ast.TreeDSL with CompactTreePrinter {
+trait TransMatcher extends ast.TreeDSL {
self: ExplicitOuter with ParallelMatching =>
import global.{ typer => _, _ }
import analyzer.Typer
import definitions._
import CODE._
+ import Debug.tracing
// cunit is set to the current unit in ExplicitOuter's transformUnit,
// and nulled out afterward to avoid leaking.
@@ -58,7 +59,7 @@ trait TransMatcher extends ast.TreeDSL with CompactTreePrinter {
def singleMatch(): (List[Tree], MatrixInit) = {
val v = copyVar(selector, isChecked)
- (List(v.valDef), MatrixInit(List(v.lhs), cases, matchError(v.ident)))
+ (tracing("root(s)", List(v.valDef)), MatrixInit(List(v.lhs), cases, matchError(v.ident)))
}
// For (x, y, z) match { ... we start with multiple roots, called tpXX.
@@ -67,7 +68,7 @@ trait TransMatcher extends ast.TreeDSL with CompactTreePrinter {
val vs = args zip rootTypes map { case (arg, tpe) => copyVar(arg, isChecked, tpe, "tp") }
def merror = matchError(treeCopy.Apply(app, fn, vs map (_.ident)))
- (vs map (_.valDef), MatrixInit(vs map (_.lhs), cases, merror))
+ (tracing("root(s)", vs map (_.valDef)), MatrixInit(vs map (_.lhs), cases, merror))
}
// sets up top level variables and algorithm input
@@ -87,6 +88,8 @@ trait TransMatcher extends ast.TreeDSL with CompactTreePrinter {
matrix optimize dfatree
}
+ object compactTreePrinters extends CompactTreePrinter
+
private def toCompactString(t: Tree): String = {
val buffer = new StringWriter()
val printer = compactTreePrinters.create(new PrintWriter(buffer))
@@ -96,98 +99,3 @@ trait TransMatcher extends ast.TreeDSL with CompactTreePrinter {
}
}
-/** A tree printer which is stingier about vertical whitespace and unnecessary
- * punctuation than the standard one.
- */
-trait CompactTreePrinter {
- val global: Global
-
- object compactTreePrinters extends {
- val trees: global.type = global
- } with TreePrinters {
- import trees._
-
- override def create(writer: PrintWriter): TreePrinter = new TreePrinter(writer) {
- // drill down through Blocks and pull out the real statements.
- def allStatements(t: Tree): List[Tree] = t match {
- case Block(stmts, expr) => (stmts flatMap allStatements) ::: List(expr)
- case _ => List(t)
- }
-
- override def printRaw(tree: Tree): Unit = {
- // routing supercalls through this for debugging ease
- def s() = {
- // Console.println("toSuper: " + tree.getClass)
- super.printRaw(tree)
- }
-
- tree match {
- // labels used for jumps - does not map to valid scala code
- case LabelDef(name, params, rhs) =>
- print("labeldef %s(%s) = ".format(name, params mkString ","))
- printRaw(rhs)
-
- // target.method(arg) ==> target method arg
- case Apply(Select(target, method), List(arg)) =>
- (target, arg) match {
- case (_: Ident, _: Literal | _: Ident) =>
- printRaw(target)
- print(" %s " format symName(tree, method))
- printRaw(arg)
- 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)
- if (n startsWith "unary_") {
- print(n drop 6)
- print(qualifier)
- }
- else s()
-
- // target.toString() ==> target.toString
- case Apply(fn, Nil) => printRaw(fn)
-
- // if a Block only continues one actual statement, just print it.
- case Block(stats, expr) =>
- allStatements(tree) match {
- case List(x) => printRow(List(x), "", ";", "")
- case _ => s()
- }
-
- // 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 (", "", ") ")
-
- def ifIndented(x: Tree) = {
- indent ; println ; printRaw(x) ; undent
- }
-
- indent ; println ;
- allStatements(thenp) match {
- case List(x: If) => ifIndented(x)
- case List(x) => printRaw(x)
- case _ => printRaw(thenp)
- }
- undent ; println ;
- val elseStmts = allStatements(elsep)
- if (!elseStmts.isEmpty) {
- print("else")
- indent ; println
- elseStmts match {
- case List(x) => printRaw(x)
- case xs => printRaw(elsep)
- }
- undent ; println
- }
- case _ => s()
- }
- }
- }
- }
-
- lazy val compactTreePrinter = compactTreePrinters.create()
-}
diff --git a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
index 0118c0f9cc..9aeebb2360 100644
--- a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
+++ b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
@@ -460,19 +460,19 @@ abstract class ExplicitOuter extends InfoTransform
sym setFlag notPROTECTED
super.transform(tree)
- case Apply(sel @ Select(qual, name), args)
- if (name == nme.CONSTRUCTOR && isInner(sel.symbol.owner)) =>
- val outerVal = atPos(tree.pos) {
- if (qual.isInstanceOf[This]) { // it's a call between constructors of same class
- assert(outerParam != NoSymbol)
- outerValue
- } else {
- var pre = qual.tpe.prefix
- if (pre == NoPrefix) pre = sym.owner.outerClass.thisType
- gen.mkAttributedQualifier(pre)
- }
- }
- super.transform(treeCopy.Apply(tree, sel, outerVal :: args))
+ case Apply(sel @ Select(qual, name), args) if (name == nme.CONSTRUCTOR && isInner(sel.symbol.owner)) =>
+ val outerVal = atPos(tree.pos)(qual match {
+ // it's a call between constructors of same class
+ case _: This =>
+ assert(outerParam != NoSymbol)
+ outerValue
+ case _ =>
+ gen.mkAttributedQualifier(qual.tpe.prefix match {
+ case NoPrefix => sym.owner.outerClass.thisType
+ case x => x
+ })
+ })
+ super.transform(treeCopy.Apply(tree, sel, outerVal :: args))
// TransMatch hook
case mch: Match =>