Skip to content

Commit fb9a9e6

Browse files
oderskyDarkDimius
authored andcommitted
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.
1 parent 318db7d commit fb9a9e6

File tree

3 files changed

+101
-69
lines changed

3 files changed

+101
-69
lines changed

src/dotty/tools/dotc/transform/Erasure.scala

Lines changed: 5 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -158,27 +158,18 @@ object Erasure {
158158
cast(tree, pt)
159159
}
160160

161-
class Typer extends typer.Typer with NoChecking {
161+
class Typer extends typer.ReTyper with NoChecking {
162162
import Boxing._
163163

164-
def erasedType(tree: untpd.Tree)(implicit ctx: Context): Type =
165-
erasure(tree.tpe.asInstanceOf[Type])
164+
def erasedType(tree: untpd.Tree)(implicit ctx: Context): Type = erasure(tree.typeOpt)
166165

167-
private def promote(tree: untpd.Tree)(implicit ctx: Context): tree.ThisTree[Type] = {
166+
override def promote(tree: untpd.Tree)(implicit ctx: Context): tree.ThisTree[Type] = {
168167
assert(tree.hasType)
169168
val erased = erasedType(tree)(ctx.withPhase(ctx.erasurePhase))
170169
ctx.log(s"promoting ${tree.show}: ${erased.showWithUnderlying()}")
171170
tree.withType(erased)
172171
}
173172

174-
override def typedIdent(tree: untpd.Ident, pt: Type)(implicit ctx: Context): Tree = {
175-
val tree1 = promote(tree)
176-
tree1.tpe match {
177-
case ThisType(cls) => This(cls) withPos tree.pos
178-
case _ => tree1
179-
}
180-
}
181-
182173
/** Type check select nodes, applying the following rewritings exhaustively
183174
* on selections `e.m`.
184175
*
@@ -263,41 +254,20 @@ object Erasure {
263254
super.typedDefDef(ddef1, sym)
264255
}
265256

266-
override def typedClassDef(cdef: untpd.TypeDef, sym: ClassSymbol)(implicit ctx: Context) = {
267-
val TypeDef(mods, name, impl @ Template(constr, parents, self, body)) = cdef
268-
val cdef1 = untpd.cpy.TypeDef(cdef, mods, name,
269-
untpd.cpy.Template(impl, constr, parents, untpd.EmptyValDef, body))
270-
super.typedClassDef(cdef1, sym)
271-
}
257+
override def typedTypeDef(tdef: untpd.TypeDef, sym: Symbol)(implicit ctx: Context) =
258+
EmptyTree
272259

273260
/*
274261
override def transformStats(stats: List[Tree], exprOwner: Symbol)(implicit ctx: Context) = {
275262
val stats1 = super.transform(stats, exprOwner)
276263
if (ctx.owner.isClass) addBridges(stats1) else stats1
277264
}
278265
*/
279-
override def typedNamed(tree: untpd.NameTree, pt: Type)(implicit ctx: Context): Tree = {
280-
if (tree eq untpd.EmptyValDef) return tpd.EmptyValDef
281-
assert(tree.hasType, tree.show)
282-
val sym = tree.symbol
283-
def localContext = ctx.fresh.setTree(tree).setOwner(sym)
284-
tree match {
285-
case tree: untpd.Ident => typedIdent(tree, pt)
286-
case tree: untpd.Select => typedSelect(tree, pt)
287-
case tree: untpd.ValDef => typedValDef(tree, sym)(localContext)
288-
case tree: untpd.DefDef => typedDefDef(tree, sym)(localContext)
289-
case tree: untpd.TypeDef =>
290-
if (tree.isClassDef) typedClassDef(tree, sym.asClass)(localContext)
291-
else EmptyTree
292-
}
293-
}
294266

295267
override def adapt(tree: Tree, pt: Type)(implicit ctx: Context): Tree =
296268
ctx.traceIndented(i"adapting ${tree.showSummary}: ${tree.tpe} to $pt", show = true) {
297269
assert(ctx.phase == ctx.erasurePhase.next, ctx.phase)
298270
if (tree.isEmpty) tree else adaptToType(tree, pt)
299271
}
300-
301-
override def index(trees: List[untpd.Tree])(implicit ctx: Context) = ctx
302272
}
303273
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package dotty.tools.dotc
2+
package typer
3+
4+
import core.Contexts._
5+
import core.Types._
6+
import core.Symbols.Symbol
7+
import typer.ProtoTypes._
8+
import ast.{tpd, untpd}
9+
import ast.Trees._
10+
11+
/** A version of Typer that keeps all symbols defined and referenced in a
12+
* previously typed tree.
13+
*
14+
* All definition nodes keep their symbols. All leaf nodes for idents, selects,
15+
* and TypeTrees keep their types. Indexing is a no-op.
16+
*
17+
* Otherwise, everything is as in Typer.
18+
*/
19+
class ReTyper extends Typer {
20+
import tpd._
21+
22+
protected def promote(tree: untpd.Tree)(implicit ctx: Context): tree.ThisTree[Type] = {
23+
assert(tree.hasType)
24+
tree.withType(tree.typeOpt)
25+
}
26+
27+
override def typedIdent(tree: untpd.Ident, pt: Type)(implicit ctx: Context): Tree =
28+
promote(tree)
29+
30+
override def typedSelect(tree: untpd.Select, pt: Type)(implicit ctx: Context): Tree = {
31+
assert(tree.hasType)
32+
val qual1 = typed(tree.qualifier, AnySelectionProto)
33+
untpd.cpy.Select(tree, qual1, tree.name).withType(tree.typeOpt)
34+
}
35+
36+
override def typedSelectFromTypeTree(tree: untpd.SelectFromTypeTree, pt: Type)(implicit ctx: Context): SelectFromTypeTree = {
37+
assert(tree.hasType)
38+
val qual1 = typed(tree.qualifier, AnySelectionProto)
39+
untpd.cpy.SelectFromTypeTree(tree, qual1, tree.name).withType(tree.typeOpt)
40+
}
41+
42+
override def typedTypeTree(tree: untpd.TypeTree, pt: Type)(implicit ctx: Context): TypeTree =
43+
promote(tree)
44+
45+
override def typedBind(tree: untpd.Bind, pt: Type)(implicit ctx: Context): Bind = {
46+
assert(tree.hasType)
47+
val body1 = typed(tree.body, pt)
48+
untpd.cpy.Bind(tree, tree.name, body1).withType(tree.typeOpt)
49+
}
50+
51+
override def retrieveSym(tree: untpd.Tree)(implicit ctx: Context): Symbol = tree.symbol
52+
53+
override def localTyper(sym: Symbol) = this
54+
55+
override def index(trees: List[untpd.Tree])(implicit ctx: Context) = ctx
56+
}

src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 40 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -775,7 +775,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
775775
//todo: make sure dependent method types do not depend on implicits or by-name params
776776
}
777777

778-
def typedTypeDef(tdef: untpd.TypeDef, sym: Symbol)(implicit ctx: Context): TypeDef = track("typedTypeDef") {
778+
def typedTypeDef(tdef: untpd.TypeDef, sym: Symbol)(implicit ctx: Context): Tree = track("typedTypeDef") {
779779
val TypeDef(mods, name, rhs) = tdef
780780
val mods1 = typedModifiers(mods)
781781
val _ = typedType(rhs) // unused, typecheck only to remove from typedTree
@@ -858,47 +858,53 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
858858
def typedAsFunction(tree: untpd.Tree, pt: Type)(implicit ctx: Context): Tree =
859859
typed(tree, if (defn.isFunctionType(pt)) pt else AnyFunctionProto)
860860

861-
def typedNamed(xtree: untpd.NameTree, pt: Type)(implicit ctx: Context): Tree = {
862-
val tree = xtree withName xtree.name.encode
863-
val sym = xtree.removeAttachment(SymOfTree) match {
864-
case Some(sym) =>
865-
sym.ensureCompleted()
866-
sym
867-
case none =>
868-
NoSymbol
869-
}
870-
871-
def localContext = {
872-
val freshCtx = ctx.fresh.setTree(xtree)
873-
if (sym.exists) freshCtx.setOwner(sym)
874-
else freshCtx // can happen for self defs
875-
}
861+
/** Retrieve symbol attached to given tree */
862+
protected def retrieveSym(tree: untpd.Tree)(implicit ctx: Context) = tree.removeAttachment(SymOfTree) match {
863+
case Some(sym) =>
864+
sym.ensureCompleted()
865+
sym
866+
case none =>
867+
NoSymbol
868+
}
876869

877-
tree match {
878-
case tree: untpd.Ident => typedIdent(tree, pt)
879-
case tree: untpd.Select => typedSelect(tree, pt)
880-
case tree: untpd.SelectFromTypeTree => typedSelectFromTypeTree(tree, pt)
881-
case tree: untpd.Bind => typedBind(tree, pt)
882-
case tree: untpd.ValDef =>
883-
if (tree.isEmpty) tpd.EmptyValDef
884-
else typedValDef(tree, sym)(localContext.setNewScope)
885-
case tree: untpd.DefDef =>
886-
val typer1 = nestedTyper.remove(sym).get
887-
typer1.typedDefDef(tree, sym)(localContext.setTyper(typer1))
888-
case tree: untpd.TypeDef =>
889-
if (tree.isClassDef) typedClassDef(tree, sym.asClass)(localContext)
890-
else typedTypeDef(tree, sym)(localContext.setNewScope)
891-
case _ => typedUnadapted(desugar(tree), pt)
892-
}
870+
/** A fresh local context with given tree and owner.
871+
* Owner might not exist (can happen for self valdefs), in which case
872+
* no owner is set in result context
873+
*/
874+
protected def localContext(tree: untpd.Tree, owner: Symbol)(implicit ctx: Context): FreshContext = {
875+
val freshCtx = ctx.fresh.setTree(tree)
876+
if (owner.exists) freshCtx.setOwner(owner) else freshCtx
893877
}
894878

879+
protected def localTyper(sym: Symbol): Typer = nestedTyper.remove(sym).get
880+
895881
def typedUnadapted(initTree: untpd.Tree, pt: Type = WildcardType)(implicit ctx: Context): Tree = {
896882
record("typedUnadapted")
897883
val xtree = expanded(initTree)
898884
xtree.removeAttachment(TypedAhead) match {
899885
case Some(ttree) => ttree
900886
case none =>
901887

888+
def typedNamed(tree: untpd.NameTree, pt: Type)(implicit ctx: Context): Tree = {
889+
val sym = retrieveSym(xtree)
890+
tree match {
891+
case tree: untpd.Ident => typedIdent(tree, pt)
892+
case tree: untpd.Select => typedSelect(tree, pt)
893+
case tree: untpd.SelectFromTypeTree => typedSelectFromTypeTree(tree, pt)
894+
case tree: untpd.Bind => typedBind(tree, pt)
895+
case tree: untpd.ValDef =>
896+
if (tree.isEmpty) tpd.EmptyValDef
897+
else typedValDef(tree, sym)(localContext(tree, sym).setNewScope)
898+
case tree: untpd.DefDef =>
899+
val typer1 = localTyper(sym)
900+
typer1.typedDefDef(tree, sym)(localContext(tree, sym).setTyper(typer1))
901+
case tree: untpd.TypeDef =>
902+
if (tree.isClassDef) typedClassDef(tree, sym.asClass)(localContext(tree, sym))
903+
else typedTypeDef(tree, sym)(localContext(tree, sym).setNewScope)
904+
case _ => typedUnadapted(desugar(tree), pt)
905+
}
906+
}
907+
902908
def typedUnnamed(tree: untpd.Tree): Tree = tree match {
903909
case tree: untpd.Apply =>
904910
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
938944
}
939945

940946
xtree match {
941-
case xtree: untpd.NameTree => typedNamed(xtree, pt)
942-
case xtree: untpd.Import => typedImport(xtree, xtree.removeAttachment(SymOfTree).get)
947+
case xtree: untpd.NameTree => typedNamed(xtree withName xtree.name.encode, pt)
948+
case xtree: untpd.Import => typedImport(xtree, retrieveSym(xtree))
943949
case xtree => typedUnnamed(xtree)
944950
}
945951
}

0 commit comments

Comments
 (0)