[
https://issues.apache.org/jira/browse/GROOVY-12570?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18135275#comment-18135275
]
ASF GitHub Bot commented on GROOVY-12570:
-----------------------------------------
codeconsole commented on PR #3099:
URL: https://github.com/apache/groovy/pull/3099#issuecomment-6527470228
@daniellansun
1. CI: the push of this commit starts a new run.
2. Search order. `superMethodOfAnotherRuntimePackage` returns from the inner
loop at the first superclass method with the same name and parameters. That
nearest method is used only if it is package-private of another run-time
package; otherwise the method returns `null` and the entry is dropped as
before, so it hides any deeper method. Added the comment on that return
(ef2eebada2).
`Groovy12568.testSuperCallReachesNearestSuperclassMethodOfSameNameAndParameters`
(indy on and off) has `A` in loader 1 with a package-private `pm()`, and four
intermediate classes extending it: `MidOfOtherLoader` (package-private `pm()`),
`PublicMid` (public `pm()`) and `MidWithoutPm` in loader 2, and
`MidOfSameLoader` (package-private `pm()`) in loader 3, the subclasses' loader.
For each, a dynamic `D…` and a `@CompileStatic` `S…` subclass override `pm()`
and call `super.pm()`; each call reaches the nearest method
(`MidOfOtherLoader`, `PublicMid`, `A`, `MidOfSameLoader`), never a deeper
`A.pm()`. A dynamic `D` reaches a public or same-run-time-package intermediate
through its `super$` method, so the early return decides the entry only for a
class without one, such as `S`; the test asserts the meta-class has no super
entry there rather than `A.pm()`, and fails if the loop goes on past the
nearest method. `testSuperCallOfPackagePrivateMethodOfClassOfAnotherPackage`
checks the package-name condition: for `p.B extends q.M`, `super.pm()` still
throws `MissingMethodException`.
3. Super index entry. `MetaClassImpl.getMethodWithoutCaching(sender, name,
types, true)` is public and returns the super index entry as it is.
`testSuperMethodsOfMetaClassForPackagePrivateMethodsOfClassOfAnotherClassLoader`
asserts that `B`'s super entries are `M`'s methods and that invoking them runs
`M`'s code, for the overloads `pm()` and `pm(String)` (a `FastArray` entry) and
`qm()` (a single entry), and that the non-super lookup still gives `B`'s
methods; the search-order test checks the super entry of each of its 8 classes.
I also removed the `isDGM(method)` check from
`superMethodOfAnotherRuntimePackage`: `notSuperUseful`, which guards both
calls, already excludes DGM methods. All lines and branches of the
`MetaClassImpl` change are covered now; the other partials Codecov shows here
are #3097's lines.
The new tests fail without the change (`MissingMethodException` for `pm`,
and no super entry). The Checkstyle and CodeNarc gates pass.
> super.m() cannot reach a package-private method of a superclass defined by
> another class loader
> -----------------------------------------------------------------------------------------------
>
> Key: GROOVY-12570
> URL: https://issues.apache.org/jira/browse/GROOVY-12570
> Project: Groovy
> Issue Type: Bug
> Components: groovy-runtime
> Affects Versions: 6.0.0
> Reporter: Scott Murphy Heiberg
> Priority: Major
>
> {code:groovy}
> def shell = new GroovyShell()
> shell.evaluate '''package p
> class M { @groovy.transform.PackageScope String pm() { 'M' } }
> true
> '''
> shell.evaluate '''package p
> class B extends M { // same package name as M, but another class loader
> String pm() { 'B>' + super.pm() }
> }
> new B().pm()
> ''' // MissingMethodException; expected 'B>M'
> {code}
> The JVM does not let {{B.pm()}} override a package-private method of another
> run-time package, so no {{super$}} method can call it, and the meta-class
> drops the method from the methods for super calls without keeping the
> superclass method. The same holds under {{@CompileStatic}}. Expected:
> {{super.pm()}} calls {{M.pm()}}.
> PR: https://github.com/apache/groovy/pull/3099
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)