Skip to content

Commit be6a0d7

Browse files
committed
GROOVY-11292, GROOVY-11750: non-sealed super class
4_0_X backport
1 parent e734926 commit be6a0d7

File tree

5 files changed

+102
-12
lines changed

5 files changed

+102
-12
lines changed

.github/workflows/groovy-build-test-ea.yml

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,8 @@ jobs:
2626
fail-fast: false
2727
matrix:
2828
os: [ubuntu-latest]
29-
java: [17]
3029
# The jdk links of "install-jdk.sh" are sometimes outdated, so we have to download openjdk releases from https://jdk.java.net/ by ourselves.
31-
jdk: ["https://download.java.net/java/GA/jdk20/bdc68b4b9cbc4ebcb30745c85038d91d/36/GPL/openjdk-20_linux-x64_bin.tar.gz",
32-
"https://download.java.net/java/GA/jdk21/fd2272bbf8e04c3dbaee13770090416c/35/GPL/openjdk-21_linux-x64_bin.tar.gz"]
30+
jdk: ['https://download.java.net/java/early_access/jdk25/15/GPL/openjdk-25-ea+15_linux-x64_bin.tar.gz']
3331
runs-on: ${{ matrix.os }}
3432
env:
3533
DEVELOCITY_ACCESS_KEY: ${{ secrets.DEVELOCITY_ACCESS_KEY }}
@@ -43,8 +41,8 @@ jobs:
4341
uses: actions/setup-java@v3
4442
with:
4543
distribution: 'zulu'
46-
java-version: ${{ matrix.java }}
4744
check-latest: true
45+
java-version: 17
4846
- uses: gradle/gradle-build-action@v2
4947
- name: Test with Gradle
5048
run: ./gradlew test -Ptarget.java.home=/home/runner/openjdk

.github/workflows/groovy-build-test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ jobs:
5353
strategy:
5454
fail-fast: false
5555
matrix:
56-
java: [9, 10, 12, 13, 14, 15, 16, 18, 19, 20, 22, 23]
56+
java: [9, 10, 12, 13, 14, 15, 16, 18, 19, 20, 22, 23, 24]
5757
runs-on: ubuntu-latest
5858
steps:
5959
- uses: actions/checkout@v4

src/main/java/org/codehaus/groovy/classgen/ClassCompletionVerifier.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@
1818
*/
1919
package org.codehaus.groovy.classgen;
2020

21-
import groovy.transform.NonSealed;
22-
import groovy.transform.Sealed;
2321
import org.apache.groovy.ast.tools.AnnotatedNodeUtils;
2422
import org.apache.groovy.ast.tools.ClassNodeUtils;
2523
import org.codehaus.groovy.ast.ASTNode;
@@ -317,7 +315,7 @@ private void checkAbstractDeclaration(final MethodNode methodNode) {
317315
}
318316

319317
private void checkClassForExtendingFinalOrSealed(final ClassNode cn) {
320-
boolean sealed = Boolean.TRUE.equals(cn.getNodeMetaData(Sealed.class));
318+
boolean sealed = Boolean.TRUE.equals(cn.getNodeMetaData(groovy.transform.Sealed.class));
321319
if (sealed && cn.getPermittedSubclasses().isEmpty()) {
322320
addError("Sealed " + getDescription(cn) + " has no explicit or implicit permitted subclasses.", cn);
323321
return;
@@ -362,8 +360,12 @@ private void checkClassForExtendingFinalOrSealed(final ClassNode cn) {
362360
addError("You are not allowed to extend the final " + getDescription(superCN) + ".", cn);
363361
}
364362

365-
private boolean nonSealed(final ClassNode node) {
366-
return Boolean.TRUE.equals(node.getNodeMetaData(NonSealed.class));
363+
private boolean nonSealed(final ClassNode cn) {
364+
if (Boolean.TRUE.equals(cn.getNodeMetaData(groovy.transform.NonSealed.class))) {
365+
return true;
366+
}
367+
ClassNode sc = cn.getSuperClass(); // GROOVY-11292, GROOVY-11750: check super class
368+
return (sc != null && sc.isSealed() && !(cn.isSealed() || isFinal(cn.getModifiers())));
367369
}
368370

369371
private void checkSealedParent(final ClassNode cn, final ClassNode parent) {
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package bugs
20+
21+
import org.codehaus.groovy.control.CompilerConfiguration
22+
import org.codehaus.groovy.tools.javac.JavaAwareCompilationUnit
23+
import org.junit.Test
24+
25+
import static groovy.test.GroovyAssert.assertScript
26+
import static groovy.test.GroovyAssert.isAtLeastJdk
27+
import static org.junit.Assume.assumeTrue
28+
29+
final class Groovy11292 {
30+
31+
@Test
32+
void testClassWithNonSealedParent1() {
33+
assumeTrue(isAtLeastJdk('17.0'))
34+
35+
def config = new CompilerConfiguration(
36+
targetDirectory: File.createTempDir(),
37+
jointCompilationOptions: [memStub: true]
38+
)
39+
40+
def parentDir = File.createTempDir()
41+
try {
42+
def a = new File(parentDir, 'A.java')
43+
a.write '''
44+
public sealed class A permits B {}
45+
'''
46+
def b = new File(parentDir, 'B.java')
47+
b.write '''
48+
public non-sealed class B extends A {}
49+
'''
50+
def c = new File(parentDir, 'C.groovy')
51+
c.write '''
52+
class C extends B {}
53+
'''
54+
def d = new File(parentDir, 'D.groovy')
55+
d.write '''
56+
class D extends C {}
57+
'''
58+
def e = new File(parentDir, 'E.groovy')
59+
e.write '''
60+
class E extends B {}
61+
'''
62+
def f = new File(parentDir, 'F.groovy')
63+
f.write '''
64+
class F extends E {}
65+
'''
66+
67+
def loader = new GroovyClassLoader(this.class.classLoader)
68+
def cu = new JavaAwareCompilationUnit(config, loader)
69+
cu.addSources(a, b, c, d, e, f)
70+
cu.compile()
71+
} finally {
72+
config.targetDirectory.deleteDir()
73+
parentDir.deleteDir()
74+
}
75+
}
76+
77+
@Test
78+
void testClassWithNonSealedParent2() {
79+
assertScript '''import java.lang.ref.SoftReference // non-sealed type
80+
81+
class TestReference<T> extends SoftReference<T> {
82+
TestReference(T referent) {
83+
super(referent)
84+
}
85+
}
86+
87+
assert new TestReference(null)
88+
'''
89+
}
90+
}

src/test/groovy/groovy/BreakContinueLabelTest.groovy

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@
1818
*/
1919
package groovy
2020

21-
import org.junit.jupiter.api.Test
21+
import org.junit.Test
2222

23-
import static org.junit.jupiter.api.Assertions.fail
23+
import static org.junit.Assert.fail
2424

2525
final class BreakContinueLabelTest {
2626

0 commit comments

Comments
 (0)