Quasiquotes упрощают многие вещи при написании макросов в Scala. Однако я заметил, что макросы, содержащие квазикокты, могут быть перекомпилированы каждый раз, когда запускается компиляция в SBT, хотя ни реализация макроса, ни какие-либо из его сайтов вызовов не были изменены и нуждаются в перекомпиляции.Избегание перекомпиляции с квазикварталами
Это, похоже, не происходит, если код в квазикварталах довольно прост, это происходит, только если есть зависимость от другого класса. Я заметил, что переписывание всего с помощью «reify», похоже, решает проблему перекомпиляции, но мне не удается переписать последнюю часть без квазикварталов ...
У меня есть следующие классы:
object ExportedFunction {
def apply[R: Manifest](f: Function0[R], fd: FunctionDescription): ExportedExcelFunction = new ExcelFunction0[R] {
def apply: R = f()
val functionDescription = fd
}
def apply[T1: Manifest, R: Manifest](f: Function1[T1, R], fd: FunctionDescription): ExportedExcelFunction = new ExcelFunction1[T1, R] {
def apply(t1: T1): R = f(t1)
val functionDescription = fd
}
... and so on... until Function17...
}
я тогда анализировать object
и экспортировать любую функцию члена с помощью описанного интерфейса следующим образом:
def export(registrar: FunctionRegistrar,
root: Object,
<...more args...>) = macro exportImpl
def exportImpl(c: Context)(registrar: c.Expr[FunctionRegistrar],
root: c.Expr[Object],
<...>): c.Expr[Any] = {
import c.universe._
<... the following is simplified ...>
root.typeSignature.members.flatMap {
case x if x.isMethod =>
val method = x.asMethod
val callee = c.Expr(method))
val desc = q"""FunctionDescription(<...result from reflective lookup...>)"""
val export = q"ExportedFunction($callee _, $desc)"
q"$registrar.+=({$export})"
я могу переписать первую и последнюю строку с но мне не удается переписать вторую строчку, мой лучший снимок с квазикварталами:
val export = reify {
...
ExportedFunction(c.Expr(q"""$callee _"""), desc)
...
}.tree
Но это приводит:
overloaded method value apply with alternatives... cannot be applied to (c.Expr[Nothing], c.universe.Expr[FunctionDescription])
Я думаю, что компилятор пропускает implicits, или, возможно, этот код будет работать только для функции с фиксированным числом аргументов, так как он должен знать, на макроуровне время компиляции хау много аргументов метод имеет? Однако он работает, если все написано с использованием квазикварталов ...
Спасибо большое за последний релиз! Он исправляет проблему ;-) – gbasler
Однако, имея макросы в проекте, увеличилось время компиляции (даже если файлы не будут перекомпилированы) от 37s до 82s в нашем проекте ... – gbasler
Не могли бы вы предоставить более подробную информацию? Было бы очень полезно увидеть проект sbt, который заработал 37 секунд, и другой проект, который теперь составляет 82s для компиляции. –