Skip to content

Commit

Permalink
GROOVY-10148: Groovy should support sealed classes (tweak error messa…
Browse files Browse the repository at this point in the history
…ge and additional test cases)
  • Loading branch information
paulk-asert committed Aug 9, 2021
1 parent 4ff2f85 commit 3dcce32
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,7 @@ private void checkAbstractDeclaration(MethodNode methodNode) {
private void checkClassForExtendingFinalOrSealed(ClassNode cn) {
boolean sealed = Boolean.TRUE.equals(cn.getNodeMetaData(Sealed.class));
if (sealed && cn.getPermittedSubclasses().isEmpty()) {
addError("Sealed " + getDescription(cn) + " has no explicit or implicit permitted classes.", cn);
addError("Sealed " + getDescription(cn) + " has no explicit or implicit permitted subclasses.", cn);
return;
}
boolean isFinal = isFinal(cn.getModifiers());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,14 @@ public void visit(ASTNode[] nodes, SourceUnit source) {

if (parent instanceof ClassNode) {
ClassNode cNode = (ClassNode) parent;
if (cNode.isEnum()) {
addError("@" + SEALED_CLASS.getSimpleName() + " not allowed for enum", cNode);
return;
}
if (cNode.isAnnotationDefinition()) {
addError("@" + SEALED_CLASS.getSimpleName() + " not allowed for annotation definition", cNode);
return;
}
cNode.putNodeMetaData(SEALED_CLASS, Boolean.TRUE);
List<ClassNode> newSubclasses = getMemberClassList(anno, "permittedSubclasses");
if (newSubclasses != null) {
Expand Down
29 changes: 29 additions & 0 deletions src/test/org/codehaus/groovy/transform/SealedTransformTest.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,35 @@ class SealedTransformTest {
''').message.contains("The class 'Ellipse' cannot be non-sealed as it has no sealed parent")
}

@Test
void testInvalidSealedEnum() {
assert shouldFail(MultipleCompilationErrorsException, '''
import groovy.transform.Sealed
@Sealed enum Shape { SQUARE, CIRCLE }
''').message.contains("@Sealed not allowed for enum")
}

@Test
void testInvalidSealedAnnotationDefinition() {
assert shouldFail(MultipleCompilationErrorsException, '''
import groovy.transform.Sealed
@Sealed @interface Shape { }
''').message.contains("@Sealed not allowed for annotation definition")
}

@Test
void testNoSubclasses() {
def message = shouldFail(MultipleCompilationErrorsException, '''
import groovy.transform.Sealed
@Sealed class Shape { }
''').message
assert message.contains("Sealed class 'Shape' has no")
assert message.contains("permitted subclasses")
}

@Test
void testUnknownType() {
assert shouldFail(MultipleCompilationErrorsException, '''
Expand Down

0 comments on commit 3dcce32

Please sign in to comment.