Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
Browse files
8247849: permits clause of sealed interfaces should not allow paramet…
…erized types

Reviewed-by: jlahoda
  • Loading branch information
Vicente Romero committed Jun 25, 2020
1 parent 8a42442 commit fc8276847829fd063bacafd13cc7235643d75e84
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 19 deletions.
@@ -3761,15 +3761,7 @@ protected JCClassDecl classDeclaration(JCModifiers mods, Comment dc) {
nextToken();
implementing = typeList();
}
List<JCExpression> permitting = List.nil();
if (allowSealedTypes && token.kind == IDENTIFIER && token.name() == names.permits) {
checkSourceLevel(Feature.SEALED_CLASSES);
if ((mods.flags & Flags.SEALED) == 0) {
log.error(token.pos, Errors.InvalidPermitsClause(Fragments.ClassIsNotSealed("class")));
}
nextToken();
permitting = qualidentList(false);
}
List<JCExpression> permitting = permitsClause(mods, "class");
List<JCTree> defs = classInterfaceOrRecordBody(name, false, false);
JCClassDecl result = toP(F.at(pos).ClassDef(
mods, name, typarams, extending, implementing, permitting, defs));
@@ -3849,15 +3841,7 @@ protected JCClassDecl interfaceDeclaration(JCModifiers mods, Comment dc) {
nextToken();
extending = typeList();
}
List<JCExpression> permitting = List.nil();
if (allowSealedTypes && token.kind == IDENTIFIER && token.name() == names.permits) {
checkSourceLevel(Feature.SEALED_CLASSES);
if ((mods.flags & Flags.SEALED) == 0) {
log.error(token.pos, Errors.InvalidPermitsClause(Fragments.ClassIsNotSealed("interface")));
}
nextToken();
permitting = typeList();
}
List<JCExpression> permitting = permitsClause(mods, "interface");
List<JCTree> defs;
defs = classInterfaceOrRecordBody(name, true, false);
JCClassDecl result = toP(F.at(pos).ClassDef(
@@ -3866,6 +3850,18 @@ protected JCClassDecl interfaceDeclaration(JCModifiers mods, Comment dc) {
return result;
}

List<JCExpression> permitsClause(JCModifiers mods, String classOrInterface) {
if (allowSealedTypes && token.kind == IDENTIFIER && token.name() == names.permits) {
checkSourceLevel(Feature.SEALED_CLASSES);
if ((mods.flags & Flags.SEALED) == 0) {
log.error(token.pos, Errors.InvalidPermitsClause(Fragments.ClassIsNotSealed(classOrInterface)));
}
nextToken();
return qualidentList(false);
}
return List.nil();
}

/** EnumDeclaration = ENUM Ident [IMPLEMENTS TypeList] EnumBody
* @param mods The modifiers starting the enum declaration
* @param dc The documentation comment for the enum, or null.
@@ -768,19 +768,67 @@ sealed class C permits Sub {}
}
}

public void testParameterizedPermitted() {
private static String[] PRIMITIVES_VOID_AND_PRIMITIVE_ARRAYS = new String[] {
"byte", "short", "int", "long", "float", "double", "char", "boolean", "void",
"byte[]", "short[]", "int[]", "long[]", "float[]", "double[]", "char[]", "boolean[]"
};

public void testPermitsClause() {
for (String s : List.of(
// can't include a parameterized type
"""
sealed class C<T> permits Sub<T> {}
final class Sub<T> extends C<T> {}
""",
"""
sealed class C permits Sub<String> {}
final class Sub<T> extends C {}
""",
"""
sealed class C permits Sub<String> {}
non-sealed class Sub<T> extends C {}
""",
"""
sealed interface IC permits ID<String> {}
non-sealed interface ID<T> extends IC {}
""",

// can't include an array type
"""
sealed class C<T> permits Sub[] {}
final class Sub<T> extends C<T> {}
""",
"""
sealed class C permits Sub[] {}
non-sealed class Sub<T> extends C {}
""",
"""
sealed interface IC permits ID[] {}
non-sealed interface ID<T> extends IC {}
"""
)) {
assertFail("compiler.err.expected", s);
}

for (String s : List.of(
// can't include primitives, void or primitive arrays
"""
sealed class C<T> permits # {}
final class Sub<T> extends C<T> {}
""",
"""
sealed class C permits # {}
non-sealed class Sub<T> extends C {}
""",
"""
sealed interface IC permits # {}
non-sealed interface ID<T> extends IC {}
"""
)) {
for (String t: PRIMITIVES_VOID_AND_PRIMITIVE_ARRAYS){
assertFail("compiler.err.expected", s, t);
}
}
}

private Path[] findJavaFiles(Path... paths) throws IOException {

0 comments on commit fc82768

Please sign in to comment.