Как получить позицию диапазона из макроаннотации?

Я использую макрос аннотации к коду инструмента. Как я могу получить положение диапазона некоторых выражений?

@ScalaKata object SHA {
    val foo = "foo" 
    val bar = "bar"
    foo; bar
    // ...
}
// result: Map((75, 78) -> "foo", (80, 83) -> "bar")

Макрос инструментов:

package com.scalakata.eval

import scala.reflect.macros.blackbox.Context

import scala.language.experimental.macros
import scala.annotation.StaticAnnotation

object ScalaKataMacro {

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


    val result: Tree = {
      val eval = newTermName("eval$")
      annottees.map(_.tree).toList match {
        case q"object $name { ..$body }" :: Nil => {

          val instr = newTermName("instr$")
          implicit def lift = Liftable[c.universe.Position] { p =>
            q"(${p.start}, ${p.end})"
          }
          def instrument(rhs: Tree): Tree = {
            q"""
            {
              val t = $rhs
              ${instr}(${rhs.pos}) = t
              t
            }
            """
          }

          val bodyI = body.map {
            case ident: Ident => instrument(ident)
            case otherwise => otherwise
          }
          q"""
          object $name { 
            val $instr = scala.collection.mutable.Map.empty[(Int, Int), Any]

            def $eval() = {
              ..$bodyI
              $instr
            }
          }
          """
        }
      }
    }
    c.Expr[Any](result)
  }
}

class ScalaKata extends StaticAnnotation {
  def macroTransform(annottees: Any*) = macro ScalaKataMacro.impl
}

У меня есть опция диапазона scalacOptions += "-Yrangepos"

Я сейчас получаю только стартовую позицию: result: Map((75, 75) -> "foo", (80, 80) -> "bar")

1 ответ

Решение

В раю есть ошибка, которая искажает позиции диапазонов макро аргументов. Это исправлено в недавно опубликованном 2.1.0-SNAPSHOT.

Однако в Scala 2.11.0 и 2.11.1 есть также регрессия, которая также портит позиции диапазона. Поэтому вы сможете получить доступ к позициям диапазона в макроаннотациях только в 2.10.x или в предстоящем 2.11.2 (запланировано на конец июля).

Другие вопросы по тегам