From d5c155c681e207c9d9c83385f3318b0b7d37b4ce Mon Sep 17 00:00:00 2001 From: Aosen Xiong Date: Tue, 7 May 2024 20:38:03 -0400 Subject: [PATCH] Further clean up --- .../PICONoInitAnnotatedTypeFactory.java | 47 ++++------------ .../pico/typecheck/PICONoInitVisitor.java | 56 ++----------------- 2 files changed, 17 insertions(+), 86 deletions(-) diff --git a/src/main/java/pico/typecheck/PICONoInitAnnotatedTypeFactory.java b/src/main/java/pico/typecheck/PICONoInitAnnotatedTypeFactory.java index 78e59aa..6a71dcd 100644 --- a/src/main/java/pico/typecheck/PICONoInitAnnotatedTypeFactory.java +++ b/src/main/java/pico/typecheck/PICONoInitAnnotatedTypeFactory.java @@ -130,10 +130,7 @@ public QualifierHierarchy createQualifierHierarchy() { @Override public ParameterizedExecutableType constructorFromUse(NewClassTree tree) { - boolean hasExplicitAnnos = false; - if (!getExplicitNewClassAnnos(tree).isEmpty()) { - hasExplicitAnnos = true; - } + boolean hasExplicitAnnos = !getExplicitNewClassAnnos(tree).isEmpty(); ParameterizedExecutableType mType = super.constructorFromUse(tree); AnnotatedExecutableType method = mType.executableType; if (!hasExplicitAnnos && method.getReturnType().hasAnnotation(RECEIVER_DEPENDANT_MUTABLE)) { @@ -173,10 +170,7 @@ public PICOPropagationTreeAnnotator(AnnotatedTypeFactory atypeFactory) { public Void visitNewArray(NewArrayTree tree, AnnotatedTypeMirror type) { AnnotatedTypeMirror componentType = ((AnnotatedTypeMirror.AnnotatedArrayType) type).getComponentType(); - boolean noExplicitATM = false; - if (!componentType.hasAnnotation(RECEIVER_DEPENDANT_MUTABLE)) { - noExplicitATM = true; - } + boolean noExplicitATM = !componentType.hasAnnotation(RECEIVER_DEPENDANT_MUTABLE); super.visitNewArray(tree, type); // if new explicit anno before, but RDM after, the RDM must come from the type // declaration bound @@ -189,10 +183,7 @@ public Void visitNewArray(NewArrayTree tree, AnnotatedTypeMirror type) { @Override public Void visitTypeCast(TypeCastTree node, AnnotatedTypeMirror type) { - boolean hasExplicitAnnos = false; - if (!type.getAnnotations().isEmpty()) { - hasExplicitAnnos = true; - } + boolean hasExplicitAnnos = !type.getAnnotations().isEmpty(); super.visitTypeCast(node, type); if (!hasExplicitAnnos && type.hasAnnotation(RECEIVER_DEPENDANT_MUTABLE)) { type.replaceAnnotation(MUTABLE); @@ -200,19 +191,6 @@ public Void visitTypeCast(TypeCastTree node, AnnotatedTypeMirror type) { return null; } - // - /** - * Because TreeAnnotator runs before DefaultForTypeAnnotator, implicitly immutable types are - * not guaranteed to always have immutable annotation. If this happens, we manually add - * immutable to type. We use addMissingAnnotations because we want to respect existing - * annotation on type - */ - private void applyImmutableIfImplicitlyImmutable(AnnotatedTypeMirror type) { - if (PICOTypeUtil.isImplicitlyImmutableType(type)) { - type.addMissingAnnotations(new HashSet<>(Collections.singletonList(IMMUTABLE))); - } - } - @Override public Void visitBinary(BinaryTree node, AnnotatedTypeMirror type) { return null; @@ -360,17 +338,14 @@ public Void visitExecutable(AnnotatedExecutableType t, Void p) { // for now: default array in receiver, parameter and return type to RDM if (t.getReceiverType() != null) { if (PICOTypeUtil.isArrayType(t.getReceiverType(), atypeFactory)) { - switch (t.toString()) { - case "Object clone(Array this)": - // Receiver type will not be viewpoint adapted: - // SyntheticArrays.replaceReturnType() will rollback the viewpoint adapt - // result. - // Use readonly to allow all invocations. - if (!t.getReceiverType().hasAnnotationInHierarchy(READONLY)) - t.getReceiverType().replaceAnnotation(READONLY); - // The return type will be fixed by SyntheticArrays anyway. - // Qualifiers added here will not have effect. - break; + if (t.toString().equals("Object clone(Array this)")) {// Receiver type will not be viewpoint adapted: + // SyntheticArrays.replaceReturnType() will rollback the viewpoint adapt + // result. + // Use readonly to allow all invocations. + if (!t.getReceiverType().hasAnnotationInHierarchy(READONLY)) + t.getReceiverType().replaceAnnotation(READONLY); + // The return type will be fixed by SyntheticArrays anyway. + // Qualifiers added here will not have effect. } } } diff --git a/src/main/java/pico/typecheck/PICONoInitVisitor.java b/src/main/java/pico/typecheck/PICONoInitVisitor.java index 125cd56..8ff2477 100644 --- a/src/main/java/pico/typecheck/PICONoInitVisitor.java +++ b/src/main/java/pico/typecheck/PICONoInitVisitor.java @@ -51,15 +51,13 @@ import pico.common.PICOTypeUtil; import pico.common.ViewpointAdapterGettable; -/** Created by mier on 20/06/17. Enforce PICO type rules. */ public class PICONoInitVisitor extends BaseTypeVisitor { - private final boolean shouldOutputFbcError; final Map fbcViolatedMethods; public PICONoInitVisitor(BaseTypeChecker checker) { super(checker); - shouldOutputFbcError = checker.hasOption("printFbcErrors"); + boolean shouldOutputFbcError = checker.hasOption("printFbcErrors"); fbcViolatedMethods = shouldOutputFbcError ? new HashMap<>() : null; } @@ -107,33 +105,6 @@ public boolean isValidUse(AnnotatedTypeMirror.AnnotatedArrayType type, Tree tree return !AnnotationUtils.areSame(used, BOTTOM); } - private static boolean isAnnoValidUse(AnnotationMirror declared, AnnotationMirror used) { - if (AnnotationUtils.areSame(declared, RECEIVER_DEPENDANT_MUTABLE) - || AnnotationUtils.areSame(declared, READONLY)) { - // Element is declared with @ReceiverDependantMutable bound, any instantiation is - // allowed. We don't use - // a subtype check to validate the correct usage here. Because @Readonly is the super - // type of - // @ReceiverDependantMutable, but it's still considered valid usage. - return true; - } - - if (AnnotationUtils.areSame(declared, MUTABLE) - && !(AnnotationUtils.areSame(used, IMMUTABLE) - || AnnotationUtils.areSame(used, RECEIVER_DEPENDANT_MUTABLE))) { - return true; - } - - if (AnnotationUtils.areSame(declared, IMMUTABLE) - && !(AnnotationUtils.areSame(used, MUTABLE) - || AnnotationUtils.areSame(used, RECEIVER_DEPENDANT_MUTABLE))) { - return true; - } - - // All valid cases are listed above. So returns false here. - return false; - } - private boolean isAdaptedSubtype(AnnotationMirror lhs, AnnotationMirror rhs) { ExtendedViewpointAdapter vpa = ((ViewpointAdapterGettable) atypeFactory).getViewpointAdapter(); @@ -362,17 +333,13 @@ private boolean allowWrite(AnnotatedTypeMirror receiverType, ExpressionTree vari // the field // is declared as final, Java compiler will catch that, and we couldn't have reached this // point + // If the receiver is mutable, we allow assigning/reassigning + // } else if (TreeUtils.elementFromUse(variable)) { + // // If the field is not initialized, we allow assigning/reassigning + // return true; if (PICOTypeUtil.isAssigningAssignableField(variable, atypeFactory)) { return isAllowedAssignableField(receiverType, variable); - } else if (receiverType.hasAnnotation(MUTABLE)) { - // If the receiver is mutable, we allow assigning/reassigning - return true; - // } else if (TreeUtils.elementFromUse(variable)) { - // // If the field is not initialized, we allow assigning/reassigning - // return true; - } - - return false; + } else return receiverType.hasAnnotation(MUTABLE); } private boolean isAllowedAssignableField( @@ -495,17 +462,6 @@ public Void visitMethodInvocation(MethodInvocationTree node, Void p) { return null; } - private void saveFbcViolatedMethods( - ExecutableElement method, String actualReceiver, String declaredReceiver) { - if (actualReceiver.contains("@UnderInitialization") - && declaredReceiver.contains("@Initialized")) { - String key = ElementUtils.enclosingTypeElement(method) + "#" + method; - Integer times = - fbcViolatedMethods.get(key) == null ? 1 : fbcViolatedMethods.get(key) + 1; - fbcViolatedMethods.put(key, times); - } - } - @Override protected AnnotationMirrorSet getExceptionParameterLowerBoundAnnotations() { AnnotationMirrorSet result = new AnnotationMirrorSet();