[
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)