Add check for sealed interfaces
Some checks failed
Build and Test with Maven / Build-and-test-with-Maven (push) Failing after 6m41s

This commit is contained in:
Daniel Holle 2024-09-13 14:23:03 +02:00
parent 72035c48f2
commit eb454aa5b2
4 changed files with 16 additions and 3 deletions

View File

@ -3,7 +3,7 @@ import java.lang.Object;
import java.lang.Float;
import java.lang.String;
sealed interface List permits LinkedElem {}
sealed interface List permits LinkedElem, Elem {}
public record LinkedElem(Integer a,List l) implements List{} //Implementiert List und wird auch permittet

View File

@ -1599,6 +1599,16 @@ public class Codegen {
if (!(clazz instanceof TargetInterface))
access |= ACC_SUPER;
// Check sealed
for (var intf : clazz.implementingInterfaces()) {
var intfClass = compiler.getClass(new JavaClassName(intf.name()));
if (intfClass.isSealed()) {
if (intfClass.getPermittedSubtypes().stream().noneMatch(type -> type.getName().equals(new JavaClassName(className)))) {
throw new CodeGenException("Sealed interface " + intfClass.getClassName() + " doesn't permit class " + className);
}
}
}
var signature = generateSignature(clazz, clazz.generics());
var interfaces = clazz.implementingInterfaces().stream().map(TargetType::getInternalName).toArray(String[]::new);
var superType = clazz.superType() != null ? clazz.superType().getInternalName() : "java/lang/Object";

View File

@ -393,12 +393,12 @@ public class SyntaxTreeGenerator {
if (!Objects.isNull(ctx.EXTENDS())) {
extendedInterfaces.addAll(convert(ctx.typeList(0), generics));
}
List<RefType> permittedSubtypes = new ArrayList<>();
List<RefType> permittedSubtypes = null;
// Ist Bit für 'sealed'-Modifier gesetzt
if ((modifiers & 4096) != 0) {
if (!Objects.isNull(ctx.PERMITS())) {
// permitted subtypes sind letzte typeList (siehe Grammatikregel 'classDeclaration')
permittedSubtypes.addAll(convert(ctx.typeList(ctx.typeList().size() - 1), generics));
permittedSubtypes = new ArrayList<>(convert(ctx.typeList(ctx.typeList().size() - 1), generics));
} else {
// falls sealed modifier ohne 'permits'-List oder umgekehrt
throw new NotImplementedException("Invalid sealed class declaration");

View File

@ -86,6 +86,9 @@ public class ClassOrInterface extends SyntaxTreeNode implements TypeScope {
return staticInitializer;
}
public boolean isSealed() { return permittedSubtypes != null; }
public List<RefType> getPermittedSubtypes() { return permittedSubtypes != null ? permittedSubtypes : List.of(); }
public boolean isInterface() {
return (Modifier.INTERFACE & this.getModifiers()) != 0;
}