Каков рекомендуемый способ передачи результатов вычислений макросов во -время выполнения?

Я пытаюсь построить некоторый SQL -как абстракцию, и я столкнулся с проблемой.

Это упрощенная «таблица базы данных» :

trait Coffee {
  def id: Long
  def name: String
  def brand: String
}

. Это моя абстракция запроса:

import language.experimental.macros

object Query {  
  def from[T] = 
    macro QueryMacros.fromMacro[T]
}

class From[T] {  
  def select[S](s: T => S): Select[T] =
    macro QueryMacros.selectMacro[T, S]
}

class Select[T] {
  def where(pred: T => Boolean): Where =
    macro QueryMacros.whereMacro[T]
}

class Where(val result: String)

Это моя реализация макроса:

import scala.reflect.macros.Context

object QueryMacros {
  val result = new StringBuilder

  def fromMacro[T : c.WeakTypeTag](c: Context): c.Expr[From[T]] = { 
    result ++= ("FROM " + c.weakTypeOf[T])
    c.universe.reify(new From[T])
  }

  def selectMacro[T : c.WeakTypeTag, S : c.WeakTypeTag](c: Context)(s: c.Expr[T => S]): c.Expr[Select[T]] = {
    result ++= ("SELECT " + s.tree)
    c.universe.reify(new Select[T])
  }

  def whereMacro[S](c: Context)(pred: c.Expr[S]): c.Expr[Where] = {
    result ++= ("WHERE " + pred.tree)
    c.universe.reify(new Where(result.toString))
  }
}

И это мой пример кода:

object Main extends App {
  println("Query start")
  val query = 
    Query.from[Coffee]
        .select(_.id)
        .where(_.brand == "FairTrade")

  println(query.result)
  println("Query end")
}

Он компилируется и работает нормально, но на выходе:

Query start

Query end

По сути, resultкажется пустым. Я ожидал, что он будет содержать накопленные строки деревьев.

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

9
задан soc 12 October 2012 в 15:26
поделиться