Как я могу сослаться на включение этого в макрос Scala?

Следующий макрос, извлеченный из более крупного примера, должен создать дерево, не содержащее ничего, кроме ссылки на this:

def echoThisImpl(c:Context): c.Expr[Any] = {
  import c.universe._

  val selfTree = This(c.enclosingClass.symbol)
  c.Expr[AnyRef](selfTree)
}

def echoThis: Any = macro CallMacro.echoThisImpl

Но вызов echoThis, например

object Testing extends App {
  val thisValue = CallMacro.echoThis
  println(thisValue)
}

не удается скомпилировать, с сообщением

[error] /home/rafael/dev/scala/goose/goose-macros/src/test/scala/Testing.scala:8: type mismatch;
[error]  found   : <noprefix>
[error]  required: Any
[error]   val thisValue = CallMacro.echoThis

Если я установил флаг -Ymacro-debug-lite, сгенерированное дерево будет This(newTermName("<local Testing>")).


person Rafael de F. Ferreira    schedule 18.09.2012    source источник


Ответы (1)


Есть два варианта достижения желаемого:

1) Используйте This(tpnme.EMPTY). В настоящее время это не компилируется, поэтому вам придется вместо этого использовать This(newTypeName("")), но в RC1 это будет исправлено.

2) Используйте This(c.enclosingClass.symbol.asModule.moduleClass). В настоящее время это не работает из-за https://issues.scala-lang.org/browse/SI-6394, но в RC1 это будет исправлено.

person Eugene Burmako    schedule 18.09.2012
comment
Спасибо за ответ, Евгений. Для меня этого было недостаточно. IIUC c.prefix - это выражение для дерева, которое относится к object, где определен макрос. - person Rafael de F. Ferreira; 19.09.2012
comment
(продолжение) This() принимает символ, и я думаю, что ищу символ, относящийся к классу включения макроса. Я хочу, чтобы вызов `def echoThis: Any = macro MacroImpl.echoThis` был таким же, как` def echoThis: Any = this` - person Rafael de F. Ferreira; 19.09.2012