Search in sources :

Example 1 with AnnotationProxyClass

use of com.redhat.ceylon.model.loader.model.AnnotationProxyClass in project ceylon-compiler by ceylon.

the class AnnotationUtil method interopAnnotationTargeting.

/**
 * Returns the set of output program elements that the given annotation
 * could be applied to. If the {@code errors} flag is true then add
 * warnings/errors to the tree about ambigous/impossible targets.
 */
public static EnumSet<OutputElement> interopAnnotationTargeting(EnumSet<OutputElement> outputs, Tree.Annotation annotation, boolean errors) {
    Declaration annoCtor = ((Tree.BaseMemberExpression) annotation.getPrimary()).getDeclaration();
    if (annoCtor instanceof AnnotationProxyMethod) {
        AnnotationProxyMethod proxyCtor = (AnnotationProxyMethod) annoCtor;
        AnnotationProxyClass annoClass = proxyCtor.getProxyClass();
        EnumSet<OutputElement> possibleTargets;
        if (proxyCtor.getAnnotationTarget() != null) {
            possibleTargets = EnumSet.of(proxyCtor.getAnnotationTarget());
        } else {
            possibleTargets = AnnotationTarget.outputTargets(annoClass);
        }
        EnumSet<OutputElement> actualTargets = possibleTargets.clone();
        actualTargets.retainAll(outputs);
        if (actualTargets.size() > 1) {
            if (errors) {
                StringBuffer sb = new StringBuffer();
                sb.append("ambiguous annotation target: ").append(annoCtor.getName());
                sb.append(" could be applied to several targets, use one of ");
                for (Iterator<OutputElement> iterator = actualTargets.iterator(); iterator.hasNext(); ) {
                    OutputElement x = iterator.next();
                    sb.append(Naming.getDisambigAnnoCtorName((Interface) ((AnnotationProxyMethod) annoCtor).getProxyClass().iface, x));
                    if (iterator.hasNext()) {
                        sb.append(", ");
                    }
                }
                sb.append(" to disambiguate");
                annotation.addUsageWarning(Warning.ambiguousAnnotation, sb.toString(), Backend.Java);
            }
            return null;
        } else if (actualTargets.size() == 0) {
            if (errors) {
                annotation.addError("no target for " + annoCtor.getName() + " annotation: @Target of @interface " + ((AnnotationProxyClass) annoClass).iface.getName() + " lists " + possibleTargets + " but annotated element tranforms to " + outputs, Backend.Java);
            }
        }
        return actualTargets;
    } else {
        return null;
    }
}
Also used : AnnotationProxyMethod(com.redhat.ceylon.model.loader.model.AnnotationProxyMethod) OutputElement(com.redhat.ceylon.model.loader.model.OutputElement) AnnotationProxyClass(com.redhat.ceylon.model.loader.model.AnnotationProxyClass) Declaration(com.redhat.ceylon.model.typechecker.model.Declaration) TypeDeclaration(com.redhat.ceylon.model.typechecker.model.TypeDeclaration) Interface(com.redhat.ceylon.model.typechecker.model.Interface)

Aggregations

AnnotationProxyClass (com.redhat.ceylon.model.loader.model.AnnotationProxyClass)1 AnnotationProxyMethod (com.redhat.ceylon.model.loader.model.AnnotationProxyMethod)1 OutputElement (com.redhat.ceylon.model.loader.model.OutputElement)1 Declaration (com.redhat.ceylon.model.typechecker.model.Declaration)1 Interface (com.redhat.ceylon.model.typechecker.model.Interface)1 TypeDeclaration (com.redhat.ceylon.model.typechecker.model.TypeDeclaration)1