Reputation: 627
I want to generate a type application so I can call a function like foo.bar[com.a.b.SomeType](baz)
where com.a.b.SomeType
could be any of a broad range of types. I used reflection within the macro runtime to get a reference to actual class represented by SomeType
so I can do things like get the package name, the simple name and the fully-qualified name.
When I write tq"com.a.b.SomeType"
I get the desired results, and can use interpolation in my expression, e.g.
val someType = tq"com.a.b.SomeType"
q"""
foo.bar[$someType](baz)
"""
I need to dynamically create that tq
expression using class information that I can obtain from within the macro runtime from a string. I looked at the tree generated by tq"com.example.SomeType"
and there is a series of nested Select
nodes for each of the packages com, a, b, c, which seems cumbersome to generate manually.
Select(Select(Select(Ident(TermName("com")), TermName("a")), TermName("b")), TypeName("SomeType"))
I imagine there is an easier way that I'm just not seeing.
To that end I tried things like:
tq"${someType.getPackage.getName}.${someType.getSimpleName}"
but I can see that isn't right and get errors like:
Compilation error[MyMacro.this.c.universe.Name expected but MyMacro.this.c.universe.Tree found]
So what is a concise way to achieve what I'm trying to do where the type name is only available via reflection, e.g. as an instance of Class
?
Upvotes: 0
Views: 156
Reputation: 27535
You cannot get a type from runtime reflection because this type will be used in generated code and land in binary. However, you can get the type in compile time from the call site using TypeTag
or WeakTypeTag
def myMethod[T] = macro macroImplementation
def macroImplementation[T: c.WeakTypeTag](c: Context) = {
val typeT = weakTypeOf[T].tpe
val body = q"""
foo.bar[$typeT](baz)
"""
...
}
that should let you create macros for methods with a type parameters, that you could safely fill in runtime (this typeT
will then make sure not that you are using a known type, but that you use something that comes from a type parameter and not from a thin air).
Upvotes: 1