I'm trying to answer this question.
Instead of writing:
case class Person(name: String, age: Int) {
def this() = this("",1)
}
I thought I'd use macro annotations to expand it from:
@Annotation
case class Person(name: String, age: Int)
So I tried adding the new constructor as a plain-old DefDef
using quasiquotes in a macro annotation's impl, like:
val newCtor = q"""def this() = this("", 1)"""
val newBody = body :+ newCtor
q"$mods class $name[..$tparams](..$first)(...$rest) extends ..$parents { $self => ..$newBody }"
But that returns an error: called constructor's definition must precede calling constructor's definition
Is there a way to fix that? What did I miss?
Thanks for taking a look, -Julian
It turns out that a very natural intent to generate a secondary constructor in a macro annotation has exposed two different issues.
1) The first issue (https://issues.scala-lang.org/browse/SI-8451) is about quasiquotes emitting wrong tree shapes for secondary constructors. That was fixed in 2.11.0-RC4 (yet to be released, currently available as 2.11.0-SNAPSHOT) and in paradise 2.0.0-M6 for 2.10.x (released yesterday).
2) The second issue is about unassigned positions wreaking havoc during typechecker. Curiously enough, when typechecking calls to constructors, typer uses positions in order to decide whether these calls are legal or not. That can't be patched that easily, and we have to work around: