Scala Macro - error referencing class symbol "not found: value <class>"

306 views Asked by At

I'm trying to create a Scala macro that generates code like:

val x = new com.foo.MyClass()

where com.foo.MyClass is definitely on the classpath at compile time and run time in the project using the macro.

I'm using the following c.Tree to generate the code: Apply(Select(New(Ident(TermName("com.foo.MyClass"))), termNames.CONSTRUCTOR), List())

Printing the output of the show and showRaw commands indicate that the correct code is generated, however it seems that com.foo.MyClass either isn't on the class path during macro expansion or during compilation immediately after.

I'm seeing the following error generated at the usage point of the macro (the macro impl itself is defined in a separate project):

[ERROR] /src/main/java/foo/MyWhatever.scala:10: not found: value com.foo.MyClass
[ERROR]     MyMacros.someMacro(someInput)
[ERROR]

Why is it failing to find this class on the classpath even though it's a Java file in the same project? I tried -Ymacro-debug-verbose and com.foo.MyClass isn't in the output, but a bunch of other Java & Scala classes are. I can't find a pattern to which classes are on the classpath for the Macro expansion.

Thanks for any help!

1

There are 1 answers

0
Charles Capps On

Okay! I managed to answer my own question. It turns out it works to use c.mirror.staticClass("com.foo.MyClass") to use compile-time reflection to get a class Symbol, then use Quasi-quotes.

My solution:

val classSymbol = c.mirror.staticClass("com.foo.MyClass")
val newClassTree = q"new ${classSymbol.toType}()"
c.Expr { newClassTree } // Success! This compiles and runs