diff options
author | Martin Odersky <odersky@gmail.com> | 2013-08-08 19:21:47 +0200 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2013-08-08 19:24:18 +0200 |
commit | a326b06088d7eadde03bbcd56883b62fcfd21011 (patch) | |
tree | fabc34208e4cd5c6da7600cec46e45244586adc1 /src/dotty/tools/dotc | |
parent | 7f8ce8379296a399d29fdf9ec91210f44460f98f (diff) | |
download | dotty-a326b06088d7eadde03bbcd56883b62fcfd21011.tar.gz dotty-a326b06088d7eadde03bbcd56883b62fcfd21011.tar.bz2 dotty-a326b06088d7eadde03bbcd56883b62fcfd21011.zip |
Typing of try and throw statements.
Also issues an error on returns form methods missing a return type.
Diffstat (limited to 'src/dotty/tools/dotc')
-rw-r--r-- | src/dotty/tools/dotc/ast/Trees.scala | 20 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Typer.scala | 27 |
2 files changed, 44 insertions, 3 deletions
diff --git a/src/dotty/tools/dotc/ast/Trees.scala b/src/dotty/tools/dotc/ast/Trees.scala index fd60a100e..ab1517f9c 100644 --- a/src/dotty/tools/dotc/ast/Trees.scala +++ b/src/dotty/tools/dotc/ast/Trees.scala @@ -471,7 +471,25 @@ object Trees { type ThisTree[-T >: Untyped] = Return[T] } - /** try block catch handler finally finalizer */ + /** try block catch handler finally finalizer + * + * Note: if the handler is a case block CASES of the form + * + * { case1 ... caseN } + * + * the parser returns Match(EmptyTree, CASES). Desugaring and typing this yields a closure + * node + * + * { def $anonfun(x: Throwable) = x match CASES; Closure(Nil, $anonfun) } + * + * At some later stage when we normalize the try we can revert this to + * + * Match(EmptyTree, CASES) + * + * or else if stack is non-empty + * + * Match(EmptyTree, <case x: Throwable => $anonfun(x)>) + */ case class Try[-T >: Untyped] private[ast] (expr: Tree[T], handler: Tree[T], finalizer: Tree[T]) extends TermTree[T] { type ThisTree[-T >: Untyped] = Try[T] diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala index 554884382..1e5d0d331 100644 --- a/src/dotty/tools/dotc/typer/Typer.scala +++ b/src/dotty/tools/dotc/typer/Typer.scala @@ -491,8 +491,15 @@ class Typer extends Namer with Applications with Implicits { else cx.tree match { case ddef: DefDef => val meth = ddef.symbol - (Ident(TermRef.withSym(NoPrefix, meth.asTerm)), - if (meth.isConstructor) defn.UnitType else ddef.tpt.tpe) + val from = Ident(TermRef.withSym(NoPrefix, meth.asTerm)) + val proto = + if (meth.isConstructor) + defn.UnitType + else if (ddef.tpt.isEmpty) + errorType(s"method ${meth.show} has return statement; needs result type", tree.pos) + else + ddef.tpt.tpe + (from, proto) case _ => enclMethInfo(cx.outer) } @@ -501,6 +508,22 @@ class Typer extends Namer with Applications with Implicits { cpy.Return(tree, expr1, from) withType defn.NothingType } + def typedTry(tree: untpd.Try, pt: Type)(implicit ctx: Context): Try = { + val expr1 = typed(tree.expr, pt) + val handler1 = typed(tree.handler, defn.FunctionType(defn.ThrowableType :: Nil, pt)) + val finalizer1 = typed(tree.finalizer, defn.UnitType) + val handlerResultType = handler1.tpe match { + case defn.FunctionType(_, resultType) => resultType + case _ => defn.NothingType + } + cpy.Try(tree, expr1, handler1, finalizer1).withType(expr1.tpe | handlerResultType) + } + + def typedThrow(tree: untpd.Throw)(implicit ctx: Context): Throw = { + val expr1 = typed(tree.expr, defn.ThrowableType) + cpy.Throw(tree, expr1) withType defn.NothingType + } + def typedModifiers(mods: untpd.Modifiers)(implicit ctx: Context): Modifiers = { val annotations1 = mods.annotations mapconserve typedAnnotation if (annotations1 eq mods.annotations) mods.asInstanceOf[Modifiers] |