com.redhat.ceylon.model.loader.model.AnnotationTarget Maven / Gradle / Ivy
package com.redhat.ceylon.model.loader.model;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import com.redhat.ceylon.model.loader.mirror.AnnotationMirror;
import com.redhat.ceylon.model.typechecker.model.Class;
/**
* Mirrors the elements of {@link java.lang.annotation.ElementType} for
* the purpose of targeting java annotations.
*/
public enum AnnotationTarget {
TYPE {
@Override
public Set outputs() {
return Collections.singleton(OutputElement.TYPE);
}
},
FIELD {
@Override
public Set outputs() {
return Collections.singleton(OutputElement.FIELD);
}
},
METHOD {
@Override
public Set outputs() {
HashSet result = new HashSet(3);
result.add(OutputElement.METHOD);
result.add(OutputElement.GETTER);
result.add(OutputElement.SETTER);
return result;
}
},
PARAMETER {
@Override
public Set outputs() {
return Collections.singleton(OutputElement.PARAMETER);
}
},
CONSTRUCTOR {
@Override
public Set outputs() {
return Collections.singleton(OutputElement.CONSTRUCTOR);
}
},
LOCAL_VARIABLE {
@Override
public Set outputs() {
return Collections.singleton(OutputElement.LOCAL_VARIABLE);
}
},
ANNOTATION_TYPE {
@Override
public Set outputs() {
return Collections.singleton(OutputElement.ANNOTATION_TYPE);
}
},
PACKAGE {
@Override
public Set outputs() {
return Collections.singleton(OutputElement.PACKAGE);
}
},
TYPE_USE {
@Override
public Set outputs() {
return Collections.emptySet();
}
},
TYPE_PARAMETER {
@Override
public Set outputs() {
return Collections.emptySet();
}
};
public abstract Set outputs();
/**
* Returns the elements in the {@code @Target} annotation of the given
* {@code @interface}, or null if
* the annotation type lacks the {@code @Target} annotation.
*/
public static EnumSet getAnnotationTarget(LazyInterface annotationType) {
AnnotationMirror targetAnno = annotationType.classMirror.getAnnotation("java.lang.annotation.Target");
if (targetAnno != null) {
@SuppressWarnings("unchecked")
List targets = (List)targetAnno.getValue();
EnumSet result = EnumSet.noneOf(AnnotationTarget.class);
for (String name : targets) {
result.add(AnnotationTarget.valueOf(name));
}
return result;
}
return null;
}
/**
* Returns the possible targets of the given annotation proxy class
* (according to the {@code @Target} of the {@code @interface} that
* the class is a proxy to),
* or null if {@code @interface} lacks a {@code @Target} or if
* the given class is not an annotation proxy.
*/
private static EnumSet annotationTargets(Class annotationClass) {
if (annotationClass instanceof AnnotationProxyClass) {
return getAnnotationTarget(((AnnotationProxyClass)annotationClass).iface);
} else {
return null;
}
}
/**
* Given a set of Java annotation constraints, returns the
* possible Java elements that could be generated by Ceylon elements
* that the annotation could be applied to.
* @param targets
* @return
*/
private static EnumSet possibleCeylonTargets(EnumSet targets) {
if (targets == null) {
targets = EnumSet.allOf(AnnotationTarget.class);
}
EnumSet result = EnumSet.noneOf(OutputElement.class);
for (AnnotationTarget t : targets) {
result.addAll(t.outputs());
}
return result;
}
/**
* The set of program elements the given
* annotation class could be applied to, according only to
* the {@code @Target}s on the corresponding {@code @interface}.
* @param annotationClass
* @return
*/
public static EnumSet outputTargets(Class annotationClass) {
return possibleCeylonTargets(annotationTargets(annotationClass));
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy