codeconsole opened a new pull request, #3188:
URL: https://github.com/apache/groovy/pull/3188

   An implicit-this method call from a closure whose resolve strategy is 
`DELEGATE_FIRST` and whose delegate is null is sent to `NullObject`. Instead of 
reaching the owner, it throws `NullPointerException: Cannot invoke method foo() 
on null object`:
   
   ```groovy
   class Owner {
       def foo() { 'owner' }
       def test() {
           def c = { -> foo() }
           c.resolveStrategy = Closure.DELEGATE_FIRST
           c.delegate = null
           c()
       }
   }
   assert new Owner().test() == 'owner' // NPE since 4.0.0
   ```
   
   `OWNER_FIRST` with a null owner (the delegate is never tried) and a 
dehydrated closure behave the same way. A method neither candidate has throws 
the NPE instead of `MissingMethodException`. Since GROOVY-11858, `toString()` 
and `is(x)` in such a closure run against `NullObject`. Groovy 3 skipped a null 
delegate or owner, and `Closure.getProperty` still does. Seen in 4.0.33, 5.0.8 
and 6.0.0.
   
   GROOVY-7232 dropped the `instanceof GroovyObject` check from the 
`DELEGATE_FIRST` and `OWNER_FIRST` branches of `ClosureMetaClass.invokeMethod` 
so that non-Groovy delegates work, and that also let null through. Those 
branches now require a non-null delegate or owner before trying it. The 
`*_ONLY` branches already exclude null.
   
   This and #3185 (GROOVY-12664) change different lines of 
`ClosureMetaClass.invokeMethod`; both append tests to `ClosureDelegationTest`.
   
   ## Tests
   
   `ClosureDelegationTest` gains `testDelegateFirstWithNullDelegate` (owner 
method, `toString()` and `is`), 
`testDelegateFirstWithNullDelegateStaticContext`, 
`testDelegateFirstWithNullDelegateTypeChecked`, `testOwnerFirstWithNullOwner`, 
`testMissingMethodWithNullDelegate` and `testDehydratedClosureMissingMethod`. 
All six fail without the change. `groovy.lang.*Closure*`, `groovy.*Closure*`, 
`gls.invocation.*`, `org.codehaus.groovy.runtime.*`, `groovy.transform.stc.*`, 
`org.codehaus.groovy.classgen.asm.sc.*` and `groovy.ThisAndSuperTest` pass. The 
Checkstyle and CodeNarc gates pass.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to