diff --git a/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index 2e904cc23532..fee8b95a2f8f 100644 --- a/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -647,7 +647,7 @@ class DottyBackendInterface()(implicit ctx: Context) extends BackendInterface{ } def parentSymbols: List[Symbol] = toDenot(sym).info.parents.map(_.typeSymbol) def superClass: Symbol = { - val t = toDenot(sym).superClass + val t = toDenot(sym).asClass.superClass if (t.exists) t else if (sym is Flags.ModuleClass) { // workaround #371 @@ -712,7 +712,7 @@ class DottyBackendInterface()(implicit ctx: Context) extends BackendInterface{ * All interfaces implemented by a class, except for those inherited through the superclass. * */ - def superInterfaces: List[Symbol] = decorateSymbol(sym).superInterfaces + def superInterfaces: List[Symbol] = decorateSymbol(sym).directlyInheritedTraits /** * True for module classes of package level objects. The backend will generate a mirror class for diff --git a/src/dotty/tools/dotc/Compiler.scala b/src/dotty/tools/dotc/Compiler.scala index 44e7ac450e96..a9aa65201841 100644 --- a/src/dotty/tools/dotc/Compiler.scala +++ b/src/dotty/tools/dotc/Compiler.scala @@ -45,6 +45,7 @@ class Compiler { new ElimRepeated, new NormalizeFlags, new ExtensionMethods, + new ExpandSAMs, new TailRec), List(new PatternMatcher, new ExplicitOuter, diff --git a/src/dotty/tools/dotc/Run.scala b/src/dotty/tools/dotc/Run.scala index c99f5efb9167..151288d23709 100644 --- a/src/dotty/tools/dotc/Run.scala +++ b/src/dotty/tools/dotc/Run.scala @@ -33,7 +33,7 @@ class Run(comp: Compiler)(implicit ctx: Context) { compileSources(sources) } catch { case NonFatal(ex) => - println(s"exception occurred while compiling $units%, %") + println(i"exception occurred while compiling $units%, %") throw ex } diff --git a/src/dotty/tools/dotc/ast/TreeInfo.scala b/src/dotty/tools/dotc/ast/TreeInfo.scala index 6d1c04978e78..13e10105c417 100644 --- a/src/dotty/tools/dotc/ast/TreeInfo.scala +++ b/src/dotty/tools/dotc/ast/TreeInfo.scala @@ -27,7 +27,7 @@ trait TreeInfo[T >: Untyped <: Type] { self: Trees.Instance[T] => /** Does tree contain an initialization part when seen as a member of a class or trait? */ def isNoInitMember(tree: Tree): Boolean = unsplice(tree) match { - case EmptyTree | Import(_, _) | TypeDef(_, _) => true + case EmptyTree | Import(_, _) | TypeDef(_, _) | DefDef(_, _, _, _, _) => true case tree: ValDef => tree.unforcedRhs == EmptyTree case _ => false } diff --git a/src/dotty/tools/dotc/ast/tpd.scala b/src/dotty/tools/dotc/ast/tpd.scala index de0ef3344e4e..dce06da958f7 100644 --- a/src/dotty/tools/dotc/ast/tpd.scala +++ b/src/dotty/tools/dotc/ast/tpd.scala @@ -210,7 +210,8 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo { ta.assignType(untpd.TypeDef(sym.name, TypeTree(sym.info)), sym) def ClassDef(cls: ClassSymbol, constr: DefDef, body: List[Tree], superArgs: List[Tree] = Nil)(implicit ctx: Context): TypeDef = { - val firstParent :: otherParents = cls.info.parents + val firstParentRef :: otherParentRefs = cls.info.parents + val firstParent = cls.typeRef.baseTypeWithArgs(firstParentRef.symbol) val superRef = if (cls is Trait) TypeTree(firstParent) else { @@ -225,7 +226,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo { val constr = firstParent.decl(nme.CONSTRUCTOR).suchThat(constr => isApplicable(constr.info)) New(firstParent, constr.symbol.asTerm, superArgs) } - val parents = superRef :: otherParents.map(TypeTree(_)) + val parents = superRef :: otherParentRefs.map(TypeTree(_)) val selfType = if (cls.classInfo.selfInfo ne NoType) ValDef(ctx.newSelfSym(cls)) @@ -244,6 +245,33 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo { ta.assignType(untpd.TypeDef(cls.name, impl), cls) } + /** An anonymous class + * + * new parents { forwarders } + * + * where `forwarders` contains forwarders for all functions in `fns`. + * @param parents a non-empty list of class types + * @param fns a non-empty of functions for which forwarders should be defined in the class. + * The class has the same owner as the first function in `fns`. + * Its position is the union of all functions in `fns`. + */ + def AnonClass(parents: List[Type], fns: List[TermSymbol], methNames: List[TermName])(implicit ctx: Context): Block = { + val owner = fns.head.owner + val parents1 = + if (parents.head.classSymbol.is(Trait)) defn.ObjectClass.typeRef :: parents + else parents + val cls = ctx.newNormalizedClassSymbol(owner, tpnme.ANON_FUN, Synthetic, parents1, + coord = fns.map(_.pos).reduceLeft(_ union _)) + 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)) + } + // {