From ebdeea989c940e9bf523f6054953dd7ceac123f7 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sun, 12 May 2013 15:40:22 +0200 Subject: Various fixes to trees. Try now takes a tree as catch-part (instead of a sequence of CaseDefs, which has been replaced by Match(EmptyTree, cases)). Templates now take a DefDef as constructor. Added InterpolatedString as new untyped tree constructor. --- src/dotty/tools/dotc/core/Trees.scala | 35 +++++++++++----------- src/dotty/tools/dotc/core/TypedTrees.scala | 10 +++++-- src/dotty/tools/dotc/core/UntypedTrees.scala | 3 +- src/dotty/tools/dotc/core/pickling/UnPickler.scala | 6 ++-- 4 files changed, 30 insertions(+), 24 deletions(-) diff --git a/src/dotty/tools/dotc/core/Trees.scala b/src/dotty/tools/dotc/core/Trees.scala index 96533afb7..3e09eafb7 100644 --- a/src/dotty/tools/dotc/core/Trees.scala +++ b/src/dotty/tools/dotc/core/Trees.scala @@ -91,7 +91,7 @@ object Trees { case class Modifiers[T >: Untyped] ( flags: FlagSet = EmptyFlags, privateWithin: TypeName = tpnme.EMPTY, - annotations: List[Tree[T]] = Nil) extends Positioned { + annotations: List[Tree[T]] = Nil) extends Positioned with Cloneable { def | (fs: FlagSet): Modifiers[T] = copy(flags = flags | fs) def & (fs: FlagSet): Modifiers[T] = copy(flags = flags & fs) @@ -151,7 +151,7 @@ object Trees { */ final def copyAttr(from: Tree[T]): ThisTree[T] = { _tpe = from._tpe - this.asInstanceOf[ThisTree[T]] + this.withPos(from.pos).asInstanceOf[ThisTree[T]] } /** Return a typed tree that's isomorphic to this tree, but has given @@ -422,8 +422,8 @@ object Trees { type ThisTree[T >: Untyped] = Return[T] } - /** try block catch { catches } */ - case class Try[T >: Untyped](block: Tree[T], catches: List[CaseDef[T]], finalizer: Tree[T]) + /** try block catch handler finally finalizer */ + case class Try[T >: Untyped](block: Tree[T], handler: Tree[T], finalizer: Tree[T]) extends TermTree[T] { type ThisTree[T >: Untyped] = Try[T] } @@ -445,6 +445,7 @@ object Trees { extends DenotingTree[T] with TypTree[T] { type ThisTree[T >: Untyped] = TypeTree[T] override def initialPos = NoPosition + override def isEmpty = !hasType && original.isEmpty } /** ref.type */ @@ -538,7 +539,7 @@ object Trees { } /** extends parents { self => body } */ - case class Template[T >: Untyped](constr: Tree[T], parents: List[Tree[T]], self: ValDef[T], body: List[Tree[T]]) + case class Template[T >: Untyped](constr: DefDef[T], parents: List[Tree[T]], self: ValDef[T], body: List[Tree[T]]) extends DefTree[T] { type ThisTree[T >: Untyped] = Template[T] } @@ -762,9 +763,9 @@ object Trees { case tree: Return[_] if (expr eq tree.expr) && (from eq tree.from) => tree case _ => Return(expr, from).copyAttr(tree) } - def derivedTry(block: Tree[T], catches: List[CaseDef[T]], finalizer: Tree[T]): Try[T] = tree match { - case tree: Try[_] if (block eq tree.block) && (catches eq tree.catches) && (finalizer eq tree.finalizer) => tree - case _ => Try(block, catches, finalizer).copyAttr(tree) + def derivedTry(block: Tree[T], handler: Tree[T], finalizer: Tree[T]): Try[T] = tree match { + case tree: Try[_] if (block eq tree.block) && (handler eq tree.handler) && (finalizer eq tree.finalizer) => tree + case _ => Try(block, handler, finalizer).copyAttr(tree) } def derivedThrow(expr: Tree[T]): Throw[T] = tree match { case tree: Throw[_] if (expr eq tree.expr) => tree @@ -826,7 +827,7 @@ object Trees { case tree: TypeDef[_] if (mods == tree.mods) && (name == tree.name) && (tparams eq tree.tparams) && (rhs eq tree.rhs) => tree case _ => TypeDef(mods, name, tparams, rhs).copyAttr(tree) } - def derivedTemplate(constr: Tree[T], parents: List[Tree[T]], self: ValDef[T], body: List[Tree[T]]): Template[T] = tree match { + def derivedTemplate(constr: DefDef[T], parents: List[Tree[T]], self: ValDef[T], body: List[Tree[T]]): Template[T] = tree match { case tree: Template[_] if (constr eq tree.constr) && (parents eq tree.parents) && (self eq tree.self) && (body eq tree.body) => tree case _ => Template(constr, parents, self, body).copyAttr(tree) } @@ -890,8 +891,8 @@ object Trees { finishCaseDef(tree.derivedCaseDef(transform(pat, c), transform(guard, c), transform(body, c)), tree, c, plugins) case Return(expr, from) => finishReturn(tree.derivedReturn(transform(expr, c), transform(from, c)), tree, c, plugins) - case Try(block, catches, finalizer) => - finishTry(tree.derivedTry(transform(block, c), transformSub(catches, c), transform(finalizer, c)), tree, c, plugins) + case Try(block, handler, finalizer) => + finishTry(tree.derivedTry(transform(block, c), transform(handler, c), transform(finalizer, c)), tree, c, plugins) case Throw(expr) => finishThrow(tree.derivedThrow(transform(expr, c)), tree, c, plugins) case SeqLiteral(elemtpt, elems) => @@ -925,7 +926,7 @@ object Trees { case TypeDef(mods, name, tparams, rhs) => finishTypeDef(tree.derivedTypeDef(mods, name, transformSub(tparams, c), transform(rhs, c)), tree, c, plugins) case Template(constr, parents, self, body) => - finishTemplate(tree.derivedTemplate(transform(constr, c), transform(parents, c), transformSub(self, c), transform(body, c)), tree, c, plugins) + finishTemplate(tree.derivedTemplate(transformSub(constr, c), transform(parents, c), transformSub(self, c), transform(body, c)), tree, c, plugins) case ClassDef(mods, name, tparams, impl) => finishClassDef(tree.derivedClassDef(mods, name, transformSub(tparams, c), transformSub(impl, c)), tree, c, plugins) case Import(expr, selectors) => @@ -1039,8 +1040,8 @@ object Trees { tree.derivedCaseDef(transform(pat), transform(guard), transform(body)) case Return(expr, from) => tree.derivedReturn(transform(expr), transformSub(from)) - case Try(block, catches, finalizer) => - tree.derivedTry(transform(block), transformSub(catches), transform(finalizer)) + case Try(block, handler, finalizer) => + tree.derivedTry(transform(block), transform(handler), transform(finalizer)) case Throw(expr) => tree.derivedThrow(transform(expr)) case SeqLiteral(elemtpt, elems) => @@ -1074,7 +1075,7 @@ object Trees { case TypeDef(mods, name, tparams, rhs) => tree.derivedTypeDef(mods, name, transformSub(tparams), transform(rhs)) case Template(constr, parents, self, body) => - tree.derivedTemplate(transform(constr), transform(parents), transformSub(self), transform(body)) + tree.derivedTemplate(transformSub(constr), transform(parents), transformSub(self), transform(body)) case ClassDef(mods, name, tparams, impl) => tree.derivedClassDef(mods, name, transformSub(tparams), transformSub(impl)) case Import(expr, selectors) => @@ -1141,8 +1142,8 @@ object Trees { this(this(this(x, pat), guard), body) case Return(expr, from) => this(this(x, expr), from) - case Try(block, catches, finalizer) => - this(this(this(x, block), catches), finalizer) + case Try(block, handler, finalizer) => + this(this(this(x, block), handler), finalizer) case Throw(expr) => this(x, expr) case SeqLiteral(elemtpt, elems) => diff --git a/src/dotty/tools/dotc/core/TypedTrees.scala b/src/dotty/tools/dotc/core/TypedTrees.scala index 3d2d2e93d..c349ec080 100644 --- a/src/dotty/tools/dotc/core/TypedTrees.scala +++ b/src/dotty/tools/dotc/core/TypedTrees.scala @@ -98,8 +98,8 @@ object TypedTrees { def Return(expr: Tree, from: Ident)(implicit ctx: Context): Return = Trees.Return(expr, from).withType(defn.NothingType).checked - def Try(block: Tree, catches: List[CaseDef], finalizer: Tree)(implicit ctx: Context): Try = - Trees.Try(block, catches, finalizer).withType(ctx.lub(block.tpe :: catches.map(_.tpe))).checked + def Try(block: Tree, handler: Tree, finalizer: Tree)(implicit ctx: Context): Try = + Trees.Try(block, handler, finalizer).withType(block.tpe | handler.tpe).checked def Throw(expr: Tree)(implicit ctx: Context): Throw = Trees.Throw(expr).withType(defn.NothingType).checked @@ -188,7 +188,7 @@ object TypedTrees { Trees.TypeDef(Modifiers(sym), sym.name, Nil, TypeTree(sym.info)) // !!! fill in typeParams .withType(refType(sym)).checked - def ClassDef(cls: ClassSymbol, typeParams: List[TypeSymbol], constr: Tree, body: List[Tree])(implicit ctx: Context): ClassDef = { + def ClassDef(cls: ClassSymbol, typeParams: List[TypeSymbol], constr: DefDef, body: List[Tree])(implicit ctx: Context): ClassDef = { val parents = cls.info.parents map (TypeTree(_)) val selfType = if (cls.classInfo.optSelfType.exists) ValDef(ctx.newSelfSym(cls)) @@ -448,8 +448,12 @@ object TypedTrees { case Try(block, catches, finalizer) => check(block.isTerm) check(finalizer.isTerm) + // TODO: check handler.isTerm && handler >: Throwable => Nothing ??? + /* for (ctch <- catches) check(ctch.pat.tpe.derivesFrom(defn.ThrowableClass)) + * + */ case Throw(expr) => check(expr.isValue) check(expr.tpe.derivesFrom(defn.ThrowableClass)) diff --git a/src/dotty/tools/dotc/core/UntypedTrees.scala b/src/dotty/tools/dotc/core/UntypedTrees.scala index 8cd857f95..6fa830a45 100644 --- a/src/dotty/tools/dotc/core/UntypedTrees.scala +++ b/src/dotty/tools/dotc/core/UntypedTrees.scala @@ -23,6 +23,7 @@ object UntypedTrees { /** (vparams) => body */ case class SymbolLit(str: String) extends Tree + case class InterpolatedString(id: TermName, stringParts: List[Tree], elems: List[Tree]) extends Tree case class Function(args: List[Tree], body: Tree) extends Tree case class InfixOp(left: Tree, op: Name, right: Tree) extends Tree case class PostfixOp(tree: Tree, op: Name) extends Tree @@ -62,7 +63,7 @@ object UntypedTrees { case t :: Nil => Parens(t) case _ => Tuple(ts) } - + def scalaAnyRefConstr = scalaDot(tpnme.AnyRef) def scalaAnyValConstr = scalaDot(tpnme.AnyVal) def scalaAnyConstr = scalaDot(tpnme.Any) diff --git a/src/dotty/tools/dotc/core/pickling/UnPickler.scala b/src/dotty/tools/dotc/core/pickling/UnPickler.scala index 60214465e..55c086e6f 100644 --- a/src/dotty/tools/dotc/core/pickling/UnPickler.scala +++ b/src/dotty/tools/dotc/core/pickling/UnPickler.scala @@ -903,7 +903,7 @@ class UnPickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClassRoot: setSymModsName() val impl = readTemplateRef() val tparams = until(end, readTypeDefRef) - ClassDef(symbol.asClass, tparams map (_.symbol.asType), EmptyTree, impl.body) // !!! TODO: pull out primary constructor + ClassDef(symbol.asClass, tparams map (_.symbol.asType), ???, impl.body) // !!! TODO: pull out primary constructor case MODULEtree => setSymModsName() @@ -956,7 +956,7 @@ class UnPickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClassRoot: val parents = times(readNat(), readTreeRef) val self = readValDefRef() val body = until(end, readTreeRef) - Trees.Template[Type](EmptyTree, parents, self, body) // !!! TODO: pull out primary constructor + Trees.Template[Type](???, parents, self, body) // !!! TODO: pull out primary constructor .withType(refType(symbol)) case BLOCKtree => @@ -1023,7 +1023,7 @@ class UnPickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClassRoot: val block = readTreeRef() val finalizer = readTreeRef() val catches = until(end, readCaseDefRef) - Try(block, catches, finalizer) + Try(block, Match(EmptyTree, catches), finalizer) case THROWtree => Throw(readTreeRef()) -- cgit v1.2.3