1
votes

Given an annotated trait, how should I go about generating an abstract class which implements the trait?

So, given the following user trait...

@Neuron
trait SomeTrait {
  // ...
}

... in my library I want to insert something like the following next to it:

abstract class SomeTraitImpl extends SomeTrait

Note that I know nothing about the given trait except it's annotated with @Neuron.

I've tried to do this with ASM, implementing the concept explained in the answer to the question Using Scala traits with implemented methods in Java, but this concept scratches only the surface of what the Scala compiler emits as byte code. Even if I succeeded to master all possible combinations of var, val, lazy val, abstract override etc the odds are high that it will break with the next release of the Scala compiler.

So it looks like I should write a compile time macro instead. However, I am scratching my head over the documentation for Scala macros, so I wonder if anyone could draft something which gets me started? Any hint is appreciated, please!

1
Do you want to modify code without @Neuron annotation? So @Neuron trait SomeTrait will left unchanged, but abstract class SomeTraitImpl extends SomeTrait will be created somewhere, am I right?dveim
Yes, the original trait should be left as is, just the new SomeTraitImpl should be inserted next to it.Christian Schlichtherle
Assume that project with @Neuron trait SomeTrait was compiled separately from project with SomeTraitImpl (remember that macros work in compile-time). How would code for SomeTraitImpl be generated? Possible workaround -- use one more macro NeuronGenerator in second project, it will do it best to find @Neuron and generate ASTs. Is that possible for your case?dveim
No, it's perfectly fine to assume that @Neuron is an annotation which signals to the Scala compiler that it should evaluate some macro for the annotated trait which transforms the code into the original trait plus its implementing class. The only constraint is that my code doesn't know anything about SomeTrait other than it has the @Neuron annotation.Christian Schlichtherle

1 Answers

0
votes

The correct approach to do this is to make @Neuron a macro annotation (using the Macro Paradise compiler plugin) and implement the macro to do the code transformation. The resulting code is now part of Neuron DI, a framework for dependency injection which I wrote.