[jira] [Comment Edited] (GROOVY-9662) Groovy 3.0.5: Closure delegate is not working properly
[ https://issues.apache.org/jira/browse/GROOVY-9662?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17251862#comment-17251862 ] Eric Milles edited comment on GROOVY-9662 at 12/18/20, 5:39 PM: This is a common case where the delegation metadata does not match the runtime resolve strategy. {{DelegatesTo}} has a default resolve strategy of {{OWNER_FIRST}} (as does {{Closure}}). So by not specifying {{strategy}} attribute, the compiler gets the default. Static compilation must choose a resolve strategy and it relies on the annotation metadata to do so. GROOVY-8394 and GROOVY-9283 discuss this further. I think GROOVY-9086 is where the change comes from. {code:groovy} void test(@DelegatesTo(value=Type) block) { block.resolveStrategy = Closure.DELEGATE_FIRST block.delegate = new Type() block.call() } {code} was (Author: emilles): This is a common case where the delegation metadata does not match the runtime resolve strategy. {{DelegatesTo}} has a default resolve strategy of {{OWNER_FIRST}} (as does {{Closure}}). So by not specifying {{strategy}} attribute, the compiler gets the default. Static compilation must choose a resolve strategy and it relies on the annotation metadata to do so. GROOVY-9283 discusses this further. I think GROOVY-9086 is where the change comes from. {code:groovy} void test(@DelegatesTo(value=Type) block) { block.resolveStrategy = Closure.DELEGATE_FIRST block.delegate = new Type() block.call() } {code} > Groovy 3.0.5: Closure delegate is not working properly > -- > > Key: GROOVY-9662 > URL: https://issues.apache.org/jira/browse/GROOVY-9662 > Project: Groovy > Issue Type: Bug >Affects Versions: 3.0.2, 3.0.3, 3.0.4, 3.0.5, 2.5.14 >Reporter: Puneet Behl >Assignee: Eric Milles >Priority: Major > Attachments: JsonViewWritableScript.groovy, StreamingJsonBuilder.java > > > In Grails Views, we are using closures to generate JSON using > `StreamingJsonBuilder`. The HAL implementation for an entity now generates an > incorrect JSON after updating to Groovy 3. > > Here is the problem code snipped from > \{{grails.plugin.json.view.api.internal.DefaultHalViewHelper#links}}: > {code:java} > jsonDelegate.call(LINKS_ATTRIBUTE) { > call(SELF_ATTRIBUTE) { > call HREF_ATTRIBUTE, viewHelper.link(resource: object, method: > HttpMethod.GET, absolute: true) > call HREFLANG_ATTRIBUTE, locale.toString() > call TYPE_ATTRIBUTE, contentType > } > Set links = getLinks(object) > for (link in links) { > call(link.rel) { > call HREF_ATTRIBUTE, link.href > call HREFLANG_ATTRIBUTE, link.hreflang?.toString() ?: > locale.toString() > def linkType = link.contentType > if (linkType) { > call TYPE_ATTRIBUTE, linkType > } > } > } > } > {code} > > Although the `resolveStatergy` for the closures is `DELEGATE_FIRST` but I > believe that is not working correctly because it works if I change the above > to: > {code:java} > delegate.call (... > {code} > > To reproduce the issue please checkout > [https://github.com/grails/grails-views/commits/bugs/groovy-9962] > -- This message was sent by Atlassian Jira (v8.3.4#803005)
[jira] [Comment Edited] (GROOVY-9662) Groovy 3.0.5: Closure delegate is not working properly
[ https://issues.apache.org/jira/browse/GROOVY-9662?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17251862#comment-17251862 ] Eric Milles edited comment on GROOVY-9662 at 12/18/20, 4:57 PM: This is a common case where the delegation metadata does not match the runtime resolve strategy. {{DelegatesTo}} has a default resolve strategy of {{OWNER_FIRST}} (as does {{Closure}}). So by not specifying {{strategy}} attribute, the compiler gets the default. Static compilation must choose a resolve strategy and it relies on the annotation metadata to do so. GROOVY-9283 discusses this further. I think GROOVY-9086 is where the change comes from. {code:groovy} void test(@DelegatesTo(value=Type) block) { block.resolveStrategy = Closure.DELEGATE_FIRST block.delegate = new Type() block.call() } {code} was (Author: emilles): This is a common case where the delegation metadata does not match the runtime resolve strategy. {{DelegatesTo}} has a default resolve strategy of {{OWNER_FIRST}} (as does {{Closure}}). So by not specifying {{strategy}} attribute, the compiler gets the default. Static compilation must choose a resolve strategy and it relies on the annotation metadata to do so. GROOVY-9283 discusses this further. I think GROOVY-9086 is where the change comes from. {code:groovy} void test(@DelegatesTo(value=Type) block) { block.resolveStrategy = Closure.DELEGATE_FIRST block.delegate = new Type() block.class() } {code} > Groovy 3.0.5: Closure delegate is not working properly > -- > > Key: GROOVY-9662 > URL: https://issues.apache.org/jira/browse/GROOVY-9662 > Project: Groovy > Issue Type: Bug >Affects Versions: 3.0.2, 3.0.3, 3.0.4, 3.0.5, 2.5.14 >Reporter: Puneet Behl >Assignee: Eric Milles >Priority: Major > Attachments: JsonViewWritableScript.groovy, StreamingJsonBuilder.java > > > In Grails Views, we are using closures to generate JSON using > `StreamingJsonBuilder`. The HAL implementation for an entity now generates an > incorrect JSON after updating to Groovy 3. > > Here is the problem code snipped from > \{{grails.plugin.json.view.api.internal.DefaultHalViewHelper#links}}: > {code:java} > jsonDelegate.call(LINKS_ATTRIBUTE) { > call(SELF_ATTRIBUTE) { > call HREF_ATTRIBUTE, viewHelper.link(resource: object, method: > HttpMethod.GET, absolute: true) > call HREFLANG_ATTRIBUTE, locale.toString() > call TYPE_ATTRIBUTE, contentType > } > Set links = getLinks(object) > for (link in links) { > call(link.rel) { > call HREF_ATTRIBUTE, link.href > call HREFLANG_ATTRIBUTE, link.hreflang?.toString() ?: > locale.toString() > def linkType = link.contentType > if (linkType) { > call TYPE_ATTRIBUTE, linkType > } > } > } > } > {code} > > Although the `resolveStatergy` for the closures is `DELEGATE_FIRST` but I > believe that is not working correctly because it works if I change the above > to: > {code:java} > delegate.call (... > {code} > > To reproduce the issue please checkout > [https://github.com/grails/grails-views/commits/bugs/groovy-9962] > -- This message was sent by Atlassian Jira (v8.3.4#803005)
[jira] [Comment Edited] (GROOVY-9662) Groovy 3.0.5: Closure delegate is not working properly
[ https://issues.apache.org/jira/browse/GROOVY-9662?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17251862#comment-17251862 ] Eric Milles edited comment on GROOVY-9662 at 12/18/20, 4:56 PM: This is a common case where the delegation metadata does not match the runtime resolve strategy. {{DelegatesTo}} has a default resolve strategy of {{OWNER_FIRST}} (as does {{Closure}}). So by not specifying {{strategy}} attribute, the compiler gets the default. Static compilation must choose a resolve strategy and it relies on the annotation metadata to do so. GROOVY-9283 discusses this further. I think GROOVY-9086 is where the change comes from. {code:groovy} void test(@DelegatesTo(value=Type) block) { block.resolveStrategy = Closure.DELEGATE_FIRST block.delegate = new Type() block.class() } {code} was (Author: emilles): This is a common case where the delegation metadata does not match the runtime resolve strategy. {{DelegatesTo}} has a default resolve strategy of {{OWNER_FIRST}}. So by not specifying {{strategy}} attribute, the compiler gets the default. Static compilation must choose a resolve strategy and it relies on the annotation metadata to do so. GROOVY-9283 discusses this further. I think GROOVY-9086 is where the change comes from. {code:groovy} void test(@DelegatesTo(value=Type) block) { block.resolveStrategy = Closure.DELEGATE_FIRST block.delegate = new Type() block.class() } {code} > Groovy 3.0.5: Closure delegate is not working properly > -- > > Key: GROOVY-9662 > URL: https://issues.apache.org/jira/browse/GROOVY-9662 > Project: Groovy > Issue Type: Bug >Affects Versions: 3.0.2, 3.0.3, 3.0.4, 3.0.5, 2.5.14 >Reporter: Puneet Behl >Assignee: Eric Milles >Priority: Major > Attachments: JsonViewWritableScript.groovy, StreamingJsonBuilder.java > > > In Grails Views, we are using closures to generate JSON using > `StreamingJsonBuilder`. The HAL implementation for an entity now generates an > incorrect JSON after updating to Groovy 3. > > Here is the problem code snipped from > \{{grails.plugin.json.view.api.internal.DefaultHalViewHelper#links}}: > {code:java} > jsonDelegate.call(LINKS_ATTRIBUTE) { > call(SELF_ATTRIBUTE) { > call HREF_ATTRIBUTE, viewHelper.link(resource: object, method: > HttpMethod.GET, absolute: true) > call HREFLANG_ATTRIBUTE, locale.toString() > call TYPE_ATTRIBUTE, contentType > } > Set links = getLinks(object) > for (link in links) { > call(link.rel) { > call HREF_ATTRIBUTE, link.href > call HREFLANG_ATTRIBUTE, link.hreflang?.toString() ?: > locale.toString() > def linkType = link.contentType > if (linkType) { > call TYPE_ATTRIBUTE, linkType > } > } > } > } > {code} > > Although the `resolveStatergy` for the closures is `DELEGATE_FIRST` but I > believe that is not working correctly because it works if I change the above > to: > {code:java} > delegate.call (... > {code} > > To reproduce the issue please checkout > [https://github.com/grails/grails-views/commits/bugs/groovy-9962] > -- This message was sent by Atlassian Jira (v8.3.4#803005)
[jira] [Comment Edited] (GROOVY-9662) Groovy 3.0.5: Closure delegate is not working properly
[ https://issues.apache.org/jira/browse/GROOVY-9662?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17251862#comment-17251862 ] Eric Milles edited comment on GROOVY-9662 at 12/18/20, 4:54 PM: This is a common case where the delegation metadata does not match the runtime resolve strategy. {{DelegatesTo}} has a default resolve strategy of {{OWNER_FIRST}}. So by not specifying {{strategy}} attribute, the compiler gets the default. Static compilation must choose a resolve strategy and it relies on the annotation metadata to do so. GROOVY-9283 discusses this further. I think GROOVY-9086 is where the change comes from. {code:groovy} void test(@DelegatesTo(value=Type) block) { block.resolveStrategy = Closure.DELEGATE_FIRST block.delegate = new Type() block.class() } {code} was (Author: emilles): This is a common case where the delegation metadata does not match the runtime resolve strategy. {{DelegatesTo}} has a default resolve strategy of {{OWNER_FIRST}}. So by not specifying {{strategy}} attribute, the compiler gets the default. Static compilation must choose a resolve strategy and it relies on the annotation metadata to do so. GROOVY-9283 discusses this further. {code:groovy} void test(@DelegatesTo(value=Type) block) { block.resolveStrategy = Closure.DELEGATE_FIRST block.delegate = new Type() block.class() } {code} > Groovy 3.0.5: Closure delegate is not working properly > -- > > Key: GROOVY-9662 > URL: https://issues.apache.org/jira/browse/GROOVY-9662 > Project: Groovy > Issue Type: Bug >Affects Versions: 3.0.2, 3.0.3, 3.0.4, 3.0.5, 2.5.14 >Reporter: Puneet Behl >Assignee: Eric Milles >Priority: Major > Attachments: JsonViewWritableScript.groovy, StreamingJsonBuilder.java > > > In Grails Views, we are using closures to generate JSON using > `StreamingJsonBuilder`. The HAL implementation for an entity now generates an > incorrect JSON after updating to Groovy 3. > > Here is the problem code snipped from > \{{grails.plugin.json.view.api.internal.DefaultHalViewHelper#links}}: > {code:java} > jsonDelegate.call(LINKS_ATTRIBUTE) { > call(SELF_ATTRIBUTE) { > call HREF_ATTRIBUTE, viewHelper.link(resource: object, method: > HttpMethod.GET, absolute: true) > call HREFLANG_ATTRIBUTE, locale.toString() > call TYPE_ATTRIBUTE, contentType > } > Set links = getLinks(object) > for (link in links) { > call(link.rel) { > call HREF_ATTRIBUTE, link.href > call HREFLANG_ATTRIBUTE, link.hreflang?.toString() ?: > locale.toString() > def linkType = link.contentType > if (linkType) { > call TYPE_ATTRIBUTE, linkType > } > } > } > } > {code} > > Although the `resolveStatergy` for the closures is `DELEGATE_FIRST` but I > believe that is not working correctly because it works if I change the above > to: > {code:java} > delegate.call (... > {code} > > To reproduce the issue please checkout > [https://github.com/grails/grails-views/commits/bugs/groovy-9962] > -- This message was sent by Atlassian Jira (v8.3.4#803005)
[jira] [Comment Edited] (GROOVY-9662) Groovy 3.0.5: Closure delegate is not working properly
[ https://issues.apache.org/jira/browse/GROOVY-9662?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17251862#comment-17251862 ] Eric Milles edited comment on GROOVY-9662 at 12/18/20, 4:52 PM: This is a common case where the delegation metadata does not match the runtime resolve strategy. {{DelegatesTo}} has a default resolve strategy of {{OWNER_FIRST}}. So by not specifying {{strategy}} attribute, the compiler gets the default. Static compilation must choose a resolve strategy and it relies on the annotation metadata to do so. GROOVY-9283 discusses this further. {code:groovy} void test(@DelegatesTo(value=Type) block) { block.resolveStrategy = Closure.DELEGATE_FIRST block.delegate = new Type() block.class() } {code} was (Author: emilles): This is a common case where the delegation metadata does not match the runtime resolve strategy. {{DelegatesTo}} has a default resolve strategy of {{OWNER_FIRST}}. So by not specifying {{strategy}} attribute, the compiler gets the default. Static compilation must choose a resolve strategy and it relies on the annotation metadata to do so. I'll try to find the ticket where this was discussed further. {code:groovy} void test(@DelegatesTo(value=Type) block) { block.resolveStrategy = Closure.DELEGATE_FIRST block.delegate = new Type() block.class() } {code} > Groovy 3.0.5: Closure delegate is not working properly > -- > > Key: GROOVY-9662 > URL: https://issues.apache.org/jira/browse/GROOVY-9662 > Project: Groovy > Issue Type: Bug >Affects Versions: 3.0.2, 3.0.3, 3.0.4, 3.0.5, 2.5.14 >Reporter: Puneet Behl >Assignee: Eric Milles >Priority: Major > Attachments: JsonViewWritableScript.groovy, StreamingJsonBuilder.java > > > In Grails Views, we are using closures to generate JSON using > `StreamingJsonBuilder`. The HAL implementation for an entity now generates an > incorrect JSON after updating to Groovy 3. > > Here is the problem code snipped from > \{{grails.plugin.json.view.api.internal.DefaultHalViewHelper#links}}: > {code:java} > jsonDelegate.call(LINKS_ATTRIBUTE) { > call(SELF_ATTRIBUTE) { > call HREF_ATTRIBUTE, viewHelper.link(resource: object, method: > HttpMethod.GET, absolute: true) > call HREFLANG_ATTRIBUTE, locale.toString() > call TYPE_ATTRIBUTE, contentType > } > Set links = getLinks(object) > for (link in links) { > call(link.rel) { > call HREF_ATTRIBUTE, link.href > call HREFLANG_ATTRIBUTE, link.hreflang?.toString() ?: > locale.toString() > def linkType = link.contentType > if (linkType) { > call TYPE_ATTRIBUTE, linkType > } > } > } > } > {code} > > Although the `resolveStatergy` for the closures is `DELEGATE_FIRST` but I > believe that is not working correctly because it works if I change the above > to: > {code:java} > delegate.call (... > {code} > > To reproduce the issue please checkout > [https://github.com/grails/grails-views/commits/bugs/groovy-9962] > -- This message was sent by Atlassian Jira (v8.3.4#803005)
[jira] [Comment Edited] (GROOVY-9662) Groovy 3.0.5: Closure delegate is not working properly
[ https://issues.apache.org/jira/browse/GROOVY-9662?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17251769#comment-17251769 ] Puneet Behl edited comment on GROOVY-9662 at 12/18/20, 1:48 PM: This is also happening with Grails Framework after updating to Groovy 2.5.14, the following code does not behave the same with `CompileStatic`: {code:java} import groovy.json.JsonOutput import groovy.json.StreamingJsonBuilder import groovy.transform.CompileStatic import org.springframework.http.HttpMethod import org.springframework.validation.ObjectError @CompileStatic class VndErrorJsonRenderer { final String LOGREF_ATTRIBUTE = 'logref' final String MESSAGE_ATTRIBUTE = "message" final String PATH_ATTRIBUTE = "path" final String RESOURCE_ATTRIBUTE = "resource" final String HREF_ATTRIBUTE = "href" final String LINKS_ATTRIBUTE = "_links" Writer targetWriter = new StringWriter() void render() { StreamingJsonBuilder writer = new StreamingJsonBuilder(targetWriter) writer.call { ObjectError oe-> writer call(LOGREF_ATTRIBUTE, "logref") call(MESSAGE_ATTRIBUTE, "msg") call(PATH_ATTRIBUTE, "http://localhost:8080";) call(LINKS_ATTRIBUTE) { call(RESOURCE_ATTRIBUTE) { call(HREF_ATTRIBUTE, "path") } } } targetWriter.flush() } } def vndErrorJsonRenderer = new VndErrorJsonRenderer() vndErrorJsonRenderer.render() JsonOutput.prettyPrint(vndErrorJsonRenderer.targetWriter.toString()) {code} was (Author: behlp): This is also happening with Grails Framework after updating to Groovy 2.5.14, the following code does not behave the same with `CompileStatic`: {code:java} import groovy.json.JsonOutput import groovy.json.StreamingJsonBuilder import groovy.transform.CompileStatic import org.springframework.http.HttpMethod import org.springframework.validation.ObjectError@CompileStatic class VndErrorJsonRenderer {final String LOGREF_ATTRIBUTE = 'logref' final String MESSAGE_ATTRIBUTE = "message" final String PATH_ATTRIBUTE = "path" final String RESOURCE_ATTRIBUTE = "resource" final String HREF_ATTRIBUTE = "href" final String LINKS_ATTRIBUTE = "_links"Writer targetWriter = new StringWriter()void render() {StreamingJsonBuilder writer = new StreamingJsonBuilder(targetWriter)writer.call { ObjectError oe-> writer call(LOGREF_ATTRIBUTE, "logref") call(MESSAGE_ATTRIBUTE, "msg") call(PATH_ATTRIBUTE, "http://localhost:8080";) call(LINKS_ATTRIBUTE) { call(RESOURCE_ATTRIBUTE) { call(HREF_ATTRIBUTE, "path") } }} targetWriter.flush() } }def vndErrorJsonRenderer = new VndErrorJsonRenderer() vndErrorJsonRenderer.render()JsonOutput.prettyPrint(vndErrorJsonRenderer.targetWriter.toString()) {code} > Groovy 3.0.5: Closure delegate is not working properly > -- > > Key: GROOVY-9662 > URL: https://issues.apache.org/jira/browse/GROOVY-9662 > Project: Groovy > Issue Type: Bug >Affects Versions: 3.0.2, 3.0.3, 3.0.4, 3.0.5, 2.5.14 >Reporter: Puneet Behl >Assignee: Eric Milles >Priority: Major > Attachments: JsonViewWritableScript.groovy, StreamingJsonBuilder.java > > > In Grails Views, we are using closures to generate JSON using > `StreamingJsonBuilder`. The HAL implementation for an entity now generates an > incorrect JSON after updating to Groovy 3. > > Here is the problem code snipped from > \{{grails.plugin.json.view.api.internal.DefaultHalViewHelper#links}}: > {code:java} > jsonDelegate.call(LINKS_ATTRIBUTE) { > call(SELF_ATTRIBUTE) { > call HREF_ATTRIBUTE, viewHelper.link(resource: object, method: > HttpMethod.GET, absolute: true) > call HREFLANG_ATTRIBUTE, locale.toString() > call TYPE_ATTRIBUTE, contentType > } > Set links = getLinks(object) > for (link in links) { > call(link.rel) { > call HREF_ATTRIBUTE, link.href > call HREFLANG_ATTRIBUTE, link.hreflang?.toString() ?: > locale.toString() > def linkType = link.contentType > if (linkType) { > call TYPE_ATTRIBUTE, linkType > } > } > } > } > {code} > > Although the `resolveStatergy` for the closures is `DELEGATE_FIRST` but I > believe that is not working correctly because it works if I change the above > to: > {code:java} > delegate.call (... > {code} > > To reproduce the issue please checkout > [https://github.com/grails/grails-views/commi
[jira] [Comment Edited] (GROOVY-9662) Groovy 3.0.5: Closure delegate is not working properly
[ https://issues.apache.org/jira/browse/GROOVY-9662?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17251769#comment-17251769 ] Puneet Behl edited comment on GROOVY-9662 at 12/18/20, 1:46 PM: This is also happening with Grails Framework after updating to Groovy 2.5.14, the following code does not behave the same with `CompileStatic`: {code:java} import groovy.json.JsonOutput import groovy.json.StreamingJsonBuilder import groovy.transform.CompileStatic import org.springframework.http.HttpMethod import org.springframework.validation.ObjectError@CompileStatic class VndErrorJsonRenderer {final String LOGREF_ATTRIBUTE = 'logref' final String MESSAGE_ATTRIBUTE = "message" final String PATH_ATTRIBUTE = "path" final String RESOURCE_ATTRIBUTE = "resource" final String HREF_ATTRIBUTE = "href" final String LINKS_ATTRIBUTE = "_links"Writer targetWriter = new StringWriter()void render() {StreamingJsonBuilder writer = new StreamingJsonBuilder(targetWriter)writer.call { ObjectError oe-> writer call(LOGREF_ATTRIBUTE, "logref") call(MESSAGE_ATTRIBUTE, "msg") call(PATH_ATTRIBUTE, "http://localhost:8080";) call(LINKS_ATTRIBUTE) { call(RESOURCE_ATTRIBUTE) { call(HREF_ATTRIBUTE, "path") } }} targetWriter.flush() } }def vndErrorJsonRenderer = new VndErrorJsonRenderer() vndErrorJsonRenderer.render()JsonOutput.prettyPrint(vndErrorJsonRenderer.targetWriter.toString()) {code} was (Author: behlp): This is also happening with Grails Framework after updating to Groovy 2.5.14, the following code does not behave the same with `CompileStatic`: {code} import groovy.json.JsonOutput import groovy.json.StreamingJsonBuilder import groovy.transform.CompileStatic import org.springframework.http.HttpMethod import org.springframework.validation.ObjectError @CompileStatic class VndErrorJsonRenderer { final String LOGREF_ATTRIBUTE = 'logref' final String MESSAGE_ATTRIBUTE = "message" final String PATH_ATTRIBUTE = "path" final String RESOURCE_ATTRIBUTE = "resource" final String HREF_ATTRIBUTE = "href" final String LINKS_ATTRIBUTE = "_links" Writer targetWriter = new StringWriter() void render() { StreamingJsonBuilder writer = new StreamingJsonBuilder(targetWriter) writer.call *{* ObjectError oe*->* ** writer call(LOGREF_ATTRIBUTE, "logref") call(MESSAGE_ATTRIBUTE, "msg") call(PATH_ATTRIBUTE, "http://localhost:8080";) call(LINKS_ATTRIBUTE) *{* ** call(RESOURCE_ATTRIBUTE) *{* ** call(HREF_ATTRIBUTE, "path") *}* *}* *}* ** targetWriter.flush() } } def vndErrorJsonRenderer = new VndErrorJsonRenderer() vndErrorJsonRenderer.render() JsonOutput._prettyPrint_(vndErrorJsonRenderer.targetWriter.toString()) {code} > Groovy 3.0.5: Closure delegate is not working properly > -- > > Key: GROOVY-9662 > URL: https://issues.apache.org/jira/browse/GROOVY-9662 > Project: Groovy > Issue Type: Bug >Affects Versions: 3.0.2, 3.0.3, 3.0.4, 3.0.5, 2.5.14 >Reporter: Puneet Behl >Assignee: Eric Milles >Priority: Major > Attachments: JsonViewWritableScript.groovy, StreamingJsonBuilder.java > > > In Grails Views, we are using closures to generate JSON using > `StreamingJsonBuilder`. The HAL implementation for an entity now generates an > incorrect JSON after updating to Groovy 3. > > Here is the problem code snipped from > \{{grails.plugin.json.view.api.internal.DefaultHalViewHelper#links}}: > {code:java} > jsonDelegate.call(LINKS_ATTRIBUTE) { > call(SELF_ATTRIBUTE) { > call HREF_ATTRIBUTE, viewHelper.link(resource: object, method: > HttpMethod.GET, absolute: true) > call HREFLANG_ATTRIBUTE, locale.toString() > call TYPE_ATTRIBUTE, contentType > } > Set links = getLinks(object) > for (link in links) { > call(link.rel) { > call HREF_ATTRIBUTE, link.href > call HREFLANG_ATTRIBUTE, link.hreflang?.toString() ?: > locale.toString() > def linkType = link.contentType > if (linkType) { > call TYPE_ATTRIBUTE, linkType > } > } > } > } > {code} > > Although the `resolveStatergy` for the closures is `DELEGATE_FIRST` but I > believe that is not working correctly because it works if I change the above > to: > {code:
[jira] [Comment Edited] (GROOVY-9662) Groovy 3.0.5: Closure delegate is not working properly
[ https://issues.apache.org/jira/browse/GROOVY-9662?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17209668#comment-17209668 ] Eric Milles edited comment on GROOVY-9662 at 10/7/20, 5:09 PM: --- The difference in behavior comes from the static compiler using more of the declared delegation metadata. {{grails.plugin.json.builder.StreamingJsonBuilder.StreamingJsonDelegate #cloneDelegateAndGetContent}} and {{#curryDelegateAndGetContent}} uses {{groovy.lang.DelegatesTo}} to indicate the type of the closure's delegate, but does not correctly indicate the resolve strategy. {code:java} // "strategy = Closure.DELEGATE_FIRST" was added to match how the closure is actually invoked private static void curryDelegateAndGetContent(Writer w, @DelegatesTo(value = StreamingJsonDelegate.class, strategy = Closure.DELEGATE_FIRST) Closure c, Object o, boolean first, JsonGenerator generator) { StreamingJsonDelegate delegate = new StreamingJsonDelegate(w, first, generator); Closure curried = c.curry(o); curried.setDelegate(delegate); curried.setResolveStrategy(Closure.DELEGATE_FIRST); curried.call(); } {code} If I propagate the resolve strategy to all callers of this method (in [^StreamingJsonBuilder.java], [^JsonViewWritableScript.groovy], JsonView, etc.) the test case works as expected. was (Author: emilles): The difference in behavior comes from the static compiler using more of the declared delegation metadata. {{grails.plugin.json.builder.StreamingJsonBuilder.StreamingJsonDelegate #cloneDelegateAndGetContent}} and {{#curryDelegateAndGetContent}} uses {{groovy.lang.DelegatesTo}} to indicate the type of the closure's delegate, but does not correctly indicate the resolve strategy. {code:java} // "strategy = Closure.DELEGATE_FIRST" was added to match how the closure is actually invoked private static void curryDelegateAndGetContent(Writer w, @DelegatesTo(value = StreamingJsonDelegate.class, strategy = Closure.DELEGATE_FIRST) Closure c, Object o, boolean first, JsonGenerator generator) { StreamingJsonDelegate delegate = new StreamingJsonDelegate(w, first, generator); Closure curried = c.curry(o); curried.setDelegate(delegate); curried.setResolveStrategy(Closure.DELEGATE_FIRST); curried.call(); } {code} If I propagate the resolve strategy to all callers of this method (in [^StreamingJsonBuilder.java], JsonViewWriteableSript, JsonView, etc.) the test case works as expected. > Groovy 3.0.5: Closure delegate is not working properly > -- > > Key: GROOVY-9662 > URL: https://issues.apache.org/jira/browse/GROOVY-9662 > Project: Groovy > Issue Type: Bug >Affects Versions: 3.0.2, 3.0.3, 3.0.4, 3.0.5 >Reporter: Puneet Behl >Assignee: Eric Milles >Priority: Major > Attachments: JsonViewWritableScript.groovy, StreamingJsonBuilder.java > > > In Grails Views, we are using closures to generate JSON using > `StreamingJsonBuilder`. The HAL implementation for an entity now generates an > incorrect JSON after updating to Groovy 3. > > Here is the problem code snipped from Grails Views: > {code:java} > jsonDelegate.call(LINKS_ATTRIBUTE) { > call(SELF_ATTRIBUTE) { > call HREF_ATTRIBUTE, viewHelper.link(resource: object, method: > HttpMethod.GET, absolute: true) > call HREFLANG_ATTRIBUTE, locale.toString() > call TYPE_ATTRIBUTE, contentType > } > Set links = getLinks(object) > for (link in links) { > call(link.rel) { > call HREF_ATTRIBUTE, link.href > call HREFLANG_ATTRIBUTE, link.hreflang?.toString() ?: > locale.toString() > def linkType = link.contentType > if (linkType) { > call TYPE_ATTRIBUTE, linkType > } > } > } > } > {code} > > Although the `resolveStatergy` for the closures is `DELEGATE_FIRST` but I > believe that is not working correctly because it works if I change the above > to: > {code:java} > delegate.call (... > {code} > > To reproduce the issue please checkout > https://github.com/grails/grails-views/commits/bugs/groovy-9962 > -- This message was sent by Atlassian Jira (v8.3.4#803005)
[jira] [Comment Edited] (GROOVY-9662) Groovy 3.0.5: Closure delegate is not working properly
[ https://issues.apache.org/jira/browse/GROOVY-9662?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17209668#comment-17209668 ] Eric Milles edited comment on GROOVY-9662 at 10/7/20, 5:07 PM: --- The difference in behavior comes from the static compiler using more of the declared delegation metadata. {{grails.plugin.json.builder.StreamingJsonBuilder.StreamingJsonDelegate #cloneDelegateAndGetContent}} and {{#curryDelegateAndGetContent}} uses {{groovy.lang.DelegatesTo}} to indicate the type of the closure's delegate, but does not correctly indicate the resolve strategy. {code:java} // "strategy = Closure.DELEGATE_FIRST" was added to match how the closure is actually invoked private static void curryDelegateAndGetContent(Writer w, @DelegatesTo(value = StreamingJsonDelegate.class, strategy = Closure.DELEGATE_FIRST) Closure c, Object o, boolean first, JsonGenerator generator) { StreamingJsonDelegate delegate = new StreamingJsonDelegate(w, first, generator); Closure curried = c.curry(o); curried.setDelegate(delegate); curried.setResolveStrategy(Closure.DELEGATE_FIRST); curried.call(); } {code} If I propagate the resolve strategy to all callers of this method (in [^StreamingJsonBuilder.java], JsonViewWriteableSript, JsonView, etc.) the test case works as expected. was (Author: emilles): The difference in behavior comes from the static compiler using more of the declared delegation metadata. {{grails.plugin.json.builder.StreamingJsonBuilder.StreamingJsonDelegate#curryDelegateAndGetContent}} uses {{groovy.lang.DelegatesTo}} to indicate the type of the closure's delegate, but does not correctly indicate the resolve strategy. {code:java} // "strategy = Closure.DELEGATE_FIRST" was added to match how the closure is actually invoked private static void curryDelegateAndGetContent(Writer w, @DelegatesTo(value = StreamingJsonDelegate.class, strategy = Closure.DELEGATE_FIRST) Closure c, Object o, boolean first, JsonGenerator generator) { StreamingJsonDelegate delegate = new StreamingJsonDelegate(w, first, generator); Closure curried = c.curry(o); curried.setDelegate(delegate); curried.setResolveStrategy(Closure.DELEGATE_FIRST); curried.call(); } {code} If I propagate the resolve strategy to all callers of this method (in [^StreamingJsonBuilder.java], JsonViewWriteableSript, JsonView, etc.) the test case works as expected. > Groovy 3.0.5: Closure delegate is not working properly > -- > > Key: GROOVY-9662 > URL: https://issues.apache.org/jira/browse/GROOVY-9662 > Project: Groovy > Issue Type: Bug >Affects Versions: 3.0.2, 3.0.3, 3.0.4, 3.0.5 >Reporter: Puneet Behl >Assignee: Eric Milles >Priority: Major > Attachments: StreamingJsonBuilder.java > > > In Grails Views, we are using closures to generate JSON using > `StreamingJsonBuilder`. The HAL implementation for an entity now generates an > incorrect JSON after updating to Groovy 3. > > Here is the problem code snipped from Grails Views: > {code:java} > jsonDelegate.call(LINKS_ATTRIBUTE) { > call(SELF_ATTRIBUTE) { > call HREF_ATTRIBUTE, viewHelper.link(resource: object, method: > HttpMethod.GET, absolute: true) > call HREFLANG_ATTRIBUTE, locale.toString() > call TYPE_ATTRIBUTE, contentType > } > Set links = getLinks(object) > for (link in links) { > call(link.rel) { > call HREF_ATTRIBUTE, link.href > call HREFLANG_ATTRIBUTE, link.hreflang?.toString() ?: > locale.toString() > def linkType = link.contentType > if (linkType) { > call TYPE_ATTRIBUTE, linkType > } > } > } > } > {code} > > Although the `resolveStatergy` for the closures is `DELEGATE_FIRST` but I > believe that is not working correctly because it works if I change the above > to: > {code:java} > delegate.call (... > {code} > > To reproduce the issue please checkout > https://github.com/grails/grails-views/commits/bugs/groovy-9962 > -- This message was sent by Atlassian Jira (v8.3.4#803005)
[jira] [Comment Edited] (GROOVY-9662) Groovy 3.0.5: Closure delegate is not working properly
[ https://issues.apache.org/jira/browse/GROOVY-9662?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17202987#comment-17202987 ] Paul King edited comment on GROOVY-9662 at 9/28/20, 4:02 AM: - >From the log when I run tests in the grails-views/views-json subproject: {noformat} result.jsonText == '{"_links":{"self":{"href":"http://localhost:8080/player","hreflang":"en","type":"application/hal+json"}},"name":"Cantona"}' | || | |false | |1 difference (99% similarity) | | {"_links":{"self":{(,)"href":"http://localhost:8080/player","hreflang":"en","type":"application/hal+json"}},"name":"Cantona"} ... {noformat} Each level during json rendering has its own closure with a delegate having a boolean property {{first}} which is checked to avoid a comma before the first element at that level. Here, {{first}} from an outer level (where it is already set to false) is returned, hence the extra comma one level down. I haven't yet had time to produce a standalone example. was (Author: paulk): >From the log when I run tests in the grails-views/views-json subproject: {noformat} result.jsonText == '{"_links":{"self":{"href":"http://localhost:8080/player","hreflang":"en","type":"application/hal+json"}},"name":"Cantona"}' | || | |false | |1 difference (99% similarity) | | {"_links":{"self":{(,)"href":"http://localhost:8080/player","hreflang":"en","type":"application/hal+json"}},"name":"Cantona"} ... {noformat} Each level during json rendering has its own closure with a delegate having a boolean property {{first}} which is checked to avoid a comma before the first element at that level. Here, {{first}} from an outer level (where it is already set to false) is returned, hence the extra comma one level down. > Groovy 3.0.5: Closure delegate is not working properly > -- > > Key: GROOVY-9662 > URL: https://issues.apache.org/jira/browse/GROOVY-9662 > Project: Groovy > Issue Type: Bug >Affects Versions: 3.0.2, 3.0.3, 3.0.4, 3.0.5 >Reporter: Puneet Behl >Assignee: Eric Milles >Priority: Major > > In Grails Views, we are using closures to generate JSON using > `StreamingJsonBuilder`. The HAL implementation for an entity now generates an > incorrect JSON after updating to Groovy 3. > > Here is the problem code snipped from Grails Views: > {code:java} > jsonDelegate.call(LINKS_ATTRIBUTE) { > call(SELF_ATTRIBUTE) { > call HREF_ATTRIBUTE, viewHelper.link(resource: object, method: > HttpMethod.GET, absolute: true) > call HREFLANG_ATTRIBUTE, locale.toString() > call TYPE_ATTRIBUTE, contentType > } > Set links = getLinks(object) > for (link in links) { > call(link.rel) { > call HREF_ATTRIBUTE, link.href > call HREFLANG_ATTRIBUTE, link.hreflang?.toString() ?: > locale.toString() > def linkType = link.contentType > if (linkType) { > call TYPE_ATTRIBUTE, linkType > } > } > } > } > {code} > > Although the `resolveStatergy` for the closures is `DELEGATE_FIRST` but I > believe that is not working correctly because it works if I change the above > to: > {code:java} > delegate.call (... > {code} > > To reproduce the issue please checkout > https://github.com/grails/grails-views/commits/bugs/groovy-9962 > -- This message was sent by Atlassian Jira (v8.3.4#803005)
[jira] [Comment Edited] (GROOVY-9662) Groovy 3.0.5: Closure delegate is not working properly
[ https://issues.apache.org/jira/browse/GROOVY-9662?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17202987#comment-17202987 ] Paul King edited comment on GROOVY-9662 at 9/28/20, 3:59 AM: - >From the log when I run tests in the grails-views/views-json subproject: {noformat} result.jsonText == '{"_links":{"self":{"href":"http://localhost:8080/player","hreflang":"en","type":"application/hal+json"}},"name":"Cantona"}' | || | |false | |1 difference (99% similarity) | | {"_links":{"self":{(,)"href":"http://localhost:8080/player","hreflang":"en","type":"application/hal+json"}},"name":"Cantona"} ... {noformat} Each level during json rendering has its own closure with a delegate having a boolean property {{first}} which is checked to avoid a comma before the first element at that level. Here, {{first}} from an outer level (where it is already set to false) is returned, hence the extra comma one level down. was (Author: paulk): >From the log when I run tests in the grails-views/views-json subproject: {noformat} result.jsonText == '{"_links":{"self":{"href":"http://localhost:8080/player","hreflang":"en","type":"application/hal+json"}},"name":"Cantona"}' | || | |false | |1 difference (99% similarity) | | {"_links":{"self":{(,)"href":"http://localhost:8080/player","hreflang":"en","type":"application/hal+json"}},"name":"Cantona"} ... {noformat} Each level has a boolean property {{first}} which is checked to avoid a comma before the first element. Here, {{first}} from an outer level (where it is already set to false) is returned, hence the extra comma one level down. > Groovy 3.0.5: Closure delegate is not working properly > -- > > Key: GROOVY-9662 > URL: https://issues.apache.org/jira/browse/GROOVY-9662 > Project: Groovy > Issue Type: Bug >Affects Versions: 3.0.2, 3.0.3, 3.0.4, 3.0.5 >Reporter: Puneet Behl >Assignee: Eric Milles >Priority: Major > > In Grails Views, we are using closures to generate JSON using > `StreamingJsonBuilder`. The HAL implementation for an entity now generates an > incorrect JSON after updating to Groovy 3. > > Here is the problem code snipped from Grails Views: > {code:java} > jsonDelegate.call(LINKS_ATTRIBUTE) { > call(SELF_ATTRIBUTE) { > call HREF_ATTRIBUTE, viewHelper.link(resource: object, method: > HttpMethod.GET, absolute: true) > call HREFLANG_ATTRIBUTE, locale.toString() > call TYPE_ATTRIBUTE, contentType > } > Set links = getLinks(object) > for (link in links) { > call(link.rel) { > call HREF_ATTRIBUTE, link.href > call HREFLANG_ATTRIBUTE, link.hreflang?.toString() ?: > locale.toString() > def linkType = link.contentType > if (linkType) { > call TYPE_ATTRIBUTE, linkType > } > } > } > } > {code} > > Although the `resolveStatergy` for the closures is `DELEGATE_FIRST` but I > believe that is not working correctly because it works if I change the above > to: > {code:java} > delegate.call (... > {code} > > To reproduce the issue please checkout > https://github.com/grails/grails-views/commits/bugs/groovy-9962 > -- This message was sent by Atlassian Jira (v8.3.4#803005)
[jira] [Comment Edited] (GROOVY-9662) Groovy 3.0.5: Closure delegate is not working properly
[ https://issues.apache.org/jira/browse/GROOVY-9662?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17202939#comment-17202939 ] Jochen Theodorou edited comment on GROOVY-9662 at 9/28/20, 12:41 AM: - The problem with that runtime meta class is, that we actually have to know if we do "someClosure()"/"someClosure.call()" or something like "x.foo \{ call() \}". The first I name a call from outside, the second a call from inside. So if everything would be wired correctly you would use the "sender" information in that invokeMethod up there to determine if the call is from inside or not. My last information in this area was, that the sender information is in general not reliable - that is for example because of the optional invokeMethod path. Maybe it is for reliable enough for open blocks like in "x.foo \{ call() \}" and worth implementing in ClosureMetaClass. Of course that comes with another problem... assuming we do want recursive call invocations, but have that new logic implemented, then how would you do it? And for that matter... how do I do it now in static compiled code if the delegation mechanism is set? And maybe it is sometimes better to say, that you cannot do that then. Meaning no calls on the closure implementing the block from inside the block itself. was (Author: blackdrag): The problem with that runtime meta class is, that we actually have to know if we do "someClosure()"/"someClosure.call()" or something like "x.foo { call()}". The first I name a call from outside, the second a call from inside. So if everything would be wired correctly you would use the "sender" information in that invokeMethod up there to determine if the call is from inside or not. My last information in this area was, that the sender information is in general not reliable - that is for example because of the optional invokeMethod path. Maybe it is for reliable enough for open blocks like in "x.foo { call() }" and worth implementing in ClosureMetaClass. Of course that comes with another problem... assuming we do want recursive call invocations, but have that new logic implemented, then how would you do it? And for that matter... how do I do it now in static compiled code if the delegation mechanism is set? And maybe it is sometimes better to say, that you cannot do that then. Meaning no calls on the closure implementing the block from inside the block itself. > Groovy 3.0.5: Closure delegate is not working properly > -- > > Key: GROOVY-9662 > URL: https://issues.apache.org/jira/browse/GROOVY-9662 > Project: Groovy > Issue Type: Bug >Affects Versions: 3.0.2, 3.0.3, 3.0.4, 3.0.5 >Reporter: Puneet Behl >Assignee: Eric Milles >Priority: Major > > In Grails Views, we are using closures to generate JSON using > `StreamingJsonBuilder`. The HAL implementation for an entity now generates an > incorrect JSON after updating to Groovy 3. > > Here is the problem code snipped from Grails Views: > {code:java} > jsonDelegate.call(LINKS_ATTRIBUTE) { > call(SELF_ATTRIBUTE) { > call HREF_ATTRIBUTE, viewHelper.link(resource: object, method: > HttpMethod.GET, absolute: true) > call HREFLANG_ATTRIBUTE, locale.toString() > call TYPE_ATTRIBUTE, contentType > } > Set links = getLinks(object) > for (link in links) { > call(link.rel) { > call HREF_ATTRIBUTE, link.href > call HREFLANG_ATTRIBUTE, link.hreflang?.toString() ?: > locale.toString() > def linkType = link.contentType > if (linkType) { > call TYPE_ATTRIBUTE, linkType > } > } > } > } > {code} > > Although the `resolveStatergy` for the closures is `DELEGATE_FIRST` but I > believe that is not working correctly because it works if I change the above > to: > {code:java} > delegate.call (... > {code} > > To reproduce the issue please checkout > https://github.com/grails/grails-views/commits/bugs/groovy-9962 > -- This message was sent by Atlassian Jira (v8.3.4#803005)
[jira] [Comment Edited] (GROOVY-9662) Groovy 3.0.5: Closure delegate is not working properly
[ https://issues.apache.org/jira/browse/GROOVY-9662?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17202930#comment-17202930 ] Eric Milles edited comment on GROOVY-9662 at 9/27/20, 10:19 PM: ClosureMetaClass checks the closure for any method right after the call/doCall block. {code:java} public Object invokeMethod(Class sender, Object object, String methodName, Object[] originalArguments, boolean isCallToSuper, boolean fromInsideClass) { ... MetaMethod method = null; final Closure closure = (Closure) object; if (CLOSURE_DO_CALL_METHOD.equals(methodName) || CLOSURE_CALL_METHOD.equals(methodName)) { ... } boolean shouldDefer = closure.getResolveStrategy() == Closure.DELEGATE_ONLY && isInternalMethod(methodName); if (method == null && !shouldDefer) { method = CLOSURE_METACLASS.pickMethod(methodName, argClasses); // HERE! } if (method != null) return method.doMethodInvoke(object, arguments); {code} Here is a quick demonstration: {code:groovy} class D { void run() { println 'D.run()' } } class C { int times = 5 void test() { new D().with { println "C.test.with $times" if (--times) run() // Closure.run() or D.run()? } } } new C().test() {code} was (Author: emilles): ClosureMetaClass checks the closure for any method right after the call/doCall block. {code:java} public Object invokeMethod(Class sender, Object object, String methodName, Object[] originalArguments, boolean isCallToSuper, boolean fromInsideClass) { ... MetaMethod method = null; final Closure closure = (Closure) object; if (CLOSURE_DO_CALL_METHOD.equals(methodName) || CLOSURE_CALL_METHOD.equals(methodName)) { ... } boolean shouldDefer = closure.getResolveStrategy() == Closure.DELEGATE_ONLY && isInternalMethod(methodName); if (method == null && !shouldDefer) { method = CLOSURE_METACLASS.pickMethod(methodName, argClasses); // HERE! } if (method != null) return method.doMethodInvoke(object, arguments); {code} > Groovy 3.0.5: Closure delegate is not working properly > -- > > Key: GROOVY-9662 > URL: https://issues.apache.org/jira/browse/GROOVY-9662 > Project: Groovy > Issue Type: Bug >Affects Versions: 3.0.2, 3.0.3, 3.0.4, 3.0.5 >Reporter: Puneet Behl >Assignee: Eric Milles >Priority: Major > > In Grails Views, we are using closures to generate JSON using > `StreamingJsonBuilder`. The HAL implementation for an entity now generates an > incorrect JSON after updating to Groovy 3. > > Here is the problem code snipped from Grails Views: > {code:java} > jsonDelegate.call(LINKS_ATTRIBUTE) { > call(SELF_ATTRIBUTE) { > call HREF_ATTRIBUTE, viewHelper.link(resource: object, method: > HttpMethod.GET, absolute: true) > call HREFLANG_ATTRIBUTE, locale.toString() > call TYPE_ATTRIBUTE, contentType > } > Set links = getLinks(object) > for (link in links) { > call(link.rel) { > call HREF_ATTRIBUTE, link.href > call HREFLANG_ATTRIBUTE, link.hreflang?.toString() ?: > locale.toString() > def linkType = link.contentType > if (linkType) { > call TYPE_ATTRIBUTE, linkType > } > } > } > } > {code} > > Although the `resolveStatergy` for the closures is `DELEGATE_FIRST` but I > believe that is not working correctly because it works if I change the above > to: > {code:java} > delegate.call (... > {code} > > To reproduce the issue please checkout > https://github.com/grails/grails-views/commits/bugs/groovy-9962 > -- This message was sent by Atlassian Jira (v8.3.4#803005)
[jira] [Comment Edited] (GROOVY-9662) Groovy 3.0.5: Closure delegate is not working properly
[ https://issues.apache.org/jira/browse/GROOVY-9662?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17165862#comment-17165862 ] Eric Milles edited comment on GROOVY-9662 at 9/27/20, 9:58 PM: --- When I try this: {code:groovy} class D { def call(... args) { println "D.call(${args})" args[1].call(args[0]) } } class C { def test() { new D().with { ... args -> println "C.test.with" call (123) { println "C.test.with.call" } } } } new C().test() {code} I get a stack overflow for "call" in dynamic mode, so the runtime is resolving "call" against the Closure instance and not the delegate. Thus, I'm hesitant to change the SC precedence of Closure methods. Adding a "delegate." qualifier is a safer long-term bet that is also cross-compatible with pre-3.0.5 Groovy. was (Author: emilles): When I try this: {code:groovy} class D { def call(... args) { println "D.call(${args})" args[1].call(args[0]) } } class C { def test() { new D().with { println "C.test.with" call (123) { println "C.test.with.call" } } } } new C().test() {code} I get a MissingMethodException for "call" in dynamic mode, so it seems the runtime is trying to resolve call against the Closure instance and not the delegate. Thus, I'm hesitant to change the SC precedence of Closure methods. Adding a "delegate." qualifier is a safer long-term bet that is also cross-compatible with pre-3.0.5 Groovy. > Groovy 3.0.5: Closure delegate is not working properly > -- > > Key: GROOVY-9662 > URL: https://issues.apache.org/jira/browse/GROOVY-9662 > Project: Groovy > Issue Type: Bug >Affects Versions: 3.0.2, 3.0.3, 3.0.4, 3.0.5 >Reporter: Puneet Behl >Assignee: Eric Milles >Priority: Major > > In Grails Views, we are using closures to generate JSON using > `StreamingJsonBuilder`. The HAL implementation for an entity now generates an > incorrect JSON after updating to Groovy 3. > > Here is the problem code snipped from Grails Views: > {code:java} > jsonDelegate.call(LINKS_ATTRIBUTE) { > call(SELF_ATTRIBUTE) { > call HREF_ATTRIBUTE, viewHelper.link(resource: object, method: > HttpMethod.GET, absolute: true) > call HREFLANG_ATTRIBUTE, locale.toString() > call TYPE_ATTRIBUTE, contentType > } > Set links = getLinks(object) > for (link in links) { > call(link.rel) { > call HREF_ATTRIBUTE, link.href > call HREFLANG_ATTRIBUTE, link.hreflang?.toString() ?: > locale.toString() > def linkType = link.contentType > if (linkType) { > call TYPE_ATTRIBUTE, linkType > } > } > } > } > {code} > > Although the `resolveStatergy` for the closures is `DELEGATE_FIRST` but I > believe that is not working correctly because it works if I change the above > to: > {code:java} > delegate.call (... > {code} > > To reproduce the issue please checkout > https://github.com/grails/grails-views/commits/bugs/groovy-9962 > -- This message was sent by Atlassian Jira (v8.3.4#803005)
[jira] [Comment Edited] (GROOVY-9662) Groovy 3.0.5: Closure delegate is not working properly
[ https://issues.apache.org/jira/browse/GROOVY-9662?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17201514#comment-17201514 ] Paul King edited comment on GROOVY-9662 at 9/24/20, 1:16 PM: - For any method name apart from {{call}} and {{doCall}}, dynamic Groovy will call the delegate. There is special logic for those names. Static Groovy has had different behavior for those methods. was (Author: paulk): For any method name apart from {{call}} and {{doCall}}, dynamic Groovy will call the delegate. There is special logic for those names. > Groovy 3.0.5: Closure delegate is not working properly > -- > > Key: GROOVY-9662 > URL: https://issues.apache.org/jira/browse/GROOVY-9662 > Project: Groovy > Issue Type: Bug >Affects Versions: 3.0.2, 3.0.3, 3.0.4, 3.0.5 >Reporter: Puneet Behl >Priority: Major > > In Grails Views, we are using closures to generate JSON using > `StreamingJsonBuilder`. The HAL implementation for an entity now generates an > incorrect JSON after updating to Groovy 3. > > Here is the problem code snipped from Grails Views: > {code:java} > jsonDelegate.call(LINKS_ATTRIBUTE) { > call(SELF_ATTRIBUTE) { > call HREF_ATTRIBUTE, viewHelper.link(resource: object, method: > HttpMethod.GET, absolute: true) > call HREFLANG_ATTRIBUTE, locale.toString() > call TYPE_ATTRIBUTE, contentType > } > Set links = getLinks(object) > for (link in links) { > call(link.rel) { > call HREF_ATTRIBUTE, link.href > call HREFLANG_ATTRIBUTE, link.hreflang?.toString() ?: > locale.toString() > def linkType = link.contentType > if (linkType) { > call TYPE_ATTRIBUTE, linkType > } > } > } > } > {code} > > Although the `resolveStatergy` for the closures is `DELEGATE_FIRST` but I > believe that is not working correctly because it works if I change the above > to: > {code:java} > delegate.call (... > {code} > > To reproduce the issue please checkout > https://github.com/grails/grails-views/commits/bugs/groovy-9962 > -- This message was sent by Atlassian Jira (v8.3.4#803005)
[jira] [Comment Edited] (GROOVY-9662) Groovy 3.0.5: Closure delegate is not working properly
[ https://issues.apache.org/jira/browse/GROOVY-9662?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17165812#comment-17165812 ] Eric Milles edited comment on GROOVY-9662 at 7/27/20, 4:06 PM: --- Am I correct in understanding that {{call (...) ...}} is expected to be resolving "call" against the delegate? There was a change to give Closure's methods like "getDelegate()", "getResolveStrategy()", etc. a higher priority so that any delegate that implements methodMissing would not trap them. GROOVY-9604 and https://github.com/apache/groovy/commit/f60285ec072821502f33d7a999b5574bee53b6e2 was (Author: emilles): Am I correct in understanding that "call (...) { ...}" is supposed to be resolving "call" against the delegate? There was a change to give Closure's methods like "getDelegate()", "getResolveStrategy()", etc. a higher priority so that any delegate that implements methodMissing would not trap them. GROOVY-9604 and https://github.com/apache/groovy/commit/f60285ec072821502f33d7a999b5574bee53b6e2 > Groovy 3.0.5: Closure delegate is not working properly > -- > > Key: GROOVY-9662 > URL: https://issues.apache.org/jira/browse/GROOVY-9662 > Project: Groovy > Issue Type: Bug >Affects Versions: 3.0.2, 3.0.3, 3.0.4, 3.0.5 >Reporter: Puneet Behl >Priority: Major > > In Grails Views, we are using closures to generate JSON using > `StreamingJsonBuilder`. The HAL implementation for an entity now generates an > incorrect JSON after updating to Groovy 3. > > Here is the problem code snipped from Grails Views: > {code:java} > jsonDelegate.call(LINKS_ATTRIBUTE) { > call(SELF_ATTRIBUTE) { > call HREF_ATTRIBUTE, viewHelper.link(resource: object, method: > HttpMethod.GET, absolute: true) > call HREFLANG_ATTRIBUTE, locale.toString() > call TYPE_ATTRIBUTE, contentType > } > Set links = getLinks(object) > for (link in links) { > call(link.rel) { > call HREF_ATTRIBUTE, link.href > call HREFLANG_ATTRIBUTE, link.hreflang?.toString() ?: > locale.toString() > def linkType = link.contentType > if (linkType) { > call TYPE_ATTRIBUTE, linkType > } > } > } > } > {code} > > Although the `resolveStatergy` for the closures is `DELEGATE_FIRST` but I > believe that is not working correctly because it works if I change the above > to: > {code:java} > delegate.call (... > {code} > > -- This message was sent by Atlassian Jira (v8.3.4#803005)