Closed cornerman closed 6 years ago
On the other hand, you probably don't want to create a new anonymous class when Tret
is a (non-abstract) class.
On the other hand, you probably don't want to create a new anonymous class when Tret is a (non-abstract) class.
You are right, but for an abstract class or a trait, it does not make sense.
inevitably someone will come up with the following example:
def foo = new util.Random().nextBoolean()
class C; trait T
q"new ${if (foo) typeOf[C] else typeOf[T]} { ..${List.empty[Tree]} }"
Besides, quasiquotes are untyped - they don't know the difference between a class and a trait if all they are given is a name for example.
I guess we can't have the best usability in both scenarios - it's a trade-off.
Arguably always creating the anonymous class is more precise because there are explicit brackets in the quasiquote. But there are similar syntactic constructs that wouldn't make sense anymore, e.g. type arguments: q"method[..${List.empty[Type]}]"
.
I doubt a change like this is likely to make it in since macros will be completely revamped anyway.
Good point! It just triggered an unexpected bug in my macro when generating an implementation for a type without abstract members, so I wanted to mention it here. A fix is probably not worth it given the coming deprecation of the current macro system, as you already said.
A workaround is to use List(EmptyTree)
instead of an empty list for statements.
closing all quasiquotes tickets; see #10755
In a macro, I am instantiating a trait and generate method implementations for it.
This works as expected as long as
bodyList
is non-empty. But as soon as it is empty, the generate code looks like this:q"trait Tret; new Tret()"
. This is missing the{ }
at the end, which will not compile, as a trait can only be instantiated as an anonymous class.It does not behave the same as an explicitly empty body: