Search in sources :

Example 1 with NonSealed

use of groovy.transform.NonSealed in project groovy by apache.

the class ClassCompletionVerifier method checkClassForExtendingFinalOrSealed.

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 subclasses.", cn);
        return;
    }
    boolean isFinal = isFinal(cn.getModifiers());
    if (sealed && isFinal) {
        addError("The " + getDescription(cn) + " cannot be both final and sealed.", cn);
        return;
    }
    boolean explicitNonSealed = nonSealed(cn);
    ClassNode superCN = cn.getSuperClass();
    boolean sealedSuper = superCN != null && superCN.isSealed();
    boolean sealedInterface = Arrays.stream(cn.getInterfaces()).anyMatch(ClassNode::isSealed);
    boolean nonSealedSuper = superCN != null && nonSealed(superCN);
    boolean nonSealedInterface = Arrays.stream(cn.getInterfaces()).anyMatch(this::nonSealed);
    if (explicitNonSealed && !(sealedSuper || sealedInterface || nonSealedSuper || nonSealedInterface)) {
        addError("The " + getDescription(cn) + " cannot be non-sealed as it has no sealed parent.", cn);
        return;
    }
    if (sealedSuper || sealedInterface) {
        if (sealed && explicitNonSealed) {
            addError("The " + getDescription(cn) + " cannot be both sealed and non-sealed.", cn);
            return;
        }
        if (isFinal && explicitNonSealed) {
            addError("The " + getDescription(cn) + " cannot be both final and non-sealed.", cn);
            return;
        }
        if (sealedSuper) {
            checkSealedParent(cn, superCN);
        }
        if (sealedInterface) {
            for (ClassNode candidate : cn.getInterfaces()) {
                if (candidate.isSealed()) {
                    checkSealedParent(cn, candidate);
                }
            }
        }
    }
    if (superCN == null || !isFinal(superCN.getModifiers()))
        return;
    addError("You are not allowed to extend the final " + getDescription(superCN) + ".", cn);
}
Also used : InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) ClassNode(org.codehaus.groovy.ast.ClassNode) NonSealed(groovy.transform.NonSealed) Sealed(groovy.transform.Sealed)

Aggregations

NonSealed (groovy.transform.NonSealed)1 Sealed (groovy.transform.Sealed)1 ClassNode (org.codehaus.groovy.ast.ClassNode)1 InnerClassNode (org.codehaus.groovy.ast.InnerClassNode)1