aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2014-03-30 16:31:01 +0200
committerDmitry Petrashko <dmitry.petrashko@gmail.com>2014-03-31 14:53:52 +0200
commitfb9a9e65c941a7b840baaa32641818d32b45b5b7 (patch)
tree0026788e85913e88d51eb00a6596d6733447d52e /src
parent318db7dc616a659687d95380efa16159cfaeb984 (diff)
downloaddotty-fb9a9e65c941a7b840baaa32641818d32b45b5b7.tar.gz
dotty-fb9a9e65c941a7b840baaa32641818d32b45b5b7.tar.bz2
dotty-fb9a9e65c941a7b840baaa32641818d32b45b5b7.zip
Factored re-typing logic into seperate ReTyper class
Refactored re-typing logic from erasure into seperate ReTyper class. Another candidate subclass of ReTyper is a future TreeChecker.
Diffstat (limited to 'src')
-rw-r--r--src/dotty/tools/dotc/transform/Erasure.scala40
-rw-r--r--src/dotty/tools/dotc/typer/ReTyper.scala56
-rw-r--r--src/dotty/tools/dotc/typer/Typer.scala74
3 files changed, 101 insertions, 69 deletions
diff --git a/src/dotty/tools/dotc/transform/Erasure.scala b/src/dotty/tools/dotc/transform/Erasure.scala
index b403d4e66..d4156e1d7 100644
--- a/src/dotty/tools/dotc/transform/Erasure.scala
+++ b/src/dotty/tools/dotc/transform/Erasure.scala
@@ -158,27 +158,18 @@ object Erasure {
cast(tree, pt)
}
- class Typer extends typer.Typer with NoChecking {
+ class Typer extends typer.ReTyper with NoChecking {
import Boxing._
- def erasedType(tree: untpd.Tree)(implicit ctx: Context): Type =
- erasure(tree.tpe.asInstanceOf[Type])
+ def erasedType(tree: untpd.Tree)(implicit ctx: Context): Type = erasure(tree.typeOpt)
- private def promote(tree: untpd.Tree)(implicit ctx: Context): tree.ThisTree[Type] = {
+ override def promote(tree: untpd.Tree)(implicit ctx: Context): tree.ThisTree[Type] = {
assert(tree.hasType)
val erased = erasedType(tree)(ctx.withPhase(ctx.erasurePhase))
ctx.log(s"promoting ${tree.show}: ${erased.showWithUnderlying()}")
tree.withType(erased)
}
- override def typedIdent(tree: untpd.Ident, pt: Type)(implicit ctx: Context): Tree = {
- val tree1 = promote(tree)
- tree1.tpe match {
- case ThisType(cls) => This(cls) withPos tree.pos
- case _ => tree1
- }
- }
-
/** Type check select nodes, applying the following rewritings exhaustively
* on selections `e.m`.
*
@@ -263,12 +254,8 @@ object Erasure {
super.typedDefDef(ddef1, sym)
}
- override def typedClassDef(cdef: untpd.TypeDef, sym: ClassSymbol)(implicit ctx: Context) = {
- val TypeDef(mods, name, impl @ Template(constr, parents, self, body)) = cdef
- val cdef1 = untpd.cpy.TypeDef(cdef, mods, name,
- untpd.cpy.Template(impl, constr, parents, untpd.EmptyValDef, body))
- super.typedClassDef(cdef1, sym)
- }
+ override def typedTypeDef(tdef: untpd.TypeDef, sym: Symbol)(implicit ctx: Context) =
+ EmptyTree
/*
override def transformStats(stats: List[Tree], exprOwner: Symbol)(implicit ctx: Context) = {
@@ -276,28 +263,11 @@ object Erasure {
if (ctx.owner.isClass) addBridges(stats1) else stats1
}
*/
- override def typedNamed(tree: untpd.NameTree, pt: Type)(implicit ctx: Context): Tree = {
- if (tree eq untpd.EmptyValDef) return tpd.EmptyValDef
- assert(tree.hasType, tree.show)
- val sym = tree.symbol
- def localContext = ctx.fresh.setTree(tree).setOwner(sym)
- tree match {
- case tree: untpd.Ident => typedIdent(tree, pt)
- case tree: untpd.Select => typedSelect(tree, pt)
- case tree: untpd.ValDef => typedValDef(tree, sym)(localContext)
- case tree: untpd.DefDef => typedDefDef(tree, sym)(localContext)
- case tree: untpd.TypeDef =>
- if (tree.isClassDef) typedClassDef(tree, sym.asClass)(localContext)
- else EmptyTree
- }
- }
override def adapt(tree: Tree, pt: Type)(implicit ctx: Context): Tree =
ctx.traceIndented(i"adapting ${tree.showSummary}: ${tree.tpe} to $pt", show = true) {
assert(ctx.phase == ctx.erasurePhase.next, ctx.phase)
if (tree.isEmpty) tree else adaptToType(tree, pt)
}
-
- override def index(trees: List[untpd.Tree])(implicit ctx: Context) = ctx
}
} \ No newline at end of file
diff --git a/src/dotty/tools/dotc/typer/ReTyper.scala b/src/dotty/tools/dotc/typer/ReTyper.scala
new file mode 100644
index 000000000..896dbba7d
--- /dev/null
+++ b/src/dotty/tools/dotc/typer/ReTyper.scala
@@ -0,0 +1,56 @@
+package dotty.tools.dotc
+package typer
+
+import core.Contexts._
+import core.Types._
+import core.Symbols.Symbol
+import typer.ProtoTypes._
+import ast.{tpd, untpd}
+import ast.Trees._
+
+/** A version of Typer that keeps all symbols defined and referenced in a
+ * previously typed tree.
+ *
+ * All definition nodes keep their symbols. All leaf nodes for idents, selects,
+ * and TypeTrees keep their types. Indexing is a no-op.
+ *
+ * Otherwise, everything is as in Typer.
+ */
+class ReTyper extends Typer {
+ import tpd._
+
+ protected def promote(tree: untpd.Tree)(implicit ctx: Context): tree.ThisTree[Type] = {
+ assert(tree.hasType)
+ tree.withType(tree.typeOpt)
+ }
+
+ override def typedIdent(tree: untpd.Ident, pt: Type)(implicit ctx: Context): Tree =
+ promote(tree)
+
+ override def typedSelect(tree: untpd.Select, pt: Type)(implicit ctx: Context): Tree = {
+ assert(tree.hasType)
+ val qual1 = typed(tree.qualifier, AnySelectionProto)
+ untpd.cpy.Select(tree, qual1, tree.name).withType(tree.typeOpt)
+ }
+
+ override def typedSelectFromTypeTree(tree: untpd.SelectFromTypeTree, pt: Type)(implicit ctx: Context): SelectFromTypeTree = {
+ assert(tree.hasType)
+ val qual1 = typed(tree.qualifier, AnySelectionProto)
+ untpd.cpy.SelectFromTypeTree(tree, qual1, tree.name).withType(tree.typeOpt)
+ }
+
+ override def typedTypeTree(tree: untpd.TypeTree, pt: Type)(implicit ctx: Context): TypeTree =
+ promote(tree)
+
+ override def typedBind(tree: untpd.Bind, pt: Type)(implicit ctx: Context): Bind = {
+ assert(tree.hasType)
+ val body1 = typed(tree.body, pt)
+ untpd.cpy.Bind(tree, tree.name, body1).withType(tree.typeOpt)
+ }
+
+ override def retrieveSym(tree: untpd.Tree)(implicit ctx: Context): Symbol = tree.symbol
+
+ override def localTyper(sym: Symbol) = this
+
+ override def index(trees: List[untpd.Tree])(implicit ctx: Context) = ctx
+} \ No newline at end of file
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala
index b72cd0fa8..c2488f68c 100644
--- a/src/dotty/tools/dotc/typer/Typer.scala
+++ b/src/dotty/tools/dotc/typer/Typer.scala
@@ -775,7 +775,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
//todo: make sure dependent method types do not depend on implicits or by-name params
}
- def typedTypeDef(tdef: untpd.TypeDef, sym: Symbol)(implicit ctx: Context): TypeDef = track("typedTypeDef") {
+ def typedTypeDef(tdef: untpd.TypeDef, sym: Symbol)(implicit ctx: Context): Tree = track("typedTypeDef") {
val TypeDef(mods, name, rhs) = tdef
val mods1 = typedModifiers(mods)
val _ = typedType(rhs) // unused, typecheck only to remove from typedTree
@@ -858,40 +858,26 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
def typedAsFunction(tree: untpd.Tree, pt: Type)(implicit ctx: Context): Tree =
typed(tree, if (defn.isFunctionType(pt)) pt else AnyFunctionProto)
- def typedNamed(xtree: untpd.NameTree, pt: Type)(implicit ctx: Context): Tree = {
- val tree = xtree withName xtree.name.encode
- val sym = xtree.removeAttachment(SymOfTree) match {
- case Some(sym) =>
- sym.ensureCompleted()
- sym
- case none =>
- NoSymbol
- }
-
- def localContext = {
- val freshCtx = ctx.fresh.setTree(xtree)
- if (sym.exists) freshCtx.setOwner(sym)
- else freshCtx // can happen for self defs
- }
+ /** Retrieve symbol attached to given tree */
+ protected def retrieveSym(tree: untpd.Tree)(implicit ctx: Context) = tree.removeAttachment(SymOfTree) match {
+ case Some(sym) =>
+ sym.ensureCompleted()
+ sym
+ case none =>
+ NoSymbol
+ }
- tree match {
- case tree: untpd.Ident => typedIdent(tree, pt)
- case tree: untpd.Select => typedSelect(tree, pt)
- case tree: untpd.SelectFromTypeTree => typedSelectFromTypeTree(tree, pt)
- case tree: untpd.Bind => typedBind(tree, pt)
- case tree: untpd.ValDef =>
- if (tree.isEmpty) tpd.EmptyValDef
- else typedValDef(tree, sym)(localContext.setNewScope)
- case tree: untpd.DefDef =>
- val typer1 = nestedTyper.remove(sym).get
- typer1.typedDefDef(tree, sym)(localContext.setTyper(typer1))
- case tree: untpd.TypeDef =>
- if (tree.isClassDef) typedClassDef(tree, sym.asClass)(localContext)
- else typedTypeDef(tree, sym)(localContext.setNewScope)
- case _ => typedUnadapted(desugar(tree), pt)
- }
+ /** A fresh local context with given tree and owner.
+ * Owner might not exist (can happen for self valdefs), in which case
+ * no owner is set in result context
+ */
+ protected def localContext(tree: untpd.Tree, owner: Symbol)(implicit ctx: Context): FreshContext = {
+ val freshCtx = ctx.fresh.setTree(tree)
+ if (owner.exists) freshCtx.setOwner(owner) else freshCtx
}
+ protected def localTyper(sym: Symbol): Typer = nestedTyper.remove(sym).get
+
def typedUnadapted(initTree: untpd.Tree, pt: Type = WildcardType)(implicit ctx: Context): Tree = {
record("typedUnadapted")
val xtree = expanded(initTree)
@@ -899,6 +885,26 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
case Some(ttree) => ttree
case none =>
+ def typedNamed(tree: untpd.NameTree, pt: Type)(implicit ctx: Context): Tree = {
+ val sym = retrieveSym(xtree)
+ tree match {
+ case tree: untpd.Ident => typedIdent(tree, pt)
+ case tree: untpd.Select => typedSelect(tree, pt)
+ case tree: untpd.SelectFromTypeTree => typedSelectFromTypeTree(tree, pt)
+ case tree: untpd.Bind => typedBind(tree, pt)
+ case tree: untpd.ValDef =>
+ if (tree.isEmpty) tpd.EmptyValDef
+ else typedValDef(tree, sym)(localContext(tree, sym).setNewScope)
+ case tree: untpd.DefDef =>
+ val typer1 = localTyper(sym)
+ typer1.typedDefDef(tree, sym)(localContext(tree, sym).setTyper(typer1))
+ case tree: untpd.TypeDef =>
+ if (tree.isClassDef) typedClassDef(tree, sym.asClass)(localContext(tree, sym))
+ else typedTypeDef(tree, sym)(localContext(tree, sym).setNewScope)
+ case _ => typedUnadapted(desugar(tree), pt)
+ }
+ }
+
def typedUnnamed(tree: untpd.Tree): Tree = tree match {
case tree: untpd.Apply =>
if (ctx.mode is Mode.Pattern) typedUnApply(tree, pt) else typedApply(tree, pt)
@@ -938,8 +944,8 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
}
xtree match {
- case xtree: untpd.NameTree => typedNamed(xtree, pt)
- case xtree: untpd.Import => typedImport(xtree, xtree.removeAttachment(SymOfTree).get)
+ case xtree: untpd.NameTree => typedNamed(xtree withName xtree.name.encode, pt)
+ case xtree: untpd.Import => typedImport(xtree, retrieveSym(xtree))
case xtree => typedUnnamed(xtree)
}
}