Reputation: 1077
I have the following code:
def invokeFunction(logger: Logger, fName: String) = macro invokeFunctionImpl
//...
def invokeFunctionImpl(c: Context)(logger: c.Expr[Logger], fName: c.Expr[String]) ={
import c.universe._
// i'd like to invoke: logger.${fName}("some message")
}
Another problem I'm facing is naming a function during compile-time, using a given argument:
def createFunction(fName: String) = macro createFunctionImpl
//...
def createFunctionImpl(c: Context)(fName: c.Expr[String], param: c.Expr[String]) ={
import c.universe._
// i'd like to create: def functionNamed${fName}(param: [paramType]) = {
// implementation unimportant
}
Any help would be appreciated.
Upvotes: 0
Views: 252
Reputation: 51703
invokeFunction
should be like
def invokeFunction(logger: Logger, fName: String): Unit = macro invokeFunctionImpl
def invokeFunctionImpl(c: blackbox.Context)(logger: c.Expr[Logger], fName: c.Expr[String]): c.Expr[Unit] ={
import c.universe._
val q"${fNameStr: String}" = fName.tree
c.Expr(q"""$logger.${TermName(fNameStr)}("some message")""")
}
I added return type. I assume that fName
is a compile-time String
literal (otherwise you'll have MatchError
).
Regarding createFunction
try
def createFunction(fName: String, param: String): Unit = macro createFunctionImpl
def createFunctionImpl(c: blackbox.Context)(fName: c.Expr[String], param: c.Expr[String]): c.Expr[Unit] ={
import c.universe._
val q"${fNameStr: String}" = fName.tree
val q"${paramNameStr: String}" = param.tree
c.Expr(q"""
def ${TermName(fNameStr)}(${TermName(paramNameStr)}: ParamType) = ???
()
""")
}
Please notice that signatures of macro and its implementation must correspond to each other. So I added param
to createFunction
. And I added return type. Also it's important that a function being created will be accessible only inside the block that our macro is expanded to. New definitions is not what def macros are normally intended for (macro annotations are).
I'm not sure I understand completely what you're doing. It will be easier to answer if you provide code how you're going to use your macros.
Upvotes: 2