Attualmente sto giocando un po 'con le macro e forse questa è una cattiva idea comunque, ma ecco il mio problema:macro Scala assegnano param della funzione decostruita
Ho la seguente macro:
def using[A <: { def close(): Unit }, B](resource: A)(f: A => B) = macro usingImpl[A, B]
def usingImpl[A <: { def close(): Unit }, B](c: Context)(resource: c.Expr[A])(f: c.Expr[A => B]): c.Expr[B] = {
import c.universe._
f.tree match {
case Function(params, body) =>
//val ValDef(modifiers, name, tpt, _) = params.head
c.Expr[B](
Block(
List(
//ValDef(modifiers, name, tpt, resource.tree)
ValDef(params.head.symbol, resource.tree)
),
body
)
)
case _: Select =>
reify {
val res = resource.splice
try {
f.splice(res)
} finally {
res.close()
}
}
}
}
In caso di Select
, richiama semplicemente la funzione e chiudo la risorsa, funziona correttamente. Ma nel caso di un Function
, vorrei assegnare il valore param alla risorsa e chiamare il corpo. Quando utilizzo il creatore deprecato di ValDef
, che accetta uno Symbol
e uno Tree
, tutto funziona correttamente. Se sto usando il creatore di 4 argomenti, ho ricevuto un errore del compilatore, affermando che il valore x$1
non rientra nell'ambito. Quando guardo il codice che entrambe le versioni producono, sembra esattamente lo stesso:
Expr[Int]({
<synthetic> val x$1: Test.Foo = new Test.this.Foo();
x$1.bar.+(23)
})
C'è forse un modo, usare semplicemente params.head
e assegnare un valore? Grazie per qualsiasi aiuto!
modificare:
io chiamo la macro in questo modo:
object Test extends App {
import Macros._
class Foo {
def close() {}
def bar = 3
}
println(using(new Foo)(_.bar + 3))
}
Come ho detto, se sto utilizzando la versione non ha commentato, mi dà un errore del compilatore, che le stampe l'AST e alla fine questo messaggio: [error] symbol value x$1 does not exist in Test$delayedInit$body.apply
E sto usando 2.10.1.
La decostruzione di 'params.head' dovrebbe funzionare perfettamente - non riesco a riprodurre il tuo errore (con 2.10.0 o 2.10.1), e in effetti ottengo un errore del compilatore con la versione non commentata. Puoi pubblicare il codice che stai utilizzando per chiamare la macro? –
aggiornato la mia domanda – drexin
Hai provato a creare distruttori in Scala? Grande idea! –