Return-Path: X-Original-To: apmail-groovy-users-archive@minotaur.apache.org Delivered-To: apmail-groovy-users-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 58E0118546 for ; Sat, 22 Aug 2015 08:22:10 +0000 (UTC) Received: (qmail 228 invoked by uid 500); 22 Aug 2015 08:22:10 -0000 Delivered-To: apmail-groovy-users-archive@groovy.apache.org Received: (qmail 193 invoked by uid 500); 22 Aug 2015 08:22:10 -0000 Mailing-List: contact users-help@groovy.incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: users@groovy.incubator.apache.org Delivered-To: mailing list users@groovy.incubator.apache.org Received: (qmail 183 invoked by uid 99); 22 Aug 2015 08:22:10 -0000 Received: from Unknown (HELO spamd4-us-west.apache.org) (209.188.14.142) by apache.org (qpsmtpd/0.29) with ESMTP; Sat, 22 Aug 2015 08:22:10 +0000 Received: from localhost (localhost [127.0.0.1]) by spamd4-us-west.apache.org (ASF Mail Server at spamd4-us-west.apache.org) with ESMTP id AF144C0041 for ; Sat, 22 Aug 2015 08:22:09 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at spamd4-us-west.apache.org X-Spam-Flag: NO X-Spam-Score: 2.9 X-Spam-Level: ** X-Spam-Status: No, score=2.9 tagged_above=-999 required=6.31 tests=[DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HTML_MESSAGE=3] autolearn=disabled Authentication-Results: spamd4-us-west.apache.org (amavisd-new); dkim=pass (2048-bit key) header.d=gmail.com Received: from mx1-us-east.apache.org ([10.40.0.8]) by localhost (spamd4-us-west.apache.org [10.40.0.11]) (amavisd-new, port 10024) with ESMTP id qvakxYDc4D99 for ; Sat, 22 Aug 2015 08:21:54 +0000 (UTC) Received: from mail-lb0-f178.google.com (mail-lb0-f178.google.com [209.85.217.178]) by mx1-us-east.apache.org (ASF Mail Server at mx1-us-east.apache.org) with ESMTPS id 1589050939 for ; Sat, 22 Aug 2015 08:06:51 +0000 (UTC) Received: by lbbsx3 with SMTP id sx3so55678299lbb.0 for ; Sat, 22 Aug 2015 01:06:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :content-type; bh=PVh/Lgh78Kd9DdO+W1ZyhUf5NhD3+zjICmp0z8AgfV8=; b=mWiZstj3DVsZwxqH8mWm6VK9ri2llmOo4WuTmclTccFkhpHkOZILnAXPU+8NjPmv4d lsMjgfst+lrNHFQ+yHGUcbnKXwMs1SS4BUvMJH4wPEDUw+5P3F0osYdtkwxytp0MNsxg ctJlyWvPGR94mYj5VOEAwktco4eGlfC47Q0Q+WyMmN+XqzZOs5RdjsI7CMkOWkpl9mDZ r2b/RtV79t5sZrlIx99QL8/m6RncCIocRZlrHg1uKj0wRPVF0dgCOmAwQv35UupKfsXT 1drbbU+E5LpiB/1mi05jj0IaHNsoM0b9R0XYeWHnwzz7E3APalBeOHwRSCpuYWawd/y5 MXTQ== MIME-Version: 1.0 X-Received: by 10.152.170.195 with SMTP id ao3mr10496015lac.30.1440230804480; Sat, 22 Aug 2015 01:06:44 -0700 (PDT) Received: by 10.112.149.167 with HTTP; Sat, 22 Aug 2015 01:06:44 -0700 (PDT) In-Reply-To: References: Date: Sat, 22 Aug 2015 10:06:44 +0200 Message-ID: Subject: Re: Add closures to class via AST From: =?UTF-8?Q?C=C3=A9dric_Champeau?= To: users@groovy.incubator.apache.org Content-Type: multipart/alternative; boundary=089e0112c59e7eeab2051de1dd2a --089e0112c59e7eeab2051de1dd2a Content-Type: text/plain; charset=UTF-8 Hi Anto, (first of all, I don't think you will get more answers by sending multiple mails in a single day, we all have our respective jobs). I'm not sure if your closure code makes a lot of sense, however, `param` is indeed null. What you generate is: def helloTest(def param) { { param -> // why delegate.with? delegate.with { println delegate param() } }.call() } So you can already see that you have a conflict between the method parameter name and the closure parameter. Regular code will not let you do this, if you do AST xforms, you have to care about it yourself and make sure you don't mix things up. So imagine that you rename the method param name to `p` and call the method. -> NPE, because you call the closure with no arguments, which will cause param to be `null`. That's what is happening. On the other hand, if you create a closure that takes *no* argument and refers to the parameter like this: def helloTest(def param) { { -> delegate.with { println delegate param() } }.call() } Then it works as you expect. Last but not least, you may have to call the VariableScopeVisitor yourself depending on the compiler phase your AST transform works. Best regards, 2015-08-22 1:05 GMT+02:00 Anto Aravinth : > Any ideas will greatly helps!! > On 21 Aug 2015 16:57, "Anto Aravinth" wrote: > >> Hi All, >> >> Any solutions? >> On 21 Aug 2015 09:21, "Anto Aravinth" >> wrote: >> >>> Hi all, >>> >>> >>> >>> I'm trying to add an closure to my classNode via AST transformation. My >>> code looks something like this: >>> >>> >>> >>> List closure = new AstBuilder().buildFromCode { >>> >>> { param -> >>> >>> delegate.with { >>> >>> param() >>> >>> } >>> >>> } >>> >>> } >>> >>> >>> >>> cNode.addMethod(new MethodNode('helloTest', ACC_PUBLIC, >>> ClassHelper.DYNAMIC_TYPE,[new Parameter(ClassHelper.OBJECT_TYPE, "param")] >>> as Parameter[], ClassNode.EMPTY_ARRAY, closure[0])); >>> >>> >>> >>> And running AST transformation, on the test class: >>> >>> >>> >>> @AddMethod >>> >>> class Test{ >>> >>> } >>> >>> >>> >>> def a = new Test() >>> >>> a.helloTest({ >>> >>> println "Works great!"; >>> >>> }) >>> >>> >>> >>> Now no errors nothing. The code works fine, but since I have passed an >>> println to the helloTest closure, I expect it to print on my console, which >>> didn't happen. Looks like my closure itself didn't ran. Then I called the >>> closure myself, something like this: >>> >>> >>> >>> List closure = new AstBuilder().buildFromCode { >>> >>> { param -> >>> >>> delegate.with { >>> >>> println delegate >>> >>> param() >>> >>> } >>> >>> }.call() >>> >>> } >>> >>> >>> >>> Now this gives NPE, saying param is null. Looks now the parameter is not >>> getting binded. Delegate is getting printed as expected. >>> >>> >>> >>> Also I'm not sure, the way I have added the closure to my class is right >>> or not. Any help would be great! >>> >> --089e0112c59e7eeab2051de1dd2a Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable
Hi Anto,

(first of all, I don't thi= nk you will get more answers by sending multiple mails in a single day, we = all have our respective jobs).

I'm not sure if= your closure code makes a lot of sense, however, `param` is indeed null. W= hat you generate is:

def helloTest(def param) {
{ param ->
// why delegate.with?
<= /span> delegate.with {
= println delegate
param()
}
=
}.call()
}
=

So you can already see that you have a conflict between= the method parameter name and the closure parameter. Regular code will not= let you do this, if you do AST xforms, you have to care about it yourself = and make sure you don't mix things up. So imagine that you rename the m= ethod param name to `p` and call the method. -> NPE, because you call th= e closure with no arguments, which will cause param to be `null`. That'= s what is happening. On the other hand, if you create a closure that takes = *no* argument and refers to the parameter like this:

<=
span style=3D"color:rgb(0,0,67);font-weight:bold">def helloTest(def param) {
{= ->
delegate.wit= h {
println delegate param() }
}.call()
}
<= /pre>

Then it works as you expect. Last but not le= ast, you may have to call the VariableScopeVisitor yourself depending on th= e compiler phase your AST transform works.

Best re= gards,

2015-08-22 1:05 GMT+02:00 Anto Aravinth <anto.aravinth.cse@gmai= l.com>:

Any = ideas will greatly helps!!

On 21 Aug 2015 16:57, "Anto Aravinth" = <anto.a= ravinth.cse@gmail.com> wrote:

Hi All,

Any solutions?

On 21 Aug 2015 09:21, "Anto Aravinth" = <anto.a= ravinth.cse@gmail.com> wrote:

Hi all,

=C2=A0

I'm trying to add an closure to my classNode via AST tra= nsformation. My code looks something like this:

=C2=A0

List<ASTNode> closure =3D new AstBuilder().buildFromCo= de {

=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 { pa= ram ->

=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 delegate.with {

=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 param()

=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 }

=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 }

=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 }

=C2=A0

=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 cNode.addMethod(ne= w MethodNode('helloTest', ACC_PUBLIC, ClassHelper.DYNAMIC_TYPE,[new= Parameter(ClassHelper.OBJECT_TYPE, "param")] as Parameter[], Cla= ssNode.EMPTY_ARRAY, closure[0]));

=C2=A0

And running AST transformation, on the test class:

=C2=A0

@AddMethod

class Test{

}

=C2=A0

def a =3D new Test()

a.helloTest({

=C2=A0 =C2=A0 =C2=A0 =C2=A0 println "Works great!"= ;

})

=C2=A0

Now no errors nothing. The code works fine, but since I have= passed an println to the helloTest closure, I expect it to print on my con= sole, which didn't happen. Looks like my closure itself didn't ran.= Then I called the closure myself, something like this:

=C2=A0

=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 List<ASTNode>= ; closure =3D new AstBuilder().buildFromCode {

=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 { pa= ram ->

=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 delegate.with {

=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 println delegate

=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 param()

=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 }

=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 }.ca= ll()

=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 }

=C2=A0

Now this gives NPE, saying param is null. Looks now the para= meter is not getting binded. Delegate is getting printed as expected. =C2= =A0

=C2=A0

Also I'm not sure, the way I have added the closure to m= y class is right or not. Any help would be great!


--089e0112c59e7eeab2051de1dd2a--