A non-approving macro dude is one of the main use cases that you implement to learn how to use macros?
Well, that’s what I thought too.
By "glean snippets" in my other answer, I meant what specs2 does in its macro s2 .
, , rip-off .
, REPL, . , , , .
?
, -Yrangepos, .
, , .
(, paulp, vox paulpuli) , , ", ", , , , , , .
, p . , , , , , , .
, showCode , 10 < 5 false, .
object X {
import reflect.macros.blackbox.Context
def impl[A: c.WeakTypeTag](c: Context)(p: c.Expr[Boolean])(body: c.Expr[A]) = {
import c.universe._
def treeLine(t: Tree): String = lineAt(t.pos)
def lineAt(pos: Position): String = if (pos.isRange) pos.lineContent.drop(pos.column - 1).take(pos.end - pos.start + 1) else "???"
val msg =
if (p.tree.pos.isRange) {
treeLine(p.tree)
} else {
showCode(p.tree)
}
q"require($p, $msg) ; $body"
}
def x[A](p: Boolean)(body: =>A): A = macro X.impl[A]
}
, :
object X {
import reflect.macros.blackbox.Context
def impl(c: Context)(p: c.Expr[Boolean]) = {
import c.universe._
def lineAt(pos: Position): String = if (pos.isRange) pos.lineContent.drop(pos.column - 1).take(pos.end - pos.start + 1) else "???"
val msg = lineAt(c.macroApplication.pos) // oh, joy
q"require($p, $msg) ; new { def apply[A](body: =>A): A = body }"
}
def x(p: Boolean): { def apply[A](body: =>A): A } = macro X.impl
}
x(10 < 5)(println("hi")): requirement failed: (10 < 5)(p. .