Search in sources :

Example 1 with UI

use of org.checkerframework.checker.guieffect.qual.UI in project checker-framework by typetools.

the class GuiEffectTypeFactory method findInheritedEffectRange.

public Effect.EffectRange findInheritedEffectRange(TypeElement declaringType, ExecutableElement overridingMethod, boolean issueConflictWarning, Tree errorNode) {
    assert (declaringType != null);
    ExecutableElement ui_override = null;
    ExecutableElement safe_override = null;
    ExecutableElement poly_override = null;
    // We must account for explicit annotation, type declaration annotations, and package
    // annotations
    boolean isUI = (getDeclAnnotation(overridingMethod, UIEffect.class) != null || isUIType(declaringType)) && getDeclAnnotation(overridingMethod, SafeEffect.class) == null;
    boolean isPolyUI = getDeclAnnotation(overridingMethod, PolyUIEffect.class) != null;
    // TODO: We must account for @UI and @AlwaysSafe annotations for extends
    // and implements clauses, and do the proper substitution of @Poly effects and quals!
    // List<? extends TypeMirror> interfaces = declaringType.getInterfaces();
    TypeMirror superclass = declaringType.getSuperclass();
    while (superclass != null && superclass.getKind() != TypeKind.NONE) {
        ExecutableElement overrides = findJavaOverride(overridingMethod, superclass);
        if (overrides != null) {
            Effect eff = getDeclaredEffect(overrides);
            assert (eff != null);
            if (eff.isSafe()) {
                // found a safe override
                safe_override = overrides;
                if (isUI && issueConflictWarning) {
                    checker.report(Result.failure("override.effect.invalid", overridingMethod, declaringType, safe_override, superclass), errorNode);
                }
                if (isPolyUI && issueConflictWarning) {
                    checker.report(Result.failure("override.effect.invalid.polymorphic", overridingMethod, declaringType, safe_override, superclass), errorNode);
                }
            } else if (eff.isUI()) {
                // found a ui override
                ui_override = overrides;
            } else {
                assert (eff.isPoly());
                poly_override = overrides;
            // TODO: Is this right? is the supertype covered by the
            // directSuperTypes() method all I need? Or should I be
            // using that utility method that returns a set of
            // annodecl-method pairs given a method that overrides stuff
            // if (isUI && issueConflictWarning) {
            // AnnotatedTypeMirror.AnnotatedDeclaredType supdecl =
            // fromElement((TypeElement)(((DeclaredType)superclass).asElement()));//((DeclaredType)superclass).asElement());
            // // Need to special case an anonymous class with @UI on the decl, because
            // "new @UI Runnable {...}" parses as @UI on an anon class decl extending
            // Runnable
            // boolean isAnonInstantiation =
            // TypesUtils.isAnonymousType(ElementUtils.getType(declaringType)) &&
            // getDeclAnnotation(declaringType, UI.class) != null;
            // if (!isAnonInstantiation && !hasAnnotationByName(supdecl, UI.class)) {
            // checker.report(Result.failure("override.effect.invalid",
            // "non-UI instantiation of "+supdecl), errorNode);
            // If uncommenting this, change the above line to match other calls of
            // Result.failure("override.effect.invalid", ...)
            // }
            // }
            }
        }
        DeclaredType decl = (DeclaredType) superclass;
        superclass = ((TypeElement) decl.asElement()).getSuperclass();
    }
    AnnotatedTypeMirror.AnnotatedDeclaredType annoDecl = fromElement(declaringType);
    for (AnnotatedTypeMirror.AnnotatedDeclaredType ty : annoDecl.directSuperTypes()) {
        ExecutableElement overrides = findJavaOverride(overridingMethod, ty.getUnderlyingType());
        if (overrides != null) {
            Effect eff = getDeclaredEffect(overrides);
            if (eff.isSafe()) {
                // found a safe override
                safe_override = overrides;
                if (isUI && issueConflictWarning) {
                    checker.report(Result.failure("override.effect.invalid", overridingMethod, declaringType, safe_override, ty), errorNode);
                }
                if (isPolyUI && issueConflictWarning) {
                    checker.report(Result.failure("override.effect.invalid.polymorphic", overridingMethod, declaringType, safe_override, ty), errorNode);
                }
            } else if (eff.isUI()) {
                // found a ui override
                ui_override = overrides;
            } else {
                assert (eff.isPoly());
                poly_override = overrides;
                if (isUI && issueConflictWarning) {
                    AnnotatedTypeMirror.AnnotatedDeclaredType supdecl = ty;
                    // Need to special case an anonymous class with @UI on
                    // the decl, because "new @UI Runnable {...}" parses as
                    // @UI on an anon class decl extending Runnable
                    boolean isAnonInstantiation = isAnonymousType(declaringType) && fromElement(declaringType).hasAnnotation(UI.class);
                    if (!isAnonInstantiation && !supdecl.hasAnnotation(UI.class)) {
                        checker.report(Result.failure("override.effect.invalid.nonui", overridingMethod, declaringType, poly_override, supdecl), errorNode);
                    }
                }
            }
        }
    }
    // We don't need to issue warnings for inheriting from poly and a concrete effect.
    if (ui_override != null && safe_override != null && issueConflictWarning) {
        // There may be more than two parent methods, but for now it's
        // enough to know there are at least 2 in conflict
        checker.report(Result.warning("override.effect.warning.inheritance", overridingMethod, declaringType, ui_override.toString(), ui_override.getEnclosingElement().asType().toString(), safe_override.toString(), safe_override.getEnclosingElement().asType().toString()), errorNode);
    }
    Effect min = (safe_override != null ? new Effect(SafeEffect.class) : (poly_override != null ? new Effect(PolyUIEffect.class) : (ui_override != null ? new Effect(UIEffect.class) : null)));
    Effect max = (ui_override != null ? new Effect(UIEffect.class) : (poly_override != null ? new Effect(PolyUIEffect.class) : (safe_override != null ? new Effect(SafeEffect.class) : null)));
    if (debugSpew) {
        System.err.println("Found " + declaringType + "." + overridingMethod + " to have inheritance pair (" + min + "," + max + ")");
    }
    if (min == null && max == null) {
        return null;
    } else {
        return new Effect.EffectRange(min, max);
    }
}
Also used : PolyUI(org.checkerframework.checker.guieffect.qual.PolyUI) UI(org.checkerframework.checker.guieffect.qual.UI) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) TypeMirror(javax.lang.model.type.TypeMirror) PolyUIEffect(org.checkerframework.checker.guieffect.qual.PolyUIEffect) ExecutableElement(javax.lang.model.element.ExecutableElement) SafeEffect(org.checkerframework.checker.guieffect.qual.SafeEffect) PolyUIEffect(org.checkerframework.checker.guieffect.qual.PolyUIEffect) UIEffect(org.checkerframework.checker.guieffect.qual.UIEffect) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) DeclaredType(javax.lang.model.type.DeclaredType)

Aggregations

ExecutableElement (javax.lang.model.element.ExecutableElement)1 DeclaredType (javax.lang.model.type.DeclaredType)1 TypeMirror (javax.lang.model.type.TypeMirror)1 PolyUI (org.checkerframework.checker.guieffect.qual.PolyUI)1 PolyUIEffect (org.checkerframework.checker.guieffect.qual.PolyUIEffect)1 SafeEffect (org.checkerframework.checker.guieffect.qual.SafeEffect)1 UI (org.checkerframework.checker.guieffect.qual.UI)1 UIEffect (org.checkerframework.checker.guieffect.qual.UIEffect)1 AnnotatedTypeMirror (org.checkerframework.framework.type.AnnotatedTypeMirror)1