[ 
https://issues.apache.org/jira/browse/GROOVY-12522?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18132040#comment-18132040
 ] 

ASF GitHub Bot commented on GROOVY-12522:
-----------------------------------------

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

   When a class declares its own version of an extension method of its 
superclass, such as `first()` in an `ArrayList` subclass, `getProperties()`, or 
`getText()` in a `File` subclass, `super.first()`, `super.properties` and 
`super.getText()` in dynamic Groovy and under `@TypeChecked` threw 
`MissingMethodException` or `MissingPropertyException`, or called 
`getText(File, String)` with a null charset. Under `@CompileStatic`, 
`super.text += v` compiles to a dynamic property access and failed the same 
way. They now call the superclass's extension method, as they do when the class 
does not declare one. This happens in 4.0.33 to master.
   
   ```groovy
   class Numbers extends ArrayList<Integer> {
       Numbers() { super([1, 2, 3]) }
       Integer first() { -1 }
       def test() { super.first() }  // threw MissingMethodException; now 1
   }
   ```
   
   Split out of #3044.
   
   ## How
   
   For `super` usage, the meta-class replaces a method the class declares with 
the MOP method `super$N$name` of the superclass method it overrides, and drops 
it when there is none. An extension method has no MOP method, so the class's 
method was dropped, and the extension method it had replaced in the method 
index was not restored. It now is: the extension method of the superclass, or 
of an interface it implements, with the same parameters, the one for the most 
specific type. The lookup is built once per class, by name.
   
   ## Tests
   
   `groovy.ThisAndSuperTest`, in all three modes, and in a closure in dynamic 
Groovy and under `@TypeChecked`. They fail without the change. Under 
`@CompileStatic`, a `super` call to an extension method in a closure fails on 
master for another reason, with `NoSuchMethodError`; GROOVY-12519 (#3045) fixes 
that, so the closure case here runs in dynamic Groovy and under `@TypeChecked` 
only. 14,936 tests in the `groovy`, `gls`, `bugs`, 
`org.codehaus.groovy.classgen`, `transform`, `runtime`, `reflection`, 
`vmplugin`, `control` and `ast` packages and the stub generator tests pass. 
`groovy-contracts`, `groovy-typecheckers`, `groovy-ginq`, 
`groovy-macro-library`, `groovy-json`, `groovy-xml` and `groovy-templates` pass 
their tests, and every subproject compiles its main and test sources. The 
Checkstyle and CodeNarc gates pass.
   




> super.name() and super.name miss an extension method that the class overrides
> -----------------------------------------------------------------------------
>
>                 Key: GROOVY-12522
>                 URL: https://issues.apache.org/jira/browse/GROOVY-12522
>             Project: Groovy
>          Issue Type: Bug
>          Components: groovy-runtime
>    Affects Versions: 6.0.0
>            Reporter: Scott Murphy Heiberg
>            Priority: Major
>
> When a class declares its own version of an extension method of its 
> superclass, {{super.name()}} and {{super.name}} in dynamic Groovy and under 
> {{@TypeChecked}} do not find the superclass's extension method:
> {code:groovy}
> class Numbers extends ArrayList<Integer> {
>     Numbers() { super([1, 2, 3]) }
>     Integer first() { -1 }
>     def test() { super.first() }
> }
> class Bean {
>     Map getProperties() { [:] }
>     def test() { super.properties.containsKey('class') }
> }
> class Text extends File {
>     Text(String path) { super(path) }
>     String getText() { 'own' }
>     def test() { [super.getText(), super.text] }
> }
> assert new Numbers().test() == 1 // fails: MissingMethodException: No 
> signature of method: first for class: java.util.ArrayList
> assert new Bean().test()          // fails: MissingPropertyException: No such 
> property: properties for class: Bean
> def file = File.createTempFile('text', '.txt')
> file.text = 'content'
> assert new Text(file.path).test() == ['content', 'content'] // fails: 
> NullPointerException: charsetName
> {code}
> {{super.getText()}} calls {{getText(File, String charset)}} with a null 
> charset, the only {{getText}} left for {{super}}. Without the class's own 
> method, all three work. Under {{@CompileStatic}} these calls work, but 
> {{super.text += 'x'}} compiles to a dynamic property access and fails the 
> same way. Seen in 4.0.33, 5.0.8, 6.0.0 and master.
> For {{super}}, a method the class declares is replaced by the MOP method 
> {{super$2$name}} of the superclass method it overrides, or dropped when there 
> is none. An extension method has no MOP method, so the class's method is 
> dropped, and the extension method it replaced in the method index is not 
> restored.
> Expected: {{super.name()}} and {{super.name}} call the superclass's extension 
> method, as they do when the class does not declare the method.
> PR: https://github.com/apache/groovy/pull/3044



--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to