Reputation: 812
Can Scala macros be used to make implementers of a method in a trait invoke the super method. For instance like this:
trait Super {
//some macro magic here: list = super.list ++ child.list
def list: List[String] = List("ein", "zwei", "DIE")
}
class Sub extends Super {
override def list: List[String] = List("4", "5")
}
object Testy extends App {
println(new Sub().list) //List(ein, zwei, DIE, 4, 5)
}
Update: See comment from @Sergey below - this is not really doable with macros.
Upvotes: 0
Views: 179
Reputation: 2900
I don't think you need macros in this particular case. In order to enforce some data from a superclass' method to be added to all results of implementing methods in any subclass, the preferred approach would be to use a template method. Make a final def
performing the addition of the fixed part and an abstract def
declaring the variable part, like so:
trait Super {
protected def additionalList: List[String]
final def list: List[String] = List("ein", "zwei", "DIE") ++ additionalList
}
class Sub extends Super {
protected val additionalList = List("4", "5")
}
object Testy extends App {
println(new Sub().list) // List(ein, zwei, DIE, 4, 5)
}
Update: If, however, you need exactly the behavior as specified in the original question, then you're out of luck, I fear: a macro can only affect what it immediately wraps, e.g. a def macro can only transform what is passed into the method, and an annotation macro can only transform its immediate annottee, be it a class, a field, a method, etc. There's no way for a macro to enforce rules on code which doesn't even know about the macro. So basically you have two options: either make your users call super
manually, or write an annotation macro and have your users annotate their subclasses with it. Both of these options are easy to omit, unfortunately.
Upvotes: 1