aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools
diff options
context:
space:
mode:
authorDmitry Petrashko <dmitry.petrashko@gmail.com>2014-03-17 22:25:47 +0100
committerDmitry Petrashko <dmitry.petrashko@gmail.com>2014-03-19 15:53:47 +0100
commit09d02bd3670b947da147aec40835822d894b17b0 (patch)
tree01e81ad97df8b0e3e59cb72b3b77893e1d6f1070 /src/dotty/tools
parent5cbd2fbc8409b446f8751792b006693e1d091055 (diff)
downloaddotty-09d02bd3670b947da147aec40835822d894b17b0.tar.gz
dotty-09d02bd3670b947da147aec40835822d894b17b0.tar.bz2
dotty-09d02bd3670b947da147aec40835822d894b17b0.zip
Allow MiniPhase to be DenotTransformer
All MiniPhases now as are full-fledged phases, and are given their own periods and can register DenotTransformers. MiniPhases belonging to same group(list) will be squashed to single phase.
Diffstat (limited to 'src/dotty/tools')
-rw-r--r--src/dotty/tools/dotc/Compiler.scala12
-rw-r--r--src/dotty/tools/dotc/core/Contexts.scala11
-rw-r--r--src/dotty/tools/dotc/core/DenotTransformers.scala2
-rw-r--r--src/dotty/tools/dotc/core/Denotations.scala13
-rw-r--r--src/dotty/tools/dotc/core/Periods.scala6
-rw-r--r--src/dotty/tools/dotc/core/Phases.scala76
-rw-r--r--src/dotty/tools/dotc/transform/CreateCompanionObjects.scala4
-rw-r--r--src/dotty/tools/dotc/transform/TreeTransform.scala148
-rw-r--r--src/dotty/tools/dotc/transform/UncurryTreeTransform.scala (renamed from src/dotty/tools/dotc/transform/SamplePhase.scala)34
9 files changed, 216 insertions, 90 deletions
diff --git a/src/dotty/tools/dotc/Compiler.scala b/src/dotty/tools/dotc/Compiler.scala
index 132a25d0b..c2f21f639 100644
--- a/src/dotty/tools/dotc/Compiler.scala
+++ b/src/dotty/tools/dotc/Compiler.scala
@@ -8,14 +8,20 @@ import Symbols._
import typer.{FrontEnd, Typer, Mode, ImportInfo}
import reporting.ConsoleReporter
import dotty.tools.dotc.core.Phases.Phase
-import dotty.tools.dotc.transform.{LazyValsCreateCompanionObjects, LazyValTranformContext}
+import dotty.tools.dotc.transform.{UncurryTreeTransform, LazyValsCreateCompanionObjects, LazyValTranformContext}
import dotty.tools.dotc.transform.TreeTransforms.{TreeTransform, TreeTransformer}
import dotty.tools.dotc.transform.PostTyperTransformers.PostTyperTransformer
+import dotty.tools.dotc.core.DenotTransformers.DenotTransformer
+import dotty.tools.dotc.core.Denotations.SingleDenotation
+import dotty.tools.dotc.transform.TreeTransforms.Separator
class Compiler {
-
- def phases: List[Phase] = List(new FrontEnd, new transform.SamplePhase)
+ def phases: List[List[Phase]] = List(
+ List(new FrontEnd), List(new LazyValsCreateCompanionObjects),
+ //force separataion between lazyVals and LVCreateCO
+ List(new LazyValTranformContext().transformer, new UncurryTreeTransform)
+ )
var runId = 1
def nextRunId = {
diff --git a/src/dotty/tools/dotc/core/Contexts.scala b/src/dotty/tools/dotc/core/Contexts.scala
index 38784ec0c..68daea440 100644
--- a/src/dotty/tools/dotc/core/Contexts.scala
+++ b/src/dotty/tools/dotc/core/Contexts.scala
@@ -25,7 +25,7 @@ import collection.immutable.BitSet
import printing._
import config.{Settings, ScalaSettings, Platform, JavaPlatform}
import language.implicitConversions
-
+import DenotTransformers.DenotTransformer
object Contexts {
/** A context is passed basically everywhere in dotc.
@@ -387,7 +387,7 @@ object Contexts {
def rootLoader(root: TermSymbol)(implicit ctx: Context): SymbolLoader = platform.rootLoader(root)
// Set up some phases to get started */
- usePhases(SomePhase :: Nil)
+ usePhases(List(List(SomePhase)))
/** The standard definitions */
val definitions = new Definitions
@@ -460,8 +460,13 @@ object Contexts {
/** Phases by id */
private[core] var phases: Array[Phase] = _
+ /** Phases with consecutive Transforms groupped into a single phase */
+ private [core] var squashedPhases: Array[Phase] = _
+
/** Next denotation transformer id */
- private[core] var nextTransformerId: Array[Int] = _
+ private[core] var nextDenotTransformerId: Array[Int] = _
+
+ private[core] var denotTransformers: Array[DenotTransformer] = _
// Printers state
/** Number of recursive invocations of a show method on cuyrrent stack */
diff --git a/src/dotty/tools/dotc/core/DenotTransformers.scala b/src/dotty/tools/dotc/core/DenotTransformers.scala
index be85b5877..e1ee355d8 100644
--- a/src/dotty/tools/dotc/core/DenotTransformers.scala
+++ b/src/dotty/tools/dotc/core/DenotTransformers.scala
@@ -21,7 +21,7 @@ object DenotTransformers {
trait DenotTransformer extends Phase {
/** The last phase during which the transformed denotations are valid */
- def lastPhaseId(implicit ctx: Context) = ctx.nextTransformerId(id + 1)
+ def lastPhaseId(implicit ctx: Context) = ctx.nextDenotTransformerId(id + 1)
/** The validity period of the transformer in the given context */
def validFor(implicit ctx: Context): Period =
diff --git a/src/dotty/tools/dotc/core/Denotations.scala b/src/dotty/tools/dotc/core/Denotations.scala
index b35647ead..e15c70637 100644
--- a/src/dotty/tools/dotc/core/Denotations.scala
+++ b/src/dotty/tools/dotc/core/Denotations.scala
@@ -501,6 +501,8 @@ object Denotations {
def current(implicit ctx: Context): SingleDenotation = {
val currentPeriod = ctx.period
val valid = myValidFor
+ assert(valid.code > 0, s"negative period $valid: ${valid.code}")
+
if (valid.runId != currentPeriod.runId) bringForward.current
else {
var cur = this
@@ -514,12 +516,15 @@ object Denotations {
if (next.validFor.code > valid.code) {
// in this case, next.validFor contains currentPeriod
cur = next
+ cur
} else {
// not found, cur points to highest existing variant
var startPid = cur.validFor.lastPhaseId + 1
- val transformer = ctx.phases(startPid - 1).asInstanceOf[DenotTransformer]
+ val nextTranformerId = ctx.nextDenotTransformerId(startPid)
+ val transformer = ctx.denotTransformers(nextTranformerId)
//println(s"transforming with $transformer")
- next = transformer.transform(cur).syncWithParents
+ if (currentPeriod.lastPhaseId > transformer.id)
+ next = transformer.transform(cur).syncWithParents
if (next eq cur)
startPid = cur.validFor.firstPhaseId
else {
@@ -534,6 +539,7 @@ object Denotations {
cur.validFor = Period(
currentPeriod.runId, startPid, transformer.lastPhaseId)
//println(s"new denot: $cur, valid for ${cur.validFor}")
+ cur.current // multiple transformations could be required
}
} else {
// currentPeriod < end of valid; in this case a version must exist
@@ -545,8 +551,9 @@ object Denotations {
cnt += 1
assert(cnt <= MaxPossiblePhaseId, s"seems to be a loop in Denotations for $this, currentPeriod = $currentPeriod")
}
+ cur
}
- cur
+
}
}
diff --git a/src/dotty/tools/dotc/core/Periods.scala b/src/dotty/tools/dotc/core/Periods.scala
index 1c9fbf0c6..61f395c7d 100644
--- a/src/dotty/tools/dotc/core/Periods.scala
+++ b/src/dotty/tools/dotc/core/Periods.scala
@@ -32,8 +32,8 @@ abstract class Periods extends DotClass { self: Context =>
*/
def stablePeriod = {
var first = phaseId
- val nxTrans = ctx.base.nextTransformerId(first)
- while (first - 1 > NoPhaseId && (ctx.base.nextTransformerId(first - 1) == nxTrans)) {
+ val nxTrans = ctx.base.nextDenotTransformerId(first)
+ while (first - 1 > NoPhaseId && (ctx.base.nextDenotTransformerId(first - 1) == nxTrans)) {
first -= 1
}
Period(runId, first, nxTrans)
@@ -49,6 +49,8 @@ object Periods {
* runid 21 bits
* last phase id: 5 bits
* #phases before last: 5 bits
+ *
+ * // Dmitry: sign == 0 isn't actually always true, in some cases phaseId == -1 is used for shifts, that easily creates code < 0
*/
class Period(val code: Int) extends AnyVal {
diff --git a/src/dotty/tools/dotc/core/Phases.scala b/src/dotty/tools/dotc/core/Phases.scala
index 81ab7acbf..c49d314bc 100644
--- a/src/dotty/tools/dotc/core/Phases.scala
+++ b/src/dotty/tools/dotc/core/Phases.scala
@@ -7,8 +7,15 @@ import util.DotClass
import DenotTransformers._
import Denotations._
import config.Printers._
+import scala.collection.mutable.{ListBuffer, ArrayBuffer}
+import dotty.tools.dotc.transform.TreeTransforms.{TreeTransformer, TreeTransform}
+import dotty.tools.dotc.transform.PostTyperTransformers.PostTyperTransformer
+import dotty.tools.dotc.transform.TreeTransforms
+import TreeTransforms.Separator
+
+trait Phases {
+ self: Context =>
-trait Phases { self: Context =>
import Phases._
def phase: Phase = base.phases(period.phaseId)
@@ -32,9 +39,13 @@ trait Phases { self: Context =>
object Phases {
- trait PhasesBase { this: ContextBase =>
+ trait PhasesBase {
+ this: ContextBase =>
+
+ // drop NoPhase at beginning
+ def allPhases = squashedPhases.tail
+
- def allPhases = phases.tail // drop NoPhase at beginning
object NoPhase extends Phase {
override def exists = false
@@ -62,10 +73,12 @@ object Phases {
/** Use the following phases in the order they are given.
* The list should never contain NoPhase.
+ * if squashing is enabled, phases in same subgroup will be squashed to single phase.
*/
- def usePhases(phases: List[Phase]) = {
- this.phases = (NoPhase :: phases ::: new TerminalPhase :: Nil).toArray
- this.nextTransformerId = new Array[Int](this.phases.length)
+ def usePhases(phases: List[List[Phase]], squash: Boolean = true) = {
+ this.phases = (NoPhase :: phases.flatten ::: new TerminalPhase :: Nil).toArray
+ this.nextDenotTransformerId = new Array[Int](this.phases.length)
+ this.denotTransformers = new Array[DenotTransformer](this.phases.length)
var i = 0
while (i < this.phases.length) {
this.phases(i)._id = i
@@ -74,11 +87,48 @@ object Phases {
var lastTransformerId = i
while (i > 0) {
i -= 1
- if (this.phases(i).isInstanceOf[DenotTransformer]) lastTransformerId = i
- nextTransformerId(i) = lastTransformerId
+ this.phases(i) match {
+ case transformer: DenotTransformer =>
+ lastTransformerId = i
+ denotTransformers(i) = transformer
+ case _ =>
+ }
+ nextDenotTransformerId(i) = lastTransformerId
}
+
+ if (squash) {
+ val squashedPhases = ListBuffer[Phase]()
+ var postTyperEmmited = false
+ var i = 0
+ while (i < phases.length) {
+ if (phases(i).length > 1) {
+ assert(phases(i).forall(x => x.isInstanceOf[TreeTransform]), "Only tree transforms can be squashed")
+
+ val transforms = phases(i).asInstanceOf[List[TreeTransform]]
+ val block =
+ if (!postTyperEmmited) {
+ postTyperEmmited = true
+ new PostTyperTransformer {
+ override def name: String = transformations.map(_.name).mkString("TreeTransform:{", ", ", "}")
+ override protected def transformations: Array[TreeTransform] = transforms.toArray
+ }
+ } else new TreeTransformer {
+ override def name: String = transformations.map(_.name).mkString("TreeTransform:{", ", ", "}")
+ override protected def transformations: Array[TreeTransform] = transforms.toArray
+ }
+ squashedPhases += block
+ block._id = phases(i).head.id
+ } else squashedPhases += phases(i).head
+ i += 1
+ }
+ this.squashedPhases = (NoPhase::squashedPhases.toList :::new TerminalPhase :: Nil).toArray
+ } else {
+ this.squashedPhases = this.phases
+ }
+
config.println(s"Phases = ${this.phases.deep}")
- config.println(s"nextTransformId = ${nextTransformerId.deep}")
+ config.println(s"squashedPhases = ${this.squashedPhases.deep}")
+ config.println(s"nextDenotTransformerId = ${nextDenotTransformerId.deep}")
}
final val typerName = "typer"
@@ -110,12 +160,12 @@ object Phases {
private[Phases] var _id = -1
/** The sequence position of this phase in the given context where 0
- * is reserved for NoPhase and the first real phase is at position 1.
- * -1 if the phase is not installed in the context.
+ * is reserved for NoPhase and the first real phase is at position 1.
+ * -1 if the phase is not installed in the context.
*/
def id = _id
- final def <= (that: Phase)(implicit ctx: Context) =
+ final def <=(that: Phase)(implicit ctx: Context) =
exists && id <= that.id
final def prev(implicit ctx: Context): Phase =
@@ -131,7 +181,7 @@ object Phases {
final def erasedTypes(implicit ctx: Context): Boolean = ctx.erasurePhase <= this
final def flatClasses(implicit ctx: Context): Boolean = ctx.flattenPhase <= this
- final def refChecked (implicit ctx: Context): Boolean = ctx.refchecksPhase <= this
+ final def refChecked(implicit ctx: Context): Boolean = ctx.refchecksPhase <= this
override def toString = name
}
diff --git a/src/dotty/tools/dotc/transform/CreateCompanionObjects.scala b/src/dotty/tools/dotc/transform/CreateCompanionObjects.scala
index 8560b6f6d..f1131b3f2 100644
--- a/src/dotty/tools/dotc/transform/CreateCompanionObjects.scala
+++ b/src/dotty/tools/dotc/transform/CreateCompanionObjects.scala
@@ -19,13 +19,13 @@ import NameOps._
/** A transformer that provides a convenient way to create companion objects
*/
-abstract class CreateCompanionObjects(group: TreeTransformer, idx: Int) extends TreeTransform(group, idx) {
+abstract class CreateCompanionObjects extends TreeTransform {
import tpd._
/** Given class definition should return true if companion object creation should be enforced
*/
- def predicate(cls: TypeDef)(implicit ctx:Context): Boolean
+ def predicate(cls: TypeDef)(implicit ctx: Context): Boolean
override def transformStats(trees: List[Tree])(implicit ctx: Context, info: TransformerInfo): List[tpd.Tree] = {
@tailrec
diff --git a/src/dotty/tools/dotc/transform/TreeTransform.scala b/src/dotty/tools/dotc/transform/TreeTransform.scala
index 3e29af0e4..6455b6062 100644
--- a/src/dotty/tools/dotc/transform/TreeTransform.scala
+++ b/src/dotty/tools/dotc/transform/TreeTransform.scala
@@ -46,7 +46,10 @@ object TreeTransforms {
* (4) chain 7 out of 20 transformations over the resulting tree node. I believe the current algorithm is suitable
* for achieving this goal, but there can be no wasted cycles anywhere.
*/
- class TreeTransform(group: TreeTransformer, idx: Int) {
+ abstract class TreeTransform extends Phase {
+
+ /** id of this treeTransform in group */
+ var idx: Int = _
def prepareForIdent(tree: Ident) = this
def prepareForSelect(tree: Select) = this
@@ -100,7 +103,7 @@ object TreeTransforms {
def transformTry(tree: Try)(implicit ctx: Context, info: TransformerInfo): Tree = tree
def transformThrow(tree: Throw)(implicit ctx: Context, info: TransformerInfo): Tree = tree
def transformSeqLiteral(tree: SeqLiteral)(implicit ctx: Context, info: TransformerInfo): Tree = tree
- def transformTypeTree(tree: TypeTree)(implicit ctx: Context): Tree = tree
+ def transformTypeTree(tree: TypeTree)(implicit ctx: Context, info: TransformerInfo): Tree = tree
def transformSelectFromTypeTree(tree: SelectFromTypeTree)(implicit ctx: Context, info: TransformerInfo): Tree = tree
def transformBind(tree: Bind)(implicit ctx: Context, info: TransformerInfo): Tree = tree
def transformAlternative(tree: Alternative)(implicit ctx: Context, info: TransformerInfo): Tree = tree
@@ -113,23 +116,42 @@ object TreeTransforms {
def transformStats(trees: List[Tree])(implicit ctx: Context, info: TransformerInfo): List[Tree] = trees
/** Transform tree using all transforms of current group (including this one) */
- def transform(tree: Tree)(implicit ctx: Context, info: TransformerInfo): Tree = group.transform(tree, info, 0)
+ def transform(tree: Tree)(implicit ctx: Context, info: TransformerInfo): Tree = info.group.transform(tree, info, 0)
/** Transform subtree using all transforms following the current one in this group */
- def transformFollowingDeep(tree: Tree)(implicit ctx: Context, info: TransformerInfo): Tree = group.transform(tree, info, idx + 1)
+ def transformFollowingDeep(tree: Tree)(implicit ctx: Context, info: TransformerInfo): Tree = info.group.transform(tree, info, idx + 1)
/** Transform single node using all transforms following the current one in this group */
- def transformFollowing(tree: Tree)(implicit ctx: Context, info: TransformerInfo): Tree = group.transformSingle(tree, idx + 1)
+ def transformFollowing(tree: Tree)(implicit ctx: Context, info: TransformerInfo): Tree = info.group.transformSingle(tree, idx + 1)
/** perform context-dependant initialization */
- def init(implicit ctx:Context): Unit = {}
+ def init(implicit ctx:Context, info: TransformerInfo): Unit = {}
+
+ protected def mkTreeTransformer = new TreeTransformer {
+ override def name: String = TreeTransform.this.name
+ override protected def transformations = Array(TreeTransform.this)
+ }
+
+ override def run(implicit ctx: Context): Unit = {
+ mkTreeTransformer.run
+ }
}
- val NoTransform = new TreeTransform(null, -1)
+ val NoTransform = new TreeTransform {
+ override def name: String = "NoTransform"
+ idx = -1
+ }
+
+ class Separator extends TreeTransform {
+ override def name: String = "Separator"
+ idx = -1
+ }
type Mutator[T] = (TreeTransform, T) => TreeTransform
- class TransformerInfo(val transformers: Array[TreeTransform], val nx: NXTransformations) {}
+ class TransformerInfo(val transformers: Array[TreeTransform], val nx: NXTransformations, val group:TreeTransformer, val contexts:Array[Context]) {
+ assert(transformers.size == contexts.size)
+ }
/**
* This class maintains track of which methods are redefined in MiniPhases and creates execution plans for transformXXX and prepareXXX
@@ -392,7 +414,7 @@ object TreeTransforms {
/** A group of tree transforms that are applied in sequence during the same phase */
abstract class TreeTransformer extends Phase {
- protected def transformations: Array[(TreeTransformer, Int) => TreeTransform]
+ protected def transformations: Array[TreeTransform]
override def run(implicit ctx: Context): Unit = {
val curTree = ctx.compilationUnit.tpdTree
@@ -425,7 +447,7 @@ object TreeTransforms {
}
if (allDone) null
else if (!transformersCopied) info
- else new TransformerInfo(result, resultNX)
+ else new TransformerInfo(result, resultNX, info.group, info.contexts)
}
val prepForIdent: Mutator[Ident] = (trans, tree) => trans.prepareForIdent(tree)
@@ -461,15 +483,23 @@ object TreeTransforms {
val prepForStats: Mutator[List[Tree]]= (trans, trees) => trans.prepareForStats(trees)
def transform(t: Tree)(implicit ctx: Context): Tree = {
- val initialTransformations = transformations.zipWithIndex.map(x => x._1(this, x._2))
- initialTransformations.foreach(_.init)
- transform(t, new TransformerInfo(initialTransformations, new NXTransformations(initialTransformations)), 0)
+ val initialTransformations = transformations
+ val contexts = initialTransformations.map(tr => ctx.fresh.withPhase(tr).ctx)
+ val info = new TransformerInfo(initialTransformations, new NXTransformations(initialTransformations), this, contexts)
+ initialTransformations.zipWithIndex.foreach{
+ case (transform, id) =>
+ transform.idx = id
+ transform.init(ctx, info)
+ }
+ transform(t, info, 0)
}
@tailrec
final private[TreeTransforms] def goIdent(tree: Ident, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = {
if (cur < info.transformers.length) {
- info.transformers(cur).transformIdent(tree) match {
+ val trans = info.transformers(cur)
+
+ trans.transformIdent(tree)(info.contexts(cur), info) match {
case t: Ident => goIdent(t, info.nx.nxTransIdent(cur + 1))
case t => transformSingle(t, cur + 1)
}
@@ -479,7 +509,8 @@ object TreeTransforms {
@tailrec
final private[TreeTransforms] def goSelect(tree: Select, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = {
if (cur < info.transformers.length) {
- info.transformers(cur).transformSelect(tree) match {
+ val trans = info.transformers(cur)
+ trans.transformSelect(tree)(info.contexts(cur), info) match {
case t: Select => goSelect(t, info.nx.nxTransSelect(cur + 1))
case t => transformSingle(t, cur + 1)
}
@@ -489,7 +520,8 @@ object TreeTransforms {
@tailrec
final private[TreeTransforms] def goThis(tree: This, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = {
if (cur < info.transformers.length) {
- info.transformers(cur).transformThis(tree) match {
+ val trans = info.transformers(cur)
+ trans.transformThis(tree)(info.contexts(cur), info) match {
case t: This => goThis(t, info.nx.nxTransThis(cur + 1))
case t => transformSingle(t, cur + 1)
}
@@ -499,7 +531,8 @@ object TreeTransforms {
@tailrec
final private[TreeTransforms] def goSuper(tree: Super, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = {
if (cur < info.transformers.length) {
- info.transformers(cur).transformSuper(tree) match {
+ val trans = info.transformers(cur)
+ trans.transformSuper(tree)(info.contexts(cur), info) match {
case t: Super => goSuper(t, info.nx.nxTransSuper(cur + 1))
case t => transformSingle(t, cur + 1)
}
@@ -509,7 +542,8 @@ object TreeTransforms {
@tailrec
final private[TreeTransforms] def goApply(tree: Apply, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = {
if (cur < info.transformers.length) {
- info.transformers(cur).transformApply(tree) match {
+ val trans = info.transformers(cur)
+ trans.transformApply(tree)(info.contexts(cur), info) match {
case t: Apply => goApply(t, info.nx.nxTransApply(cur + 1))
case t => transformSingle(t, cur + 1)
}
@@ -519,7 +553,8 @@ object TreeTransforms {
@tailrec
final private[TreeTransforms] def goTypeApply(tree: TypeApply, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = {
if (cur < info.transformers.length) {
- info.transformers(cur).transformTypeApply(tree) match {
+ val trans = info.transformers(cur)
+ trans.transformTypeApply(tree)(info.contexts(cur), info) match {
case t: TypeApply => goTypeApply(t, info.nx.nxTransTypeApply(cur + 1))
case t => transformSingle(t, cur + 1)
}
@@ -529,7 +564,8 @@ object TreeTransforms {
@tailrec
final private[TreeTransforms] def goNew(tree: New, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = {
if (cur < info.transformers.length) {
- info.transformers(cur).transformNew(tree) match {
+ val trans = info.transformers(cur)
+ trans.transformNew(tree)(info.contexts(cur), info) match {
case t: New => goNew(t, info.nx.nxTransNew(cur + 1))
case t => transformSingle(t, cur + 1)
}
@@ -539,7 +575,8 @@ object TreeTransforms {
@tailrec
final private[TreeTransforms] def goPair(tree: Pair, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = {
if (cur < info.transformers.length) {
- info.transformers(cur).transformPair(tree) match {
+ val trans = info.transformers(cur)
+ trans.transformPair(tree)(info.contexts(cur), info) match {
case t: Pair => goPair(t, info.nx.nxTransPair(cur + 1))
case t => transformSingle(t, cur + 1)
}
@@ -549,7 +586,8 @@ object TreeTransforms {
@tailrec
final private[TreeTransforms] def goTyped(tree: Typed, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = {
if (cur < info.transformers.length) {
- info.transformers(cur).transformTyped(tree) match {
+ val trans = info.transformers(cur)
+ trans.transformTyped(tree)(info.contexts(cur), info) match {
case t: Typed => goTyped(t, info.nx.nxTransTyped(cur + 1))
case t => transformSingle(t, cur + 1)
}
@@ -559,7 +597,8 @@ object TreeTransforms {
@tailrec
final private[TreeTransforms] def goAssign(tree: Assign, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = {
if (cur < info.transformers.length) {
- info.transformers(cur).transformAssign(tree) match {
+ val trans = info.transformers(cur)
+ trans.transformAssign(tree)(info.contexts(cur), info) match {
case t: Assign => goAssign(t, info.nx.nxTransAssign(cur + 1))
case t => transformSingle(t, cur + 1)
}
@@ -569,7 +608,8 @@ object TreeTransforms {
@tailrec
final private[TreeTransforms] def goLiteral(tree: Literal, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = {
if (cur < info.transformers.length) {
- info.transformers(cur).transformLiteral(tree) match {
+ val trans = info.transformers(cur)
+ trans.transformLiteral(tree)(info.contexts(cur), info) match {
case t: Literal => goLiteral(t, info.nx.nxTransLiteral(cur + 1))
case t => transformSingle(t, cur + 1)
}
@@ -579,7 +619,8 @@ object TreeTransforms {
@tailrec
final private[TreeTransforms] def goBlock(tree: Block, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = {
if (cur < info.transformers.length) {
- info.transformers(cur).transformBlock(tree) match {
+ val trans = info.transformers(cur)
+ trans.transformBlock(tree)(info.contexts(cur), info) match {
case t: Block => goBlock(t, info.nx.nxTransBlock(cur + 1))
case t => transformSingle(t, cur + 1)
}
@@ -589,7 +630,8 @@ object TreeTransforms {
@tailrec
final private[TreeTransforms] def goIf(tree: If, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = {
if (cur < info.transformers.length) {
- info.transformers(cur).transformIf(tree) match {
+ val trans = info.transformers(cur)
+ trans.transformIf(tree)(info.contexts(cur), info) match {
case t: If => goIf(t, info.nx.nxTransIf(cur + 1))
case t => transformSingle(t, cur + 1)
}
@@ -599,7 +641,8 @@ object TreeTransforms {
@tailrec
final private[TreeTransforms] def goClosure(tree: Closure, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = {
if (cur < info.transformers.length) {
- info.transformers(cur).transformClosure(tree) match {
+ val trans = info.transformers(cur)
+ trans.transformClosure(tree)(info.contexts(cur), info) match {
case t: Closure => goClosure(t, info.nx.nxTransClosure(cur + 1))
case t => transformSingle(t, cur + 1)
}
@@ -609,7 +652,8 @@ object TreeTransforms {
@tailrec
final private[TreeTransforms] def goMatch(tree: Match, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = {
if (cur < info.transformers.length) {
- info.transformers(cur).transformMatch(tree) match {
+ val trans = info.transformers(cur)
+ trans.transformMatch(tree)(info.contexts(cur), info) match {
case t: Match => goMatch(t, info.nx.nxTransMatch(cur + 1))
case t => transformSingle(t, cur + 1)
}
@@ -619,7 +663,8 @@ object TreeTransforms {
@tailrec
final private[TreeTransforms] def goCaseDef(tree: CaseDef, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = {
if (cur < info.transformers.length) {
- info.transformers(cur).transformCaseDef(tree) match {
+ val trans = info.transformers(cur)
+ trans.transformCaseDef(tree)(info.contexts(cur), info) match {
case t: CaseDef => goCaseDef(t, info.nx.nxTransCaseDef(cur + 1))
case t => transformSingle(t, cur + 1)
}
@@ -629,7 +674,8 @@ object TreeTransforms {
@tailrec
final private[TreeTransforms] def goReturn(tree: Return, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = {
if (cur < info.transformers.length) {
- info.transformers(cur).transformReturn(tree) match {
+ val trans = info.transformers(cur)
+ trans.transformReturn(tree)(info.contexts(cur), info) match {
case t: Return => goReturn(t, info.nx.nxTransReturn(cur + 1))
case t => transformSingle(t, cur + 1)
}
@@ -639,7 +685,8 @@ object TreeTransforms {
@tailrec
final private[TreeTransforms] def goTry(tree: Try, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = {
if (cur < info.transformers.length) {
- info.transformers(cur).transformTry(tree) match {
+ val trans = info.transformers(cur)
+ trans.transformTry(tree)(info.contexts(cur), info) match {
case t: Try => goTry(t, info.nx.nxTransTry(cur + 1))
case t => transformSingle(t, cur + 1)
}
@@ -649,7 +696,8 @@ object TreeTransforms {
@tailrec
final private[TreeTransforms] def goThrow(tree: Throw, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = {
if (cur < info.transformers.length) {
- info.transformers(cur).transformThrow(tree) match {
+ val trans = info.transformers(cur)
+ trans.transformThrow(tree)(info.contexts(cur), info) match {
case t: Throw => goThrow(t, info.nx.nxTransThrow(cur + 1))
case t => transformSingle(t, cur + 1)
}
@@ -659,7 +707,8 @@ object TreeTransforms {
@tailrec
final private[TreeTransforms] def goSeqLiteral(tree: SeqLiteral, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = {
if (cur < info.transformers.length) {
- info.transformers(cur).transformSeqLiteral(tree) match {
+ val trans = info.transformers(cur)
+ trans.transformSeqLiteral(tree)(info.contexts(cur), info) match {
case t: SeqLiteral => goSeqLiteral(t, info.nx.nxTransSeqLiteral(cur + 1))
case t => transformSingle(t, cur + 1)
}
@@ -669,7 +718,8 @@ object TreeTransforms {
@tailrec
final private[TreeTransforms] def goTypeTree(tree: TypeTree, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = {
if (cur < info.transformers.length) {
- info.transformers(cur).transformTypeTree(tree) match {
+ val trans = info.transformers(cur)
+ trans.transformTypeTree(tree)(info.contexts(cur), info) match {
case t: TypeTree => goTypeTree(t, info.nx.nxTransTypeTree(cur + 1))
case t => transformSingle(t, cur + 1)
}
@@ -679,7 +729,8 @@ object TreeTransforms {
@tailrec
final private[TreeTransforms] def goSelectFromTypeTree(tree: SelectFromTypeTree, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = {
if (cur < info.transformers.length) {
- info.transformers(cur).transformSelectFromTypeTree(tree) match {
+ val trans = info.transformers(cur)
+ trans.transformSelectFromTypeTree(tree)(info.contexts(cur), info) match {
case t: SelectFromTypeTree => goSelectFromTypeTree(t, info.nx.nxTransSelectFromTypeTree(cur + 1))
case t => transformSingle(t, cur + 1)
}
@@ -689,7 +740,8 @@ object TreeTransforms {
@tailrec
final private[TreeTransforms] def goBind(tree: Bind, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = {
if (cur < info.transformers.length) {
- info.transformers(cur).transformBind(tree) match {
+ val trans = info.transformers(cur)
+ trans.transformBind(tree)(info.contexts(cur), info) match {
case t: Bind => goBind(t, info.nx.nxTransBind(cur + 1))
case t => transformSingle(t, cur + 1)
}
@@ -699,7 +751,8 @@ object TreeTransforms {
@tailrec
final private[TreeTransforms] def goAlternative(tree: Alternative, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = {
if (cur < info.transformers.length) {
- info.transformers(cur).transformAlternative(tree) match {
+ val trans = info.transformers(cur)
+ trans.transformAlternative(tree)(info.contexts(cur), info) match {
case t: Alternative => goAlternative(t, info.nx.nxTransAlternative(cur + 1))
case t => transformSingle(t, cur + 1)
}
@@ -709,7 +762,8 @@ object TreeTransforms {
@tailrec
final private[TreeTransforms] def goValDef(tree: ValDef, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = {
if (cur < info.transformers.length) {
- info.transformers(cur).transformValDef(tree) match {
+ val trans = info.transformers(cur)
+ trans.transformValDef(tree)(info.contexts(cur), info) match {
case t: ValDef => goValDef(t, info.nx.nxTransValDef(cur + 1))
case t => transformSingle(t, cur + 1)
}
@@ -719,7 +773,8 @@ object TreeTransforms {
@tailrec
final private[TreeTransforms] def goDefDef(tree: DefDef, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = {
if (cur < info.transformers.length) {
- info.transformers(cur).transformDefDef(tree) match {
+ val trans = info.transformers(cur)
+ trans.transformDefDef(tree)(info.contexts(cur), info) match {
case t: DefDef => goDefDef(t, info.nx.nxTransDefDef(cur + 1))
case t => transformSingle(t, cur + 1)
}
@@ -729,7 +784,8 @@ object TreeTransforms {
@tailrec
final private[TreeTransforms] def goUnApply(tree: UnApply, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = {
if (cur < info.transformers.length) {
- info.transformers(cur).transformUnApply(tree) match {
+ val trans = info.transformers(cur)
+ trans.transformUnApply(tree)(info.contexts(cur), info) match {
case t: UnApply => goUnApply(t, info.nx.nxTransUnApply(cur + 1))
case t => transformSingle(t, cur + 1)
}
@@ -739,7 +795,8 @@ object TreeTransforms {
@tailrec
final private[TreeTransforms] def goTypeDef(tree: TypeDef, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = {
if (cur < info.transformers.length) {
- info.transformers(cur).transformTypeDef(tree) match {
+ val trans = info.transformers(cur)
+ trans.transformTypeDef(tree)(info.contexts(cur), info) match {
case t: TypeDef => goTypeDef(t, info.nx.nxTransTypeDef(cur + 1))
case t => transformSingle(t, cur + 1)
}
@@ -749,7 +806,8 @@ object TreeTransforms {
@tailrec
final private[TreeTransforms] def goTemplate(tree: Template, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = {
if (cur < info.transformers.length) {
- info.transformers(cur).transformTemplate(tree) match {
+ val trans = info.transformers(cur)
+ trans.transformTemplate(tree)(info.contexts(cur), info) match {
case t: Template => goTemplate(t, info.nx.nxTransTemplate(cur + 1))
case t => transformSingle(t, cur + 1)
}
@@ -759,7 +817,8 @@ object TreeTransforms {
@tailrec
final private[TreeTransforms] def goPackageDef(tree: PackageDef, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = {
if (cur < info.transformers.length) {
- info.transformers(cur).transformPackageDef(tree) match {
+ val trans = info.transformers(cur)
+ trans.transformPackageDef(tree)(info.contexts(cur), info) match {
case t: PackageDef => goPackageDef(t, info.nx.nxTransPackageDef(cur + 1))
case t => transformSingle(t, cur + 1)
}
@@ -1069,7 +1128,8 @@ object TreeTransforms {
@tailrec
final private[TreeTransforms] def goStats(trees: List[Tree], cur: Int)(implicit ctx: Context, info: TransformerInfo): List[Tree] = {
if (cur < info.transformers.length) {
- val stats = info.transformers(cur).transformStats(trees)
+ val trans = info.transformers(cur)
+ val stats = trans.transformStats(trees)
goStats(stats, info.nx.nxTransStats(cur + 1))
} else trees
}
diff --git a/src/dotty/tools/dotc/transform/SamplePhase.scala b/src/dotty/tools/dotc/transform/UncurryTreeTransform.scala
index ed4ac113f..fe50e41cd 100644
--- a/src/dotty/tools/dotc/transform/SamplePhase.scala
+++ b/src/dotty/tools/dotc/transform/UncurryTreeTransform.scala
@@ -10,9 +10,21 @@ import core.Types._
import ast.Trees._
import ast.tpd.{Apply, Tree, cpy}
-class SamplePhase extends TreeTransformer with DenotTransformer {
- def name = "sample"
- def transformations = Array(new UncurryTreeTransform(_, _))
+class UncurryTreeTransform extends TreeTransform with DenotTransformer {
+
+ override def name: String = "uncurry"
+ override def transformApply(tree: Apply)(implicit ctx: Context, info: TransformerInfo): Tree =
+ ctx.traceIndented(s"transforming ${tree.show}", show = true) {
+ tree.fun match {
+ case Apply(fn, args) =>
+ def showType(implicit ctx: Context) =
+ ctx.log(s"at ${ctx.phase} ${fn.symbol} has type ${fn.symbol.info.widen.show}")
+ showType
+ ctx.atNextPhase(showType(_))
+ showType
+ cpy.Apply(tree, fn, args ++ tree.args)
+ case _ => tree
+ }}
def uncurry(tp: Type)(implicit ctx: Context): Type = tp match {
case tp @ MethodType(pnames1, ptypes1) =>
@@ -36,20 +48,4 @@ class SamplePhase extends TreeTransformer with DenotTransformer {
case _ => ref.derivedSingleDenotation(ref.symbol, info1)
}
}
-}
-
-class UncurryTreeTransform(group: TreeTransformer, idx: Int) extends TreeTransform(group, idx) {
-
- override def transformApply(tree: Apply)(implicit ctx: Context, info: TransformerInfo): Tree =
- ctx.traceIndented(s"transforming ${tree.show}", show = true) {
- tree.fun match {
- case Apply(fn, args) =>
- def showType(implicit ctx: Context) =
- ctx.log(s"at ${ctx.phase} ${fn.symbol} has type ${fn.symbol.info.widen.show}")
- showType
- ctx.atNextPhase(showType(_))
- showType
- cpy.Apply(tree, fn, args ++ tree.args)
- case _ => tree
- }}
} \ No newline at end of file