scala macros error: not found: value

2019-08-07 10:57发布

问题:

I am trying to port this answer from this question to scala-2.10. This is what I tried:

Macros.scala

package myProject.macros

import scala.reflect.macros.Context
import scala.language.experimental.macros

class LoggerImpl(val c: Context) {
  import c.universe._                                                                                                                                  

  def getClassSymbol(s: Symbol): Symbol = if (s.isClass) s else getClassSymbol(s.owner)

  def logImpl(msg: Expr[String]): Unit = {
    val cl = getClassSymbol(c.enclosingClass.symbol).toString
    // Do something with cl
    // For this case cl should be "SomeObject"
  }
}

object Logger {
  def warning(msg: String): Unit = macro LoggerImpl.logImpl
}

XYZ.scala

package myProject.XYZ

import myProject.macros.Logger

object SomeObject {

  def doSomething(...) = {
    // Some operations
    Logger.warning("sss")
  }
}

But when I try to build I get these errors:

[scalac-2.10] /../Macros.scala:20: error: not found: value LoggerImpl
[scalac-2.10]   def warning(msg: String): Unit = macro LoggerImpl.logImpl
[scalac-2.10]                                            ^
[scalac-2.10] /../XYZ.scala:18: error: not found: value LoggerImpl
[scalac-2.10]   def warning(msg: String): Unit = macro LoggerImpl.logImpl
[scalac-2.10]                                            ^
[scalac-2.10] two errors found

I looked at this example, Isn't there a way to get macros working if they are in different packages?

回答1:

You could try this:

object LoggerImpl {

  def logImpl(c: Context)(msg: c.Expr[String]): c.Expr[Unit] = {
    import c.universe._                                                                                                                                  

    def getClassSymbol(s: Symbol): Symbol = if (s.isClass) s else getClassSymbol(s.owner)

    val cl = getClassSymbol(c.enclosingClass.symbol).toString
    // Do something with cl
    // For this case cl should be "SomeObject"
  }
}

Unfortunately I do not have scala 2.10 at hand, but I suppose the above should work for you, because your code does not compile for scala 2.11 either and the implementations for 10 and 11 do not seem to be to much different

Please note that you need to return c.Expr[Unit] for it to do anything, and you also need to compile it in a separate module - the last is the requirement for scala macros



标签: scala