The reproduction uses sbt run to demo the failure. The failure is not limited to sbt run. I have another project that builds an assembly and sbt-native-packager binary. Both also exhibit the failure. Tho I can't distribute those :)
Problem
Applying one macro annotation that generates or modifies a companion object works fine. Applying two macro annotations and the companion class $.class never output. Which results in a
Caused by: java.lang.ClassNotFoundException: example.C$
at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:436)
at sbt.internal.ManagedClassLoader.findClass(ManagedClassLoader.java:103)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:588)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
... 31 more
ClassNotFoundException failure when a method on the companion class is invoked.
The expectation is that the companion class is properly output when both macros are applied.
As far as I can tell using debug-lite the result of the macros is correct: The macro either adds a companion class or adds to the companion class. The resulting expansion shown by debug lite looks correct. However, the C$.class (in this case) is not output at all.
relevant section from the debug lite output:
performing macro expansion new Foo().macroTransform(@new Bar() case class C extends scala.Product with scala.Serializable {
<caseaccessor> <paramaccessor> val name: String = _;
def <init>(name: String) = {
super.<init>();
()
}
}) at RangePosition(/home/coconnor/Development/multiple-macro-annotation-issue/src/main/scala/example/Hello.scala, 109, 109, 112)
{
@new Bar() case class C extends scala.Product with scala.Serializable {
<caseaccessor> <paramaccessor> val name: String = _;
def <init>(name: String) = {
super.<init>();
()
}
};
object C extends Fooer {
def <init>() = {
super.<init>();
()
};
<empty>;
val doFoo: String = "Foo"
};
()
}
Block(List(ClassDef(Modifiers(CASE, typeNames.EMPTY, List(Apply(Select(New(Ident(TypeName("Bar"))), termNames.CONSTRUCTOR), List()))), TypeName("C"), List(), Template(List(Select(Ident(scala), TypeName("Product")), Select(Ident(scala), TypeName("Serializable"))), noSelfType, List(ValDef(Modifiers(CASEACCESSOR | PARAMACCESSOR), TermName("name"), Ident(TypeName("String")), EmptyTree), DefDef(Modifiers(), termNames.CONSTRUCTOR, List(), List(List(ValDef(Modifiers(PARAM | PARAMACCESSOR), TermName("name"), Ident(TypeName("String")), EmptyTree))), TypeTree(), Block(List(pendingSuperCall), Literal(Constant(()))))))), ModuleDef(Modifiers(), TermName("C"), Template(List(Ident(example.macros.Fooer)), noSelfType, List(DefDef(Modifiers(), termNames.CONSTRUCTOR, List(), List(List()), TypeTree(), Block(List(pendingSuperCall), Literal(Constant(())))), EmptyTree, ValDef(Modifiers(), TermName("doFoo"), Ident(TypeName("String")), Literal(Constant("Foo"))))))), Literal(Constant(())))
performing macro expansion new Bar().macroTransform(case class C extends scala.Product with scala.Serializable {
<caseaccessor> <paramaccessor> val name: String = _;
def <init>(name: String) = {
super.<init>();
()
}
}, object C extends Fooer {
def <init>() = {
super.<init>();
()
};
val doFoo: String = "Foo"
}) at source-/home/coconnor/Development/multiple-macro-annotation-issue/src/main/scala/example/Hello.scala,line-12,offset=114
{
case class C extends scala.Product with scala.Serializable {
<caseaccessor> <paramaccessor> val name: String = _;
def <init>(name: String) = {
super.<init>();
()
}
};
object C extends Fooer with Barer {
def <init>() = {
super.<init>();
()
};
val doFoo: String = "Foo";
val doBar: String = "Bar"
};
()
}
Reproduction steps
Reproduction is in this project: https://gitlab.com/coreyoconnor/multiple-macro-annotation-issue
The reproduction uses
sbt run
to demo the failure. The failure is not limited tosbt run
. I have another project that builds an assembly and sbt-native-packager binary. Both also exhibit the failure. Tho I can't distribute those :)Problem
Applying one macro annotation that generates or modifies a companion object works fine. Applying two macro annotations and the companion class
$.class
never output. Which results in aClassNotFoundException failure when a method on the companion class is invoked.
The expectation is that the companion class is properly output when both macros are applied.
As far as I can tell using
debug-lite
the result of the macros is correct: The macro either adds a companion class or adds to the companion class. The resulting expansion shown by debug lite looks correct. However, theC$.class
(in this case) is not output at all.relevant section from the debug lite output:
Note the missing
C$.class
:Credits