aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2015-04-29 21:38:44 +0200
committerMartin Odersky <odersky@gmail.com>2015-05-02 19:07:38 +0200
commit959a112c6278ef06e501f117fbc3aba50f280eb7 (patch)
treec194f86f6e148e42d1ecbe319740debfcf33e23d
parenta5eb07633581962289bf6ee32c2cc7de00333cf6 (diff)
downloaddotty-959a112c6278ef06e501f117fbc3aba50f280eb7.tar.gz
dotty-959a112c6278ef06e501f117fbc3aba50f280eb7.tar.bz2
dotty-959a112c6278ef06e501f117fbc3aba50f280eb7.zip
New utility method tpd.AnonymousClass
As the name implies, this creates an anonymous class.
-rw-r--r--src/dotty/tools/dotc/ast/tpd.scala29
1 files changed, 28 insertions, 1 deletions
diff --git a/src/dotty/tools/dotc/ast/tpd.scala b/src/dotty/tools/dotc/ast/tpd.scala
index 23b964dc4..4df3f7a63 100644
--- a/src/dotty/tools/dotc/ast/tpd.scala
+++ b/src/dotty/tools/dotc/ast/tpd.scala
@@ -245,6 +245,34 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
ta.assignType(untpd.TypeDef(cls.name, impl), cls)
}
+ /** An anonymous class
+ *
+ * new parent { forwarders }
+ *
+ * where `forwarders` contains forwarders for all functions in `fns`.
+ * `fns` must be non-empty. The class has the same owner as the first function in `fns`.
+ * Its position is the union of all functions in `fns`.
+ */
+ def AnonClass(parent: Type, fns: List[TermSymbol], methNames: List[TermName])(implicit ctx: Context): Block = {
+ def methName(fnName: TermName): TermName = if (fnName == nme.ANON_FUN) nme.apply else fnName
+ val owner = fns.head.owner
+ val parents =
+ if (parent.classSymbol.is(Trait)) defn.ObjectClass.typeRef :: parent :: Nil
+ else parent :: Nil
+ val cls = ctx.newNormalizedClassSymbol(owner, tpnme.ANON_FUN, Synthetic, parents,
+ coord = fns.map(_.pos).reduceLeft(_ union _))
+ println(i"creating anon class with parent $parent -> ${cls.info.parents}%, %")
+ println(cls.classInfo.classParents)
+ val constr = ctx.newConstructor(cls, Synthetic, Nil, Nil).entered
+ def forwarder(fn: TermSymbol, name: TermName) = {
+ val fwdMeth = fn.copy(cls, name, Synthetic | Method).entered.asTerm
+ DefDef(fwdMeth, prefss => ref(fn).appliedToArgss(prefss))
+ }
+ val forwarders = (fns, methNames).zipped.map(forwarder)
+ val cdef = ClassDef(cls, DefDef(constr), forwarders)
+ Block(cdef :: Nil, New(cls.typeRef, Nil))
+ }
+
// { <label> def while$(): Unit = if (cond) { body; while$() } ; while$() }
def WhileDo(owner: Symbol, cond: Tree, body: List[Tree])(implicit ctx: Context): Tree = {
val sym = ctx.newSymbol(owner, nme.WHILE_PREFIX, Flags.Label | Flags.Synthetic,
@@ -255,7 +283,6 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
Block(List(DefDef(sym, rhs)), call)
}
-
def Import(expr: Tree, selectors: List[untpd.Tree])(implicit ctx: Context): Import =
ta.assignType(untpd.Import(expr, selectors), ctx.newImportSymbol(ctx.owner, expr))