Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A sample that uses method parameters? #2

Open
kostaskougios opened this issue Apr 21, 2015 · 3 comments
Open

A sample that uses method parameters? #2

kostaskougios opened this issue Apr 21, 2015 · 3 comments

Comments

@kostaskougios
Copy link

Hi, it would be nice to have a sample macro that uses method arguments,i.e. A macro that proxies all methods of a trait and calls a function passing a list of all params.

Btw nice examples and really helpful.

@davegurnell
Copy link

Hi Kostas,

Sounds like a great idea! I'll put it on the TODO list but I'm not sure
when I'll have time... PRs accepted if you're willing :)

Best regards,

Dave

On Tue, Apr 21, 2015 at 10:07 PM Kostas Kougios [email protected]
wrote:

Hi, it would be nice to have a sample macro that uses method
arguments,i.e. A macro that proxies all methods of a trait and calls a
function passing a list of all params.

Btw nice examples and really helpful.

Reply to this email directly or view it on GitHub
#2.

@kostaskougios
Copy link
Author

I am about to do that but got stuck in an issue. I can't seem to get
each method parameters to a list so that I can pass them to the proxy.
This is the last step for the proxy macro to work but didn't manage to
impl it yet. My code so far is

packagemacrotests

importscala.language.experimental.macros
importscala.reflect.macros.whitebox.Context

/**

  • A demo macro that proxies traits and calls a function for each method of a trait
    *
    *@authorkostas.kougios
    */
    objectProxyMacro
    {
    typeImplementor= (String,Any) => Any

    defproxyT:T=macroimpl[T]

    defimpl[T: c.WeakTypeTag](c: Context)(implementor: c.Expr[Implementor]): c.Expr[T] = {
    importc.universe._

    valtpe = weakTypeOf[T]

    valdecls = tpe.decls.map { decl =>
    valtermName = decl.name.toTermName
    valmethod = decl.asMethod
    valparams = method.paramLists.map(.map(s => internal.valDef(s)))
    valparamVars = method.paramLists.map(
    .map { s =>
    internal.captureVariable(s)
    internal.referenceCapturedVariable(s)
    }).flatten

      q""" def$termName  (...$params) = {
         $implementor  (${termName.toString}, ...${method.paramLists}  ).asInstanceOf[${method.returnType}]
         }"""
    

    }

    c.Expr[T] {
    q"""
    new$tpe {
    ..$decls
    }
    """
    }
    }
    }

but gives a compilation error:

Error:(32, 53) Can't unquote List[List[c.universe.Symbol]] with ...,
consider omitting the dots or providing an implicit instance of
Liftable[c.universe.Symbol]
$implementor (${termName.toString},
...${method.paramLists} ).asInstanceOf[${method.returnType}]
^

Cheers
On 22/04/15 11:07, Dave Gurnell wrote:

Hi Kostas,

Sounds like a great idea! I'll put it on the TODO list but I'm not sure
when I'll have time... PRs accepted if you're willing :)

Best regards,

Dave

On Tue, Apr 21, 2015 at 10:07 PM Kostas Kougios [email protected]
wrote:

Hi, it would be nice to have a sample macro that uses method
arguments,i.e. A macro that proxies all methods of a trait and calls a
function passing a list of all params.

Btw nice examples and really helpful.

Reply to this email directly or view it on GitHub
#2.


Reply to this email directly or view it on GitHub
#2 (comment).

@davegurnell
Copy link

Hi Kostas,

I'm not sure but you may need a List[List[ValDef]]. Here's a Stack
Overflow thread that seems to be doing something similar:

http://stackoverflow.com/questions/18559559/quasiquotes-for-multiple-parameters-and-parameter-lists

I suggest asking questions like this on Stack Overflow or the scala-macros
mailing list -- you're more likely to get a useful answer there. My
knowledge of macros is rudimentary at best -- there are plenty of people
out there who know loads more.

If you do ask elsewhere, please post a link to the question here in case
others may find it useful.

Best regards,

Dave

On Sat, Apr 25, 2015 at 7:35 PM Kostas Kougios [email protected]
wrote:

I am about to do that but got stuck in an issue. I can't seem to get
each method parameters to a list so that I can pass them to the proxy.
This is the last step for the proxy macro to work but didn't manage to
impl it yet. My code so far is

packagemacrotests

importscala.language.experimental.macros
importscala.reflect.macros.whitebox.Context

/**

  • A demo macro that proxies traits and calls a function for each method of
    a trait
    *
    *@authorkostas.kougios
    */
    objectProxyMacro
    {
    typeImplementor= (String,Any) => Any

defproxyT:T=macroimpl[T]

defimpl[T: c.WeakTypeTag](c: Context)(implementor: c.Expr[Implementor]):
c.Expr[T] = {
importc.universe._

valtpe = weakTypeOf[T]

valdecls = tpe.decls.map { decl =>
valtermName = decl.name.toTermName
valmethod = decl.asMethod
valparams = method.paramLists.map(.map(s => internal.valDef(s)))
valparamVars = method.paramLists.map(
.map { s =>
internal.captureVariable(s)
internal.referenceCapturedVariable(s)
}).flatten

q""" def$termName (...$params) = {
$implementor (${termName.toString}, ...${method.paramLists}
).asInstanceOf[${method.returnType}]
}"""
}

c.Expr[T] {
q"""
new$tpe {
..$decls
}
"""
}
}
}

but gives a compilation error:

Error:(32, 53) Can't unquote List[List[c.universe.Symbol]] with ...,
consider omitting the dots or providing an implicit instance of
Liftable[c.universe.Symbol]
$implementor (${termName.toString},
...${method.paramLists} ).asInstanceOf[${method.returnType}]
^

Cheers
On 22/04/15 11:07, Dave Gurnell wrote:

Hi Kostas,

Sounds like a great idea! I'll put it on the TODO list but I'm not sure
when I'll have time... PRs accepted if you're willing :)

Best regards,

Dave

On Tue, Apr 21, 2015 at 10:07 PM Kostas Kougios <
[email protected]>
wrote:

Hi, it would be nice to have a sample macro that uses method
arguments,i.e. A macro that proxies all methods of a trait and calls a
function passing a list of all params.

Btw nice examples and really helpful.

Reply to this email directly or view it on GitHub
#2.

Reply to this email directly or view it on GitHub
<
#2 (comment)
.

Reply to this email directly or view it on GitHub
#2 (comment)
.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants