How do you create a new ClassDef in compiler a plugin?

67 views
Skip to first unread message

monster

unread,
Oct 22, 2011, 5:43:21 AM10/22/11
to scala-language
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)

Grzegorz Kossakowski

unread,
Oct 22, 2011, 6:24:36 AM10/22/11
to scala-l...@googlegroups.com
On 22 October 2011 11:43, monster <skunki...@googlemail.com> wrote:
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?

--
Grzegorz Kossakowski

Tymon Tobolski

unread,
Oct 22, 2011, 7:30:46 AM10/22/11
to scala-l...@googlegroups.com
You may want to look at source code of those plugins: https://github.com/gseitz/Lensedhttps://github.com/monterail/knigh

Tymon Tobolski

monster

unread,
Oct 22, 2011, 12:31:16 PM10/22/11
to scala-language

monster

unread,
Oct 22, 2011, 12:36:03 PM10/22/11
to scala-language
Thank you. I already found the snippet I needed in Grzegorz, but I
looked at knight (the t was missing from the link), and it looks like
I might learn useful things from it too.

On Oct 22, 1:30 pm, Tymon Tobolski <tymon.tobol...@monterail.com>
wrote:
Reply all
Reply to author
Forward
0 new messages