/** * Returns true if {@code annotation} has a single element named "value", letting us drop the * 'value=' prefix in the source code. */ private static boolean hasSingleValueWithDefaultKey(AnnotationMirror annotation) { if (annotation.getElementValues().size() != 1) { return false; } ExecutableElement key = getOnlyElement(annotation.getElementValues().keySet()); return key.getSimpleName().contentEquals("value"); }
String getConverterClassName(Element el) { AnnotationValue converter = null; for (AnnotationMirror am : el.getAnnotationMirrors()) { Map<? extends ExecutableElement, ? extends AnnotationValue> elementValues = am.getElementValues(); for (ExecutableElement e : elementValues.keySet()) { if ("converter".equals(e.getSimpleName().toString())) { converter = elementValues.get(e); } } } String result = null; if (converter != null && !TokenConverter.class.getCanonicalName().equals(converter)) { String tmp = converter.toString(); if (tmp.endsWith(".class")) { int i = tmp.lastIndexOf('.'); result = tmp.substring(0, i); } else { result = tmp; } } return result; }
/** * Returns the annotation on {@code element} formatted as a Map. This returns a Map rather than an * instance of the annotation interface to work-around the fact that Class and Class[] fields * won't work at code generation time. See * http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5089128 */ public static Map<String, Object> getAnnotation(Class<?> annotationType, Element element) { for (AnnotationMirror annotation : element.getAnnotationMirrors()) { if (!rawTypeToString(annotation.getAnnotationType(), '$').equals(annotationType.getName())) { continue; } Map<String, Object> result = new LinkedHashMap<String, Object>(); for (Method m : annotationType.getMethods()) { result.put(m.getName(), m.getDefaultValue()); } for (Map.Entry<? extends ExecutableElement, ? extends AnnotationValue> e : annotation.getElementValues().entrySet()) { String name = e.getKey().getSimpleName().toString(); Object value = e.getValue().accept(VALUE_EXTRACTOR, null); Object defaultValue = result.get(name); if (!lenientIsInstance(defaultValue.getClass(), value)) { throw new IllegalStateException( String.format( "Value of %s.%s is a %s but expected a %s\n value: %s", annotationType, name, value.getClass().getName(), defaultValue.getClass().getName(), value instanceof Object[] ? Arrays.toString((Object[]) value) : value)); } result.put(name, value); } return result; } return null; // Annotation not found. }
private void parseMethod(Api api, ExecutableElement executableElement) throws IOException { Element actionElement = generator .getProcessingEnvironment() .getElementUtils() .getTypeElement(ApiMethodDoc.class.getName()); TypeMirror apiMethodDocType = actionElement.asType(); for (AnnotationMirror am : executableElement.getAnnotationMirrors()) { if (am.getAnnotationType().equals(apiMethodDocType)) { api.apiMethodDoc = Maps.newHashMap(); for (Map.Entry<? extends ExecutableElement, ? extends AnnotationValue> ee : am.getElementValues().entrySet()) { api.apiMethodDoc.put(ee.getKey().getSimpleName().toString(), ee.getValue()); } break; } } // generator.log("apiMethodDoc: " + api.apiMethodDoc); if (null == api.apiMethodDoc) { generator.log("Method miss @ApiMethodDoc. " + executableElement); return; } api.methodName = executableElement.getSimpleName().toString(); api.methodMapping = executableElement.getAnnotation(RequestMapping.class); api.parameters = Lists.newArrayList(); for (VariableElement var : executableElement.getParameters()) { api.parameters.add(var); } }
@Override public Set<TypeElement> scan(Element e, Set<TypeElement> p) { for (AnnotationMirror annotationMirror : elements.getAllAnnotationMirrors(e)) { Element e2 = annotationMirror.getAnnotationType().asElement(); p.add((TypeElement) e2); } return super.scan(e, p); }
private static boolean hasAnnotationWithName(Element element, String simpleName) { for (AnnotationMirror mirror : element.getAnnotationMirrors()) { String annotationName = mirror.getAnnotationType().asElement().getSimpleName().toString(); if (simpleName.equals(annotationName)) { return true; } } return false; }
private Optional<String> getPointsAnnotationValueIfAny(Element element) { for (AnnotationMirror am : element.getAnnotationMirrors()) { Name annotationName = am.getAnnotationType().asElement().getSimpleName(); if (annotationName.contentEquals("Points")) { String value = getAnnotationValue(am); return Optional.of(value); } } return Optional.absent(); }
private AnnotationMirror getAnnotation(Element element, String type) { if (element != null) { for (AnnotationMirror annotation : element.getAnnotationMirrors()) { if (type.equals(annotation.getAnnotationType().toString())) { return annotation; } } } return null; }
GwtCompatibility(TypeElement type) { Optional<AnnotationMirror> gwtCompatibleAnnotation = Optional.absent(); List<? extends AnnotationMirror> annotations = type.getAnnotationMirrors(); for (AnnotationMirror annotation : annotations) { Name name = annotation.getAnnotationType().asElement().getSimpleName(); if (name.contentEquals("GwtCompatible")) { gwtCompatibleAnnotation = Optional.of(annotation); } } this.gwtCompatibleAnnotation = gwtCompatibleAnnotation; }
/** * Returns an {@link AnnotationMirror} for the annotation of type {@code annotationClassName} on * {@code element}, or {@link Optional#absent()} if no such annotation exists. */ public static Optional<AnnotationMirror> findAnnotationMirror( Element element, String annotationClassName) { for (AnnotationMirror annotationMirror : element.getAnnotationMirrors()) { TypeElement annotationTypeElement = (TypeElement) (annotationMirror.getAnnotationType().asElement()); if (annotationTypeElement.getQualifiedName().contentEquals(annotationClassName)) { return Optional.of(annotationMirror); } } return Optional.absent(); }
static boolean isJacksonJsonTypeInfoAnnotated(Element element) { List<? extends AnnotationMirror> annotationMirrors = element.getAnnotationMirrors(); for (AnnotationMirror annotation : annotationMirrors) { TypeElement annotationElement = (TypeElement) annotation.getAnnotationType().asElement(); if ("com.fasterxml.jackson.annotation.JsonTypeInfo" .equals(annotationElement.getQualifiedName().toString())) { return true; } } return false; }
/** * If any constant-value annotation has > MAX_VALUES number of values provided, treats the * value as UnknownVal. Works together with ValueVisitor.visitAnnotation, which issues a warning * to the user in this case. */ private void replaceWithUnknownValIfTooManyValues(AnnotatedTypeMirror atm) { AnnotationMirror anno = atm.getAnnotationInHierarchy(UNKNOWNVAL); if (anno != null && anno.getElementValues().size() > 0) { List<Object> values = AnnotationUtils.getElementValueArray(anno, "value", Object.class, false); if (values != null && values.size() > MAX_VALUES) { atm.replaceAnnotation(UNKNOWNVAL); } } }
static boolean isJacksonSerializedAnnotated(Element element) { List<? extends AnnotationMirror> annotationMirrors = element.getAnnotationMirrors(); for (AnnotationMirror annotation : annotationMirrors) { TypeElement annotationElement = (TypeElement) annotation.getAnnotationType().asElement(); if (JACKSON_MAPPING_ANNOTATION_CLASSES.contains( annotationElement.getQualifiedName().toString())) { return true; } } return false; }
static Parameter forVariableElement(VariableElement variable) { ImmutableSet.Builder<String> qualifiers = ImmutableSet.builder(); for (AnnotationMirror annotationMirror : variable.getAnnotationMirrors()) { DeclaredType annotationType = annotationMirror.getAnnotationType(); if (annotationType.asElement().getAnnotation(Qualifier.class) != null) { qualifiers.add(Mirrors.getQualifiedName(annotationType).toString()); } } return new Parameter( FluentIterable.from(qualifiers.build()).first(), variable.asType().toString(), variable.getSimpleName().toString()); }
protected boolean isExplicitTypeDefinition(Element declaration) { if (declaration.getKind() != ElementKind.CLASS) { debug("%s isn't a potential JAXB type because it's not a class.", declaration); return false; } PackageElement pckg = this.context.getProcessingEnvironment().getElementUtils().getPackageOf(declaration); if ((pckg != null) && (pckg.getAnnotation(Ignore.class) != null)) { debug( "%s isn't a potential JAXB type because its package is annotated as to be ignored.", declaration); return false; } if (isThrowable(declaration)) { debug( "%s isn't a potential JAXB type because it's an instance of java.lang.Throwable.", declaration); return false; } List<? extends AnnotationMirror> annotationMirrors = declaration.getAnnotationMirrors(); boolean explicitXMLTypeOrElement = false; for (AnnotationMirror mirror : annotationMirrors) { Element annotationDeclaration = mirror.getAnnotationType().asElement(); if (annotationDeclaration != null) { String fqn = annotationDeclaration instanceof TypeElement ? ((TypeElement) annotationDeclaration).getQualifiedName().toString() : ""; // exclude all XmlTransient types and all jaxws types. if (XmlTransient.class.getName().equals(fqn) || fqn.startsWith("javax.xml.ws") || fqn.startsWith("javax.ws.rs") || fqn.startsWith("javax.jws")) { debug("%s isn't a potential JAXB type because of annotation %s.", declaration, fqn); return false; } else { explicitXMLTypeOrElement = (XmlType.class.getName().equals(fqn)) || (XmlRootElement.class.getName().equals(fqn)); } } if (explicitXMLTypeOrElement) { break; } } return explicitXMLTypeOrElement; }
private Set<ConstraintCheckError> checkInternal( Element element, AnnotationMirror annotation, TypeMirror type, String messageKey) { if (constraintHelper.checkConstraint(annotation.getAnnotationType(), type) != ConstraintCheckResult.ALLOWED) { return CollectionHelper.asSet( new ConstraintCheckError( element, annotation, messageKey, annotation.getAnnotationType().asElement().getSimpleName())); } return Collections.emptySet(); }
/** @return the String value of a KeyFor, this will throw an exception */ private Set<String> getKeys(final AnnotationMirror keyFor) { if (keyFor.getElementValues().size() == 0) { return new LinkedHashSet<>(); } return new LinkedHashSet<>( AnnotationUtils.getElementValueArray(keyFor, "value", String.class, true)); }
private Map<String, Object> getAnnotationElementValues(AnnotationMirror annotation) { Map<String, Object> values = new LinkedHashMap<String, Object>(); for (Map.Entry<? extends ExecutableElement, ? extends AnnotationValue> entry : annotation.getElementValues().entrySet()) { values.put(entry.getKey().getSimpleName().toString(), entry.getValue().getValue()); } return values; }
@Override public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { for (TypeElement te : ElementFilter.typesIn(roundEnv.getRootElements())) { if (isSimpleName(te, "InvalidSource")) { for (Element c : te.getEnclosedElements()) { for (AnnotationMirror am : c.getAnnotationMirrors()) { Element ate = am.getAnnotationType().asElement(); if (isSimpleName(ate, "ExpectInterfaces")) { checkInterfaces((TypeElement) c, getValue(am)); } else if (isSimpleName(ate, "ExpectSupertype")) { checkSupertype((TypeElement) c, getValue(am)); } } } } } return true; }
/** * Determines the least upper bound of a1 and a2. If a1 and a2 are both the same type of Value * annotation, then the LUB is the result of taking all values from both a1 and a2 and removing * duplicates. If a1 and a2 are not the same type of Value annotation they may still be * mergeable because some values can be implicitly cast as others. If a1 and a2 are both in * {DoubleVal, IntVal} then they will be converted upwards: IntVal → DoubleVal to arrive at * a common annotation type. * * @return the least upper bound of a1 and a2 */ @Override public AnnotationMirror leastUpperBound(AnnotationMirror a1, AnnotationMirror a2) { if (!AnnotationUtils.areSameIgnoringValues(getTopAnnotation(a1), getTopAnnotation(a2))) { return null; } else if (isSubtype(a1, a2)) { return a2; } else if (isSubtype(a2, a1)) { return a1; } // If both are the same type, determine the type and merge: else if (AnnotationUtils.areSameIgnoringValues(a1, a2)) { List<Object> a1Values = AnnotationUtils.getElementValueArray(a1, "value", Object.class, true); List<Object> a2Values = AnnotationUtils.getElementValueArray(a2, "value", Object.class, true); HashSet<Object> newValues = new HashSet<Object>(a1Values.size() + a2Values.size()); newValues.addAll(a1Values); newValues.addAll(a2Values); return createAnnotation(a1.getAnnotationType().toString(), newValues); } // Annotations are in this hierarchy, but they are not the same else { // If either is UNKNOWNVAL, ARRAYLEN, STRINGVAL, or BOOLEAN then // the LUB is // UnknownVal if (!(AnnotationUtils.areSameByClass(a1, IntVal.class) || AnnotationUtils.areSameByClass(a1, DoubleVal.class) || AnnotationUtils.areSameByClass(a2, IntVal.class) || AnnotationUtils.areSameByClass(a2, DoubleVal.class))) { return UNKNOWNVAL; } else { // At this point one of them must be a DoubleVal and one an // IntVal AnnotationMirror doubleAnno; AnnotationMirror intAnno; if (AnnotationUtils.areSameByClass(a2, DoubleVal.class)) { doubleAnno = a2; intAnno = a1; } else { doubleAnno = a1; intAnno = a2; } List<Long> intVals = getIntValues(intAnno); List<Double> doubleVals = getDoubleValues(doubleAnno); for (Long n : intVals) { doubleVals.add(n.doubleValue()); } return createDoubleValAnnotation(doubleVals); } } }
public static Optional<AnnotationValue> findProperty( AnnotationMirror annotation, String propertyName) { for (Entry<? extends ExecutableElement, ? extends AnnotationValue> element : annotation.getElementValues().entrySet()) { if (element.getKey().getSimpleName().contentEquals(propertyName)) { return Optional.<AnnotationValue>of(element.getValue()); } } return Optional.absent(); }
/** @inheritDoc */ @Override public Slot getSlot(final AnnotationMirror annotationMirror) { final int id; if (InferenceQualifierHierarchy.isVarAnnot(annotationMirror)) { if (annotationMirror.getElementValues().isEmpty()) { return null; // TODO: should we instead throw an exception? } else { final AnnotationValue annoValue = annotationMirror.getElementValues().values().iterator().next(); id = Integer.valueOf(annoValue.toString()); } return getVariable(id); } else { if (constantStore != null) { return constantStore.get(AnnotationUtils.annotationName(annotationMirror)); } else { for (Class<? extends Annotation> realAnno : realQualifiers) { if (AnnotationUtils.areSameByClass(annotationMirror, realAnno)) { return new ConstantSlot(annotationMirror, nextId()); } } } } if (InferenceMain.isHackMode()) { return new ConstantSlot( InferenceMain.getInstance() .getRealTypeFactory() .getQualifierHierarchy() .getTopAnnotations() .iterator() .next(), nextId()); } ErrorReporter.errorAbort( annotationMirror + " is a type of AnnotationMirror not handled by getVariableSlot."); return null; // Dead }
String gwtCompatibleAnnotationString() { if (gwtCompatibleAnnotation.isPresent()) { AnnotationMirror annotation = gwtCompatibleAnnotation.get(); TypeElement annotationElement = (TypeElement) annotation.getAnnotationType().asElement(); String annotationArguments; if (annotation.getElementValues().isEmpty()) { annotationArguments = ""; } else { List<String> elements = Lists.newArrayList(); for (Map.Entry<ExecutableElement, AnnotationValue> entry : Collections.unmodifiableMap(annotation.getElementValues()).entrySet()) { elements.add(entry.getKey().getSimpleName() + " = " + entry.getValue()); } annotationArguments = "(" + Joiner.on(", ").join(elements) + ")"; } return "@" + annotationElement.getQualifiedName() + annotationArguments; } else { return ""; } }
private String getAnnotationValue(AnnotationMirror am) { for (Map.Entry<? extends ExecutableElement, ? extends AnnotationValue> e : am.getElementValues().entrySet()) { if (e.getKey().getSimpleName().contentEquals("value")) { Object value = e.getValue().getValue(); if (value instanceof String) { return (String) value; } } } return ""; }
private static VariableElement getAutoTypeParameter( ExecutableElement method, VariableElement target_parameter) { for (VariableElement param : method.getParameters()) { AnnotationMirror auto_annotation = Utils.getParameterAutoAnnotation(param); if (auto_annotation != null) { Class annotation_type = NativeTypeTranslator.getClassFromType(auto_annotation.getAnnotationType()); String parameter_name; if (annotation_type.equals(AutoType.class)) { parameter_name = param.getAnnotation(AutoType.class).value(); } else if (annotation_type.equals(AutoSize.class)) { parameter_name = param.getAnnotation(AutoSize.class).value(); } else { throw new RuntimeException("Unknown annotation type " + annotation_type); } if (target_parameter.getSimpleName().toString().equals(parameter_name)) { return param; } } } return null; }
/** Returns whether the field {@code f} is unused, given the annotations on the receiver. */ private boolean isUnused( VariableTree field, Collection<? extends AnnotationMirror> receiverAnnos) { if (receiverAnnos.isEmpty()) { return false; } AnnotationMirror unused = getDeclAnnotation(TreeUtils.elementFromDeclaration(field), Unused.class); if (unused == null) { return false; } Name when = AnnotationUtils.getElementValueClassName(unused, "when", false); for (AnnotationMirror anno : receiverAnnos) { Name annoName = ((TypeElement) anno.getAnnotationType().asElement()).getQualifiedName(); if (annoName.contentEquals(when)) { return true; } } return false; }
/** * INTERNAL: The pre-processing stages requires some knowledge of the annotation values (e.g. * targetEntity) so we will visit the annotation values and build complete MetadataAnnotation from * the mirrors. */ protected void buildMetadataAnnotations( MetadataAnnotatedElement annotatedElement, List<? extends AnnotationMirror> annotationMirrors) { AnnotationValueVisitor<Object, Object> visitor = new AnnotationValueVisitor<Object, Object>(); for (AnnotationMirror annotationMirror : annotationMirrors) { String annotation = annotationMirror.getAnnotationType().toString(); // Only add annotations that we care about. Be nice to have API // that we could call into with the annotation mirror to the // processor to see if it is a supported annotation. That is, it // would tie into the @SupportedAnnotationTypes({"javax.persistence.*", // "org.eclipse.persistence.annotations.*"}) // declaration from CanonicalModelProcessor, but I couldn't find a // way to do this. For now we'll check the strings (similar to what // is done with our ASM factory). if (annotation.contains(JPA_PERSISTENCE_PACKAGE_PREFIX) || annotation.contains(ECLIPSELINK_PERSISTENCE_PACKAGE_PREFIX)) { annotatedElement.addAnnotation( (MetadataAnnotation) visitor.visitAnnotation(annotationMirror, null)); } } }
private void verifyExclusiveMethodAnnotation(Template template, Class<?>... annotationTypes) { List<ExecutableElement> methods = ElementFilter.methodsIn(template.getTemplateType().getEnclosedElements()); for (ExecutableElement method : methods) { List<AnnotationMirror> foundAnnotations = new ArrayList<>(); for (int i = 0; i < annotationTypes.length; i++) { Class<?> annotationType = annotationTypes[i]; AnnotationMirror mirror = ElementUtils.findAnnotationMirror(context.getEnvironment(), method, annotationType); if (mirror != null) { foundAnnotations.add(mirror); } } if (foundAnnotations.size() > 1) { List<String> annotationNames = new ArrayList<>(); for (AnnotationMirror mirror : foundAnnotations) { annotationNames.add("@" + ElementUtils.getSimpleName(mirror.getAnnotationType())); } template.addError("Non exclusive usage of annotations %s.", annotationNames); } } }
/** * Inject extra bound fields into a classInfo. * * @param extraBoundFields a list that represents the extra fields defined inside a @{@link * BoundBox} annotation. * @param classInfo representation of the class whose BoundBox will receive the extra fields. */ private void injectExtraBoundFields( List<? extends AnnotationValue> extraBoundFields, ClassInfo classInfo) { if (extraBoundFields == null || extraBoundFields.isEmpty()) { return; } List<FieldInfo> listFieldInfos = classInfo.getListFieldInfos(); TypeMirror fieldClass = null; String fieldName = null; for (AnnotationValue annotationValue : extraBoundFields) { AnnotationMirror annotationMirror = (AnnotationMirror) annotationValue.getValue(); log.info("mirror " + annotationMirror.getAnnotationType()); Map<? extends ExecutableElement, ? extends AnnotationValue> mapExecutableElementToAnnotationValue = annotationMirror.getElementValues(); for (Map.Entry<? extends ExecutableElement, ? extends AnnotationValue> entry : mapExecutableElementToAnnotationValue.entrySet()) { if (BOUNDBOX_ANNOTATION_PARAMETER_EXTRA_BOUND_FIELDS_FIELD_NAME.equals( entry.getKey().getSimpleName().toString())) { fieldName = getAnnotationValueAsString(entry.getValue()); // TODO shoot an error if its null or not a valid field name in java } if (BOUNDBOX_ANNOTATION_PARAMETER_EXTRA_BOUND_FIELDS_FIELD_CLASS.equals( entry.getKey().getSimpleName().toString())) { fieldClass = (TypeMirror) entry.getValue().getValue(); } } FieldInfo fieldInfo = new FieldInfo(fieldName, fieldClass); // TODO we should add a warning to the developer here. // TODO there can even be an error if a field of the same name but with a different type // exists. if (!listFieldInfos.contains(fieldInfo)) { listFieldInfos.add(fieldInfo); } } }
private void processLabels(TypeElement resourcesType, List<LabelTemplateMethod> methods) { for (Element element : resourcesType.getEnclosedElements()) { if (element.getKind() != ElementKind.METHOD) { continue; } final ExecutableElement method = (ExecutableElement) element; Message labelAnnotation = element.getAnnotation(Message.class); final TemplateParam returnType = new TemplateParam(method.getReturnType().toString()); final boolean deprecated = method.getAnnotation(Deprecated.class) != null; final LabelTemplateMethod labelMethod; try { labelMethod = new LabelTemplateMethod( method.getSimpleName().toString(), deprecated, returnType, labelAnnotation.value(), labelAnnotation.mobile()); } catch (Throwable t) { processingEnv.getMessager().printMessage(Kind.WARNING, t.getMessage(), resourcesType); continue; } for (VariableElement variable : method.getParameters()) { final String paramName = variable.getSimpleName().toString(); final String paramType = variable.asType().toString(); List<TemplateAnnotation> annotations = new ArrayList<TemplateAnnotation>(); for (AnnotationMirror annotationMirrors : variable.getAnnotationMirrors()) { annotations.add(new TemplateAnnotation(annotationMirrors.getAnnotationType().toString())); } labelMethod.getParams().add(new TemplateParam(paramType, paramName, annotations)); } methods.add(labelMethod); } }