aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2015-03-04 16:21:45 +0100
committerMartin Odersky <odersky@gmail.com>2015-03-04 16:21:45 +0100
commitb558d6196bb75217acd466bffd59cd4ee339ba27 (patch)
tree0c79a9828333b53e22715034cccf043b5ff2849a
parent2bdce25034d50bc7526dc1d1c8f57e9c20e45b60 (diff)
downloaddotty-b558d6196bb75217acd466bffd59cd4ee339ba27.tar.gz
dotty-b558d6196bb75217acd466bffd59cd4ee339ba27.tar.bz2
dotty-b558d6196bb75217acd466bffd59cd4ee339ba27.zip
Eliminate Throw as a typed Tree
Replace with <compiler-ops>.throw(exception) Only leave Throw as an untyped tree.
-rw-r--r--src/dotty/tools/backend/jvm/DottyBackendInterface.scala4
-rw-r--r--src/dotty/tools/dotc/ast/Trees.scala15
-rw-r--r--src/dotty/tools/dotc/ast/tpd.scala9
-rw-r--r--src/dotty/tools/dotc/ast/untpd.scala10
-rw-r--r--src/dotty/tools/dotc/core/Definitions.scala4
-rw-r--r--src/dotty/tools/dotc/printing/RefinedPrinter.scala7
-rw-r--r--src/dotty/tools/dotc/transform/TreeTransform.scala28
-rw-r--r--src/dotty/tools/dotc/typer/TypeAssigner.scala3
-rw-r--r--src/dotty/tools/dotc/typer/Typer.scala4
9 files changed, 27 insertions, 57 deletions
diff --git a/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/src/dotty/tools/backend/jvm/DottyBackendInterface.scala
index 09d0452cf..44377cab4 100644
--- a/src/dotty/tools/backend/jvm/DottyBackendInterface.scala
+++ b/src/dotty/tools/backend/jvm/DottyBackendInterface.scala
@@ -29,6 +29,8 @@ import Decorators._
import tpd._
import StdNames.nme
+case class DummyThrow(expr: tpd.Tree) extends tpd.TermTree
+
class DottyBackendInterface()(implicit ctx: Context) extends BackendInterface{
trait NonExistentTree extends tpd.Tree
type Symbol = Symbols.Symbol
@@ -48,7 +50,7 @@ class DottyBackendInterface()(implicit ctx: Context) extends BackendInterface{
type Ident = tpd.Ident
type If = tpd.If
type ValDef = tpd.ValDef
- type Throw = tpd.Throw
+ type Throw = DummyThrow
type Return = tpd.Return
type Block = tpd.Block
type Typed = tpd.Typed
diff --git a/src/dotty/tools/dotc/ast/Trees.scala b/src/dotty/tools/dotc/ast/Trees.scala
index 07f8b5525..bd3dec362 100644
--- a/src/dotty/tools/dotc/ast/Trees.scala
+++ b/src/dotty/tools/dotc/ast/Trees.scala
@@ -513,12 +513,6 @@ object Trees {
type ThisTree[-T >: Untyped] = Try[T]
}
- /** throw expr */
- case class Throw[-T >: Untyped] private[ast] (expr: Tree[T])
- extends TermTree[T] {
- type ThisTree[-T >: Untyped] = Throw[T]
- }
-
/** Seq(elems) */
case class SeqLiteral[-T >: Untyped] private[ast] (elems: List[Tree[T]])
extends Tree[T] {
@@ -790,7 +784,6 @@ object Trees {
type CaseDef = Trees.CaseDef[T]
type Return = Trees.Return[T]
type Try = Trees.Try[T]
- type Throw = Trees.Throw[T]
type SeqLiteral = Trees.SeqLiteral[T]
type JavaSeqLiteral = Trees.JavaSeqLiteral[T]
type TypeTree = Trees.TypeTree[T]
@@ -942,10 +935,6 @@ object Trees {
case tree: Try if (expr eq tree.expr) && (cases eq tree.cases) && (finalizer eq tree.finalizer) => tree
case _ => finalize(tree, untpd.Try(expr, cases, finalizer))
}
- def Throw(tree: Tree)(expr: Tree)(implicit ctx: Context): Throw = tree match {
- case tree: Throw if (expr eq tree.expr) => tree
- case _ => finalize(tree, untpd.Throw(expr))
- }
def SeqLiteral(tree: Tree)(elems: List[Tree])(implicit ctx: Context): SeqLiteral = tree match {
case tree: JavaSeqLiteral =>
if (elems eq tree.elems) tree
@@ -1097,8 +1086,6 @@ object Trees {
cpy.Return(tree)(transform(expr), transformSub(from))
case Try(block, cases, finalizer) =>
cpy.Try(tree)(transform(block), transformSub(cases), transform(finalizer))
- case Throw(expr) =>
- cpy.Throw(tree)(transform(expr))
case SeqLiteral(elems) =>
cpy.SeqLiteral(tree)(transform(elems))
case TypeTree(original) =>
@@ -1200,8 +1187,6 @@ object Trees {
this(this(x, expr), from)
case Try(block, handler, finalizer) =>
this(this(this(x, block), handler), finalizer)
- case Throw(expr) =>
- this(x, expr)
case SeqLiteral(elems) =>
this(x, elems)
case TypeTree(original) =>
diff --git a/src/dotty/tools/dotc/ast/tpd.scala b/src/dotty/tools/dotc/ast/tpd.scala
index 77c607ca7..6a3c1d648 100644
--- a/src/dotty/tools/dotc/ast/tpd.scala
+++ b/src/dotty/tools/dotc/ast/tpd.scala
@@ -117,9 +117,6 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
def Try(block: Tree, cases: List[CaseDef], finalizer: Tree)(implicit ctx: Context): Try =
ta.assignType(untpd.Try(block, cases, finalizer), block, cases)
- def Throw(expr: Tree)(implicit ctx: Context): Throw =
- ta.assignType(untpd.Throw(expr))
-
def SeqLiteral(elems: List[Tree])(implicit ctx: Context): SeqLiteral =
ta.assignType(untpd.SeqLiteral(elems), elems)
@@ -252,6 +249,9 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
def Annotated(annot: Tree, arg: Tree)(implicit ctx: Context): Annotated =
ta.assignType(untpd.Annotated(annot, arg), annot, arg)
+
+ def Throw(expr: Tree)(implicit ctx: Context): Tree =
+ ref(defn.throwMethod).appliedTo(expr)
// ------ Making references ------------------------------------------------------
@@ -493,9 +493,6 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
}
}
- override def Throw(tree: Tree)(expr: Tree)(implicit ctx: Context): Throw =
- ta.assignType(untpd.cpy.Throw(tree)(expr))
-
override def SeqLiteral(tree: Tree)(elems: List[Tree])(implicit ctx: Context): SeqLiteral = {
val tree1 = untpd.cpy.SeqLiteral(tree)(elems)
tree match {
diff --git a/src/dotty/tools/dotc/ast/untpd.scala b/src/dotty/tools/dotc/ast/untpd.scala
index 02ee1eddf..dfff17514 100644
--- a/src/dotty/tools/dotc/ast/untpd.scala
+++ b/src/dotty/tools/dotc/ast/untpd.scala
@@ -50,6 +50,7 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
override def isTerm = trees.isEmpty || trees.head.isTerm
override def isType = !isTerm
}
+ case class Throw(expr: Tree) extends TermTree
case class WhileDo(cond: Tree, body: Tree) extends TermTree
case class DoWhile(body: Tree, cond: Tree) extends TermTree
case class ForYield(enums: List[Tree], expr: Tree) extends TermTree
@@ -126,7 +127,6 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
def CaseDef(pat: Tree, guard: Tree, body: Tree): CaseDef = new CaseDef(pat, guard, body)
def Return(expr: Tree, from: Tree): Return = new Return(expr, from)
def Try(expr: Tree, cases: List[CaseDef], finalizer: Tree): Try = new Try(expr, cases, finalizer)
- def Throw(expr: Tree): Throw = new Throw(expr)
def SeqLiteral(elems: List[Tree]): SeqLiteral = new SeqLiteral(elems)
def JavaSeqLiteral(elems: List[Tree]): JavaSeqLiteral = new JavaSeqLiteral(elems)
def TypeTree(original: Tree): TypeTree = new TypeTree(original)
@@ -305,6 +305,10 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
case tree: Tuple if (trees eq tree.trees) => tree
case _ => untpd.Tuple(trees).withPos(tree.pos)
}
+ def Throw(tree: Tree)(expr: Tree) = tree match {
+ case tree: Throw if (expr eq tree.expr) => tree
+ case _ => untpd.Throw(expr).withPos(tree.pos)
+ }
def WhileDo(tree: Tree)(cond: Tree, body: Tree) = tree match {
case tree: WhileDo if (cond eq tree.cond) && (body eq tree.body) => tree
case _ => untpd.WhileDo(cond, body).withPos(tree.pos)
@@ -359,6 +363,8 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
cpy.Parens(tree)(transform(t))
case Tuple(trees) =>
cpy.Tuple(tree)(transform(trees))
+ case Throw(expr) =>
+ cpy.Throw(tree)(transform(expr))
case WhileDo(cond, body) =>
cpy.WhileDo(tree)(transform(cond), transform(body))
case DoWhile(body, cond) =>
@@ -402,6 +408,8 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
this(x, t)
case Tuple(trees) =>
this(x, trees)
+ case Throw(expr) =>
+ this(x, expr)
case WhileDo(cond, body) =>
this(this(x, cond), body)
case DoWhile(body, cond) =>
diff --git a/src/dotty/tools/dotc/core/Definitions.scala b/src/dotty/tools/dotc/core/Definitions.scala
index 67c1f3105..89e4bd371 100644
--- a/src/dotty/tools/dotc/core/Definitions.scala
+++ b/src/dotty/tools/dotc/core/Definitions.scala
@@ -180,6 +180,10 @@ class Definitions {
lazy val dummyApply = newPolyMethod(
OpsPackageClass, nme.dummyApply, 1,
pt => MethodType(List(FunctionType(Nil, PolyParam(pt, 0))), PolyParam(pt, 0)))
+
+ /** Method representing a throw */
+ lazy val throwMethod = newMethod(OpsPackageClass, nme.THROWkw,
+ MethodType(List(ThrowableType), NothingType))
lazy val NothingClass: ClassSymbol = newCompleteClassSymbol(
ScalaPackageClass, tpnme.Nothing, AbstractFinal, List(AnyClass.typeRef))
diff --git a/src/dotty/tools/dotc/printing/RefinedPrinter.scala b/src/dotty/tools/dotc/printing/RefinedPrinter.scala
index babf42503..43dbef890 100644
--- a/src/dotty/tools/dotc/printing/RefinedPrinter.scala
+++ b/src/dotty/tools/dotc/printing/RefinedPrinter.scala
@@ -236,7 +236,12 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
case Super(This(name), mix) =>
optDotPrefix(name) ~ "super" ~ optText(mix)("[" ~ _ ~ "]")
case Apply(fun, args) =>
- toTextLocal(fun) ~ "(" ~ toTextGlobal(args, ", ") ~ ")"
+ if (fun.hasType && fun.symbol == defn.throwMethod)
+ changePrec (GlobalPrec) {
+ "throw " ~ toText(args.head)
+ }
+ else
+ toTextLocal(fun) ~ "(" ~ toTextGlobal(args, ", ") ~ ")"
case TypeApply(fun, args) =>
toTextLocal(fun) ~ "[" ~ toTextGlobal(args, ", ") ~ "]"
case Literal(c) =>
diff --git a/src/dotty/tools/dotc/transform/TreeTransform.scala b/src/dotty/tools/dotc/transform/TreeTransform.scala
index c1eb7e72f..ce3e3ce63 100644
--- a/src/dotty/tools/dotc/transform/TreeTransform.scala
+++ b/src/dotty/tools/dotc/transform/TreeTransform.scala
@@ -83,7 +83,6 @@ object TreeTransforms {
def prepareForCaseDef(tree: CaseDef)(implicit ctx: Context) = this
def prepareForReturn(tree: Return)(implicit ctx: Context) = this
def prepareForTry(tree: Try)(implicit ctx: Context) = this
- def prepareForThrow(tree: Throw)(implicit ctx: Context) = this
def prepareForSeqLiteral(tree: SeqLiteral)(implicit ctx: Context) = this
def prepareForTypeTree(tree: TypeTree)(implicit ctx: Context) = this
def prepareForSelectFromTypeTree(tree: SelectFromTypeTree)(implicit ctx: Context) = this
@@ -117,7 +116,6 @@ object TreeTransforms {
def transformCaseDef(tree: CaseDef)(implicit ctx: Context, info: TransformerInfo): Tree = tree
def transformReturn(tree: Return)(implicit ctx: Context, info: TransformerInfo): Tree = tree
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, info: TransformerInfo): Tree = tree
def transformSelectFromTypeTree(tree: SelectFromTypeTree)(implicit ctx: Context, info: TransformerInfo): Tree = tree
@@ -282,7 +280,6 @@ object TreeTransforms {
nxPrepMatch = index(transformations, "prepareForMatch")
nxPrepReturn = index(transformations, "prepareForReturn")
nxPrepTry = index(transformations, "prepareForTry")
- nxPrepThrow = index(transformations, "prepareForThrow")
nxPrepSeqLiteral = index(transformations, "prepareForSeqLiteral")
nxPrepTypeTree = index(transformations, "prepareForTypeTree")
nxPrepSelectFromTypeTree = index(transformations, "prepareForSelectFromTypeTree")
@@ -315,7 +312,6 @@ object TreeTransforms {
nxTransCaseDef = index(transformations, "transformCaseDef")
nxTransReturn = index(transformations, "transformReturn")
nxTransTry = index(transformations, "transformTry")
- nxTransThrow = index(transformations, "transformThrow")
nxTransSeqLiteral = index(transformations, "transformSeqLiteral")
nxTransTypeTree = index(transformations, "transformTypeTree")
nxTransSelectFromTypeTree = index(transformations, "transformSelectFromTypeTree")
@@ -358,7 +354,6 @@ object TreeTransforms {
nxPrepCaseDef = indexUpdate(prev.nxPrepCaseDef, changedTransformationClass, transformationIndex, "prepareForCaseDef", copy)
nxPrepReturn = indexUpdate(prev.nxPrepReturn, changedTransformationClass, transformationIndex, "prepareForReturn", copy)
nxPrepTry = indexUpdate(prev.nxPrepTry, changedTransformationClass, transformationIndex, "prepareForTry", copy)
- nxPrepThrow = indexUpdate(prev.nxPrepThrow, changedTransformationClass, transformationIndex, "prepareForThrow", copy)
nxPrepSeqLiteral = indexUpdate(prev.nxPrepSeqLiteral, changedTransformationClass, transformationIndex, "prepareForSeqLiteral", copy)
nxPrepTypeTree = indexUpdate(prev.nxPrepTypeTree, changedTransformationClass, transformationIndex, "prepareForTypeTree", copy)
nxPrepSelectFromTypeTree = indexUpdate(prev.nxPrepSelectFromTypeTree, changedTransformationClass, transformationIndex, "prepareForSelectFromTypeTree", copy)
@@ -390,7 +385,6 @@ object TreeTransforms {
nxTransCaseDef = indexUpdate(prev.nxTransCaseDef, changedTransformationClass, transformationIndex, "transformCaseDef", copy)
nxTransReturn = indexUpdate(prev.nxTransReturn, changedTransformationClass, transformationIndex, "transformReturn", copy)
nxTransTry = indexUpdate(prev.nxTransTry, changedTransformationClass, transformationIndex, "transformTry", copy)
- nxTransThrow = indexUpdate(prev.nxTransThrow, changedTransformationClass, transformationIndex, "transformThrow", copy)
nxTransSeqLiteral = indexUpdate(prev.nxTransSeqLiteral, changedTransformationClass, transformationIndex, "transformSeqLiteral", copy)
nxTransTypeTree = indexUpdate(prev.nxTransTypeTree, changedTransformationClass, transformationIndex, "transformTypeTree", copy)
nxTransSelectFromTypeTree = indexUpdate(prev.nxTransSelectFromTypeTree, changedTransformationClass, transformationIndex, "transformSelectFromTypeTree", copy)
@@ -428,7 +422,6 @@ object TreeTransforms {
var nxPrepCaseDef: Array[Int] = _
var nxPrepReturn: Array[Int] = _
var nxPrepTry: Array[Int] = _
- var nxPrepThrow: Array[Int] = _
var nxPrepSeqLiteral: Array[Int] = _
var nxPrepTypeTree: Array[Int] = _
var nxPrepSelectFromTypeTree: Array[Int] = _
@@ -461,7 +454,6 @@ object TreeTransforms {
var nxTransCaseDef: Array[Int] = _
var nxTransReturn: Array[Int] = _
var nxTransTry: Array[Int] = _
- var nxTransThrow: Array[Int] = _
var nxTransSeqLiteral: Array[Int] = _
var nxTransTypeTree: Array[Int] = _
var nxTransSelectFromTypeTree: Array[Int] = _
@@ -535,7 +527,6 @@ object TreeTransforms {
val prepForCaseDef: Mutator[CaseDef] = (trans, tree, ctx) => trans.prepareForCaseDef(tree)(ctx)
val prepForReturn: Mutator[Return] = (trans, tree, ctx) => trans.prepareForReturn(tree)(ctx)
val prepForTry: Mutator[Try] = (trans, tree, ctx) => trans.prepareForTry(tree)(ctx)
- val prepForThrow: Mutator[Throw] = (trans, tree, ctx) => trans.prepareForThrow(tree)(ctx)
val prepForSeqLiteral: Mutator[SeqLiteral] = (trans, tree, ctx) => trans.prepareForSeqLiteral(tree)(ctx)
val prepForTypeTree: Mutator[TypeTree] = (trans, tree, ctx) => trans.prepareForTypeTree(tree)(ctx)
val prepForSelectFromTypeTree: Mutator[SelectFromTypeTree] = (trans, tree, ctx) => trans.prepareForSelectFromTypeTree(tree)(ctx)
@@ -764,17 +755,6 @@ object TreeTransforms {
}
@tailrec
- final private[TreeTransforms] def goThrow(tree: Throw, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = {
- if (cur < info.transformers.length) {
- val trans = info.transformers(cur)
- trans.transformThrow(tree)(ctx.withPhase(trans.treeTransformPhase), info) match {
- case t: Throw => goThrow(t, info.nx.nxTransThrow(cur + 1))
- case t => transformSingle(t, cur + 1)
- }
- } else tree
- }
-
- @tailrec
final private[TreeTransforms] def goSeqLiteral(tree: SeqLiteral, cur: Int)(implicit ctx: Context, info: TransformerInfo): Tree = {
if (cur < info.transformers.length) {
val trans = info.transformers(cur)
@@ -943,7 +923,6 @@ object TreeTransforms {
case tree: CaseDef => goCaseDef(tree, info.nx.nxTransCaseDef(cur))
case tree: Return => goReturn(tree, info.nx.nxTransReturn(cur))
case tree: Try => goTry(tree, info.nx.nxTransTry(cur))
- case tree: Throw => goThrow(tree, info.nx.nxTransThrow(cur))
case tree: SeqLiteral => goSeqLiteral(tree, info.nx.nxTransLiteral(cur))
case tree: TypeTree => goTypeTree(tree, info.nx.nxTransTypeTree(cur))
case tree: Alternative => goAlternative(tree, info.nx.nxTransAlternative(cur))
@@ -1157,13 +1136,6 @@ object TreeTransforms {
val finalizer = transform(tree.finalizer, mutatedInfo, cur)
goTry(cpy.Try(tree)(block, cases1, finalizer), mutatedInfo.nx.nxTransTry(cur))
}
- case tree: Throw =>
- implicit val mutatedInfo: TransformerInfo = mutateTransformers(info, prepForThrow, info.nx.nxPrepThrow, tree, cur)
- if (mutatedInfo eq null) tree
- else {
- val expr = transform(tree.expr, mutatedInfo, cur)
- goThrow(cpy.Throw(tree)(expr), mutatedInfo.nx.nxTransThrow(cur))
- }
case tree: SeqLiteral =>
implicit val mutatedInfo: TransformerInfo = mutateTransformers(info, prepForSeqLiteral, info.nx.nxPrepSeqLiteral, tree, cur)
if (mutatedInfo eq null) tree
diff --git a/src/dotty/tools/dotc/typer/TypeAssigner.scala b/src/dotty/tools/dotc/typer/TypeAssigner.scala
index f4b0ef4f2..f85c3a577 100644
--- a/src/dotty/tools/dotc/typer/TypeAssigner.scala
+++ b/src/dotty/tools/dotc/typer/TypeAssigner.scala
@@ -304,9 +304,6 @@ trait TypeAssigner {
else tree.withType(ctx.typeComparer.lub(expr.tpe :: cases.tpes))
}
- def assignType(tree: untpd.Throw)(implicit ctx: Context) =
- tree.withType(defn.NothingType)
-
def assignType(tree: untpd.SeqLiteral, elems: List[Tree])(implicit ctx: Context) = tree match {
case tree: JavaSeqLiteral =>
tree.withType(defn.ArrayType(ctx.typeComparer.lub(elems.tpes).widen))
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala
index 76a9dbfdc..b3ac0f50a 100644
--- a/src/dotty/tools/dotc/typer/Typer.scala
+++ b/src/dotty/tools/dotc/typer/Typer.scala
@@ -735,9 +735,9 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
assignType(cpy.Try(tree)(expr1, cases1, finalizer1), expr1, cases1)
}
- def typedThrow(tree: untpd.Throw)(implicit ctx: Context): Throw = track("typedThrow") {
+ def typedThrow(tree: untpd.Throw)(implicit ctx: Context): Tree = track("typedThrow") {
val expr1 = typed(tree.expr, defn.ThrowableType)
- assignType(cpy.Throw(tree)(expr1))
+ Throw(expr1).withPos(tree.pos)
}
def typedSeqLiteral(tree: untpd.SeqLiteral, pt: Type)(implicit ctx: Context): SeqLiteral = track("typedSeqLiteral") {