I want to automatically generate an implementation for a trait, based
on an annotation on the trait. I have done this for the Java compiler,
and it was relatively easy. Unfortunately, I can find many example
modifying code on the fly in compiler plugins, but no example creating
completely new classes. The only thing I found was this discussion,
which does not seem to come to any clear solution:
http://www.scala-lang.org/node/1560
And I know that Paul Butcher is creating new classes, but he uses a
sbt plugin, instead of a compiler plugin. So, does anyone know of some
plugin that generate new classes directly?
In the Java compiler, generating new classes is basically the only
thing you can do in a plugin, without "cheating" by accessing the
"internal API", so I find it hard to believe that is it not possible
in a normal Scala compiler plugin.
So far, I have found how to create the new ClassDef, and add it to the
package, but then I get this Exception, which I cannot resolve:
??? base <none> not found in basetypes of type ABCEDF
error: java.util.NoSuchElementException: head of empty list
at scala.collection.immutable.Nil$.head(List.scala:371)
at scala.collection.immutable.Nil$.head(List.scala:368)
at scala.tools.nsc.transform.Erasure$ErasureTransformer$$anonfun$13$
$anon$5.parents(Erasure.scala:836)
at scala.tools.nsc.transform.OverridingPairs
$Cursor.<init>(OverridingPairs.scala:129)
at scala.tools.nsc.transform.Erasure$ErasureTransformer$$anonfun$13$
$anon$5.<init>(Erasure.scala:835)
at scala.tools.nsc.transform.Erasure$ErasureTransformer$$anonfun
$13.apply(Erasure.scala:835)
at scala.tools.nsc.transform.Erasure$ErasureTransformer$$anonfun
$13.apply(Erasure.scala:835)
at scala.tools.nsc.symtab.SymbolTable.atPhase(SymbolTable.scala:96)
at scala.tools.nsc.transform.Erasure
$ErasureTransformer.bridgeDefs(Erasure.scala:834)
at scala.tools.nsc.transform.Erasure
$ErasureTransformer.addBridges(Erasure.scala:910)
at scala.tools.nsc.transform.Erasure$ErasureTransformer$$anon
$3.preErase(Erasure.scala:1073)
at scala.tools.nsc.transform.Erasure$ErasureTransformer$$anon
$3.transform(Erasure.scala:1095)
at scala.tools.nsc.ast.Trees
$Transformer.transformTemplate(Trees.scala:875)
at scala.tools.nsc.ast.Trees$Transformer$$anonfun$transform
$2.apply(Trees.scala:767)
at scala.tools.nsc.ast.Trees$Transformer$$anonfun$transform
$2.apply(Trees.scala:766)
at scala.tools.nsc.ast.Trees$Transformer.atOwner(Trees.scala:899)
at scala.tools.nsc.transform.TypingTransformers
$TypingTransformer.atOwner(TypingTransformers.scala:38)
at scala.tools.nsc.transform.TypingTransformers
$TypingTransformer.atOwner(TypingTransformers.scala:31)
at scala.tools.nsc.ast.Trees$Transformer.transform(Trees.scala:765)
at scala.tools.nsc.transform.TypingTransformers
$TypingTransformer.transform(TypingTransformers.scala:53)
at scala.tools.nsc.transform.Erasure$ErasureTransformer$$anon
$3.transform(Erasure.scala:1104)
at scala.tools.nsc.ast.Trees$Transformer$$anonfun$transformStats
$1.apply(Trees.scala:891)
at scala.tools.nsc.ast.Trees$Transformer$$anonfun$transformStats
$1.apply(Trees.scala:889)
at scala.collection.immutable.List.loop$1(List.scala:117)
at scala.collection.immutable.List.mapConserve(List.scala:133)
at scala.tools.nsc.ast.Trees$Transformer.transformStats(Trees.scala:
889)
at scala.tools.nsc.ast.Trees$Transformer$$anonfun$transform
$1.apply(Trees.scala:761)
at scala.tools.nsc.ast.Trees$Transformer$$anonfun$transform
$1.apply(Trees.scala:761)
at scala.tools.nsc.ast.Trees$Transformer.atOwner(Trees.scala:899)
at scala.tools.nsc.transform.TypingTransformers
$TypingTransformer.atOwner(TypingTransformers.scala:38)
at scala.tools.nsc.transform.TypingTransformers
$TypingTransformer.atOwner(TypingTransformers.scala:31)
at scala.tools.nsc.ast.Trees$Transformer.transform(Trees.scala:760)
at scala.tools.nsc.transform.TypingTransformers
$TypingTransformer.scala$tools$nsc$transform$TypingTransformers
$TypingTransformer$$super$transform(TypingTransformers.scala:49)
at scala.tools.nsc.transform.TypingTransformers$TypingTransformer$
$anonfun$transform$2.apply(TypingTransformers.scala:51)
at scala.tools.nsc.transform.TypingTransformers$TypingTransformer$
$anonfun$transform$2.apply(TypingTransformers.scala:51)
at scala.tools.nsc.ast.Trees$Transformer.atOwner(Trees.scala:899)
at scala.tools.nsc.transform.TypingTransformers
$TypingTransformer.atOwner(TypingTransformers.scala:38)
at scala.tools.nsc.transform.TypingTransformers
$TypingTransformer.atOwner(TypingTransformers.scala:31)
at scala.tools.nsc.transform.TypingTransformers
$TypingTransformer.transform(TypingTransformers.scala:51)
at scala.tools.nsc.transform.Erasure$ErasureTransformer$$anon
$3.transform(Erasure.scala:1104)
at scala.tools.nsc.transform.Erasure
$ErasureTransformer.transform(Erasure.scala:1114)
at scala.tools.nsc.ast.Trees$Transformer.transformUnit(Trees.scala:
892)
at scala.tools.nsc.transform.Transform$Phase.apply(Transform.scala:
30)
at scala.tools.nsc.Global$GlobalPhase$$anonfun$applyPhase
$1.apply(Global.scala:326)
at scala.tools.nsc.Global$GlobalPhase$$anonfun$applyPhase
$1.apply(Global.scala:326)
at scala.tools.nsc.reporters.Reporter.withSource(Reporter.scala:47)
at scala.tools.nsc.Global$GlobalPhase.applyPhase(Global.scala:326)
at scala.tools.nsc.Global$GlobalPhase$$anonfun$run
$1.apply(Global.scala:294)
at scala.tools.nsc.Global$GlobalPhase$$anonfun$run
$1.apply(Global.scala:294)
at scala.collection.Iterator$class.foreach(Iterator.scala:652)
at scala.collection.mutable.ListBuffer$$anon
$1.foreach(ListBuffer.scala:311)
at scala.tools.nsc.Global$GlobalPhase.run(Global.scala:294)
at scala.tools.nsc.Global$Run.compileSources(Global.scala:949)
at scala.tools.nsc.Global$Run.compile(Global.scala:1034)
at scala.tools.nsc.Main$.process(Main.scala:106)
at scala.tools.nsc.Main$.main(Main.scala:123)
at scala.tools.nsc.Main.main(Main.scala)