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

Björn Kautler updated GROOVY-11823:
-----------------------------------
    Description: 
Given the following code:
{code:groovy}@Grab('org.apache.groovy.geb:geb-spock:8.0.1')
import geb.spock.GebSpec

class Foo {
  static class Bar extends GebSpec {
    def bar() {
      println(browser.driver)
      println(driver)
      expect: true
    }
  }
}{code}
and assuming that either GROOVY-11822 was fixed or Geb changed to use {{void}} 
as return type so that the code actually compiles.

Due to the Groovy compiler overwriting the {{propertyMissing}} and 
{{methodMissing}} methods, the {{println(driver)}} line no longer works, 
outside a static nested class it works as intended.

This behavior is silent and at first very confusing to a user.

One option - though an imho very bad one - would be to fail the build just like 
when you try to have any of those methods in your code directly.
But, e.g. in this case, you might still be able to use the superclass, you here 
just have to be a bit more explicit and use {{browser.}} instead of the 
meatprogramming magic, so it would be sad if the solution is to fail the build.

Maybe other two options would either a prominent compiler warning if those 
methods override ones from a superclass so that you at least have a chance to 
get aware of the problem,
or maybe it could even be made in a way that the compiler-inserted methods 
consider the superclass methods by calling them at an appropriate place.

The last solution would maybe be optimal as it would then work as expected, 
unless there are details I don't know why this cannot work.

If some class does depend on those methods not being overwritten and not just 
provide convenience like {{GebSpec}}, they can probably also declare the 
methods {{final}} to prevent static nested subclasses being created.

  was:
Given the following code:
{code:groovy}@Grab('org.apache.groovy.geb:geb-spock:8.0.1')
import geb.spock.GebSpec

class Foo {
  static class Bar extends GebSpec {
    def bar() {
      println(browser.driver)
      println(driver)
      expect: true
    }
  }
}{code}
and assuming that either GROOVY-11822 was fixed or Geb changed to use {{void}} 
as return type so that the code actually compiles.

Due to the Groovy compiler overwriting the {{propertyMissing}} and 
{{methodMissing}} methods, the {{println(driver)}} line no longer works, 
outside a static inner class it works as intended.

This behavior is silent and at first very confusing to a user.

One option - though an imho very bad one - would be to fail the build just like 
when you try to have any of those methods in your code directly.
But, e.g. in this case, you might still be able to use the superclass, you here 
just have to be a bit more explicit and use {{browser.}} instead of the 
meatprogramming magic, so it would be sad if the solution is to fail the build.

Maybe other two options would either a prominent compiler warning if those 
methods override ones from a superclass so that you at least have a chance to 
get aware of the problem,
or maybe it could even be made in a way that the compiler-inserted methods 
consider the superclass methods by calling them at an appropriate place.

The last solution would maybe be optimal as it would then work as expected, 
unless there are details I don't know why this cannot work.


> Check whether inserted metaprogramming methods in a static inner class 
> override methods in a superclass and fail, warn, or make it work
> ---------------------------------------------------------------------------------------------------------------------------------------
>
>                 Key: GROOVY-11823
>                 URL: https://issues.apache.org/jira/browse/GROOVY-11823
>             Project: Groovy
>          Issue Type: Improvement
>    Affects Versions: 4.0.29
>            Reporter: Björn Kautler
>            Priority: Major
>
> Given the following code:
> {code:groovy}@Grab('org.apache.groovy.geb:geb-spock:8.0.1')
> import geb.spock.GebSpec
> class Foo {
>   static class Bar extends GebSpec {
>     def bar() {
>       println(browser.driver)
>       println(driver)
>       expect: true
>     }
>   }
> }{code}
> and assuming that either GROOVY-11822 was fixed or Geb changed to use 
> {{void}} as return type so that the code actually compiles.
> Due to the Groovy compiler overwriting the {{propertyMissing}} and 
> {{methodMissing}} methods, the {{println(driver)}} line no longer works, 
> outside a static nested class it works as intended.
> This behavior is silent and at first very confusing to a user.
> One option - though an imho very bad one - would be to fail the build just 
> like when you try to have any of those methods in your code directly.
> But, e.g. in this case, you might still be able to use the superclass, you 
> here just have to be a bit more explicit and use {{browser.}} instead of the 
> meatprogramming magic, so it would be sad if the solution is to fail the 
> build.
> Maybe other two options would either a prominent compiler warning if those 
> methods override ones from a superclass so that you at least have a chance to 
> get aware of the problem,
> or maybe it could even be made in a way that the compiler-inserted methods 
> consider the superclass methods by calling them at an appropriate place.
> The last solution would maybe be optimal as it would then work as expected, 
> unless there are details I don't know why this cannot work.
> If some class does depend on those methods not being overwritten and not just 
> provide convenience like {{GebSpec}}, they can probably also declare the 
> methods {{final}} to prevent static nested subclasses being created.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to