aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/ast/tpd.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2014-05-05 15:05:02 +0200
committerDmitry Petrashko <dmitry.petrashko@gmail.com>2014-05-08 21:51:48 +0200
commit8baa5de7e7ee01b6d47924a293de746379271f08 (patch)
treedfe05f3c1ee3669d49ae6c84a7c1b2f9a17493a5 /src/dotty/tools/dotc/ast/tpd.scala
parent9a251994b59bdcfc3acfb4d8b22aaee359724e6b (diff)
downloaddotty-8baa5de7e7ee01b6d47924a293de746379271f08.tar.gz
dotty-8baa5de7e7ee01b6d47924a293de746379271f08.tar.bz2
dotty-8baa5de7e7ee01b6d47924a293de746379271f08.zip
Fixing tpd.ClassDef.
The superclass comnstructor of a ClassDef is supposed to be a constructor call. The fix ensures this is the case when creating classes with tpd.ClassDef.
Diffstat (limited to 'src/dotty/tools/dotc/ast/tpd.scala')
-rw-r--r--src/dotty/tools/dotc/ast/tpd.scala29
1 files changed, 24 insertions, 5 deletions
diff --git a/src/dotty/tools/dotc/ast/tpd.scala b/src/dotty/tools/dotc/ast/tpd.scala
index e9775f1dc..3b240ad2c 100644
--- a/src/dotty/tools/dotc/ast/tpd.scala
+++ b/src/dotty/tools/dotc/ast/tpd.scala
@@ -210,8 +210,24 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
def TypeDef(sym: TypeSymbol)(implicit ctx: Context): TypeDef =
ta.assignType(untpd.TypeDef(Modifiers(sym), sym.name, TypeTree(sym.info)), sym)
- def ClassDef(cls: ClassSymbol, constr: DefDef, body: List[Tree])(implicit ctx: Context): TypeDef = {
- val parents = cls.info.parents map (TypeTree(_))
+ def ClassDef(cls: ClassSymbol, constr: DefDef, body: List[Tree], superArgs: List[Tree] = Nil)(implicit ctx: Context): TypeDef = {
+ val firstParent :: otherParents = cls.info.parents
+ val superRef =
+ if (cls is Trait) TypeTree(firstParent)
+ else {
+ def isApplicable(ctpe: Type): Boolean = ctpe match {
+ case ctpe: PolyType =>
+ isApplicable(ctpe.instantiate(firstParent.argTypes))
+ case ctpe: MethodType =>
+ (superArgs corresponds ctpe.paramTypes)(_.tpe <:< _)
+ case _ =>
+ false
+ }
+ val constr = firstParent.decl(nme.CONSTRUCTOR).suchThat(constr => isApplicable(constr.info))
+ New(firstParent, constr.symbol.asTerm, superArgs)
+ }
+ val parents = superRef :: otherParents.map(TypeTree(_))
+
val selfType =
if (cls.classInfo.selfInfo ne NoType) ValDef(ctx.newSelfSym(cls))
else EmptyValDef
@@ -260,10 +276,13 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
// ------ Creating typed equivalents of trees that exist only in untyped form -------
- /** new C(args) */
- def New(tp: Type, args: List[Tree])(implicit ctx: Context): Apply = {
+ /** new C(args), calling the primary constructor of C */
+ def New(tp: Type, args: List[Tree])(implicit ctx: Context): Apply =
+ New(tp, tp.typeSymbol.primaryConstructor.asTerm, args)
+
+ /** new C(args), calling given constructor `constr` of C */
+ def New(tp: Type, constr: TermSymbol, args: List[Tree])(implicit ctx: Context): Apply = {
val targs = tp.argTypes
- val constr = tp.typeSymbol.primaryConstructor.asTerm
Apply(
Select(
New(tp withoutArgs targs),