[ 
https://issues.apache.org/jira/browse/GROOVY-6510?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Eric Milles reassigned GROOVY-6510:
-----------------------------------

    Assignee: Eric Milles

> Problems with implicit closures inside of @Category-annotated classes
> ---------------------------------------------------------------------
>
>                 Key: GROOVY-6510
>                 URL: https://issues.apache.org/jira/browse/GROOVY-6510
>             Project: Groovy
>          Issue Type: Bug
>            Reporter: David Hangl
>            Assignee: Eric Milles
>            Priority: Major
>         Attachments: ClosureInsideExtensionOrCategoryTest.groovy
>
>
> The behavior of implicit closures is in my opinion broken when used inside of 
> a category.
> As you can see in the attached TestCase in a simplified example, I had the 
> following scenario:
> - first there is an utility method (in the example the method 
> ClosureInvoker#setDelegateAndInvokeClosure(Closure)) that gets a closure, 
> resets the delegate object of it and calls this closure.
> - next we have an ExtendedClass which isn't really used in the example itself 
> other than being used as "base"-class for the category/extension-methods. 
> This is just because its own functionallity doesn't matter to get the buggy 
> behavior. Just be ensured that it made more sense in the original context 
> (e.g. it was passed to the utility method and used to setup the delegate 
> object)
> - now there is a category class with a method that invokes the utility method 
> and passing an implicit closure to it (@see 
> CategoryClass#doWorkWithImplicitClosure()). that implicit closure is invoking 
> a method of the delegate object
> - at last the testcase itself will call this category method and assert, that 
> the delegate method was really called by the closure (@see 
> ClosureInsideExtensionOrCategoryTest#testCategoryWithImplicitClosure())
> As you can see in the additional test methods, the basic behavior does work 
> as expected. But only in the special combination of an implicit closure 
> inside of the category it fails.
> As far as I can backtrack it, it seems that the AST-manipulations for 
> category classes may do the damage. It appears to me, that it will manipulate 
> ALL unqualified member-calls inside of any category-methods to be instead 
> calls to the class given by the @Category-annotation. But this manipulation 
> should in my opinion be escaped when entering the code-block of an implicit 
> closure.
> So refering to my example the method 
> CategoryClass#doWorkWithImplicitClosure() seems to lead to the following code 
> after AST-manipulation:
> {code}
> def static doWorkWithImplicitClosure(ExtendedClass obj) {
>   ClosureInvoker.setDelegateAndInvokeClosure {->
>     obj.invokeDelegate()
>   }
> }
> {code}
> This will result in avoiding the whole resolve strategy of the closure, as 
> there won't be any unqualified member calls inside of the closure at all.
> Instead I would expect, that it would generate the following code:
> {code}
> def static doWorkWithImplicitClosure(ExtendedClass obj) {     
>   ClosureInvoker.setDelegateAndInvokeClosure {->
>     //AST manipulation would "prefix" all unqualified 
>     //member calls with "obj." outside of the closure 
>     //but not here as we are inside of a closure
>     invokeDelegate()
>   }
> }
> {code}
> which would be equivalent to 
> ExtensionMethodClass#doWorkWithImplicitClosure(ExtendedClass)



--
This message was sent by Atlassian Jira
(v8.20.1#820001)

Reply via email to