简体   繁体   中英

Scala macros invoke a compile-time determined function name

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM