/** * {@inheritDoc} * * <p>In most cases, subclasses want to call this method first because it may clear all * annotations and use the hierarchy's root annotations. */ @Override public void postAsMemberOf(AnnotatedTypeMirror type, AnnotatedTypeMirror owner, Element element) { super.postAsMemberOf(type, owner, element); if (element.getKind().isField()) { Collection<? extends AnnotationMirror> declaredFieldAnnotations = getDeclAnnotations(element); AnnotatedTypeMirror fieldAnnotations = getAnnotatedType(element); computeFieldAccessType(type, declaredFieldAnnotations, owner, fieldAnnotations, element); } }
/** * Returns a set of triples {@code (expr, (result, annotation))} of conditional postconditions on * the method {@code methodElement}. */ public Set<Pair<String, Pair<Boolean, String>>> getConditionalPostconditions( ExecutableElement methodElement) { Set<Pair<String, Pair<Boolean, String>>> result = new HashSet<>(); // Check for a single contract. AnnotationMirror ensuresAnnotationIf = factory.getDeclAnnotation(methodElement, EnsuresQualifierIf.class); result.addAll(getConditionalPostcondition(ensuresAnnotationIf)); // Check for multiple contracts. AnnotationMirror ensuresAnnotationsIf = factory.getDeclAnnotation(methodElement, EnsuresQualifiersIf.class); if (ensuresAnnotationsIf != null) { List<AnnotationMirror> annotations = AnnotationUtils.getElementValueArray( ensuresAnnotationsIf, "value", AnnotationMirror.class, false); for (AnnotationMirror a : annotations) { result.addAll(getConditionalPostcondition(a)); } } // Check type-system specific annotations. Class<ConditionalPostconditionAnnotation> metaAnnotation = ConditionalPostconditionAnnotation.class; List<Pair<AnnotationMirror, AnnotationMirror>> declAnnotations = factory.getDeclAnnotationWithMetaAnnotation(methodElement, metaAnnotation); for (Pair<AnnotationMirror, AnnotationMirror> r : declAnnotations) { AnnotationMirror anno = r.first; AnnotationMirror metaAnno = r.second; List<String> expressions = AnnotationUtils.getElementValueArray(anno, "expression", String.class, false); String annotationString = AnnotationUtils.getElementValueClassName(metaAnno, "qualifier", false).toString(); boolean annoResult = AnnotationUtils.getElementValue(anno, "result", Boolean.class, false); for (String expr : expressions) { result.add(Pair.of(expr, Pair.of(annoResult, annotationString))); } } return result; }
/** * Returns a set of pairs {@code (expr, annotation)} of preconditions on the element {@code * element}. */ public Set<Pair<String, String>> getPreconditions(Element element) { Set<Pair<String, String>> result = new HashSet<>(); // Check for a single contract. AnnotationMirror requiresAnnotation = factory.getDeclAnnotation(element, RequiresQualifier.class); result.addAll(getPrecondition(requiresAnnotation)); // Check for multiple contracts. AnnotationMirror requiresAnnotations = factory.getDeclAnnotation(element, RequiresQualifiers.class); if (requiresAnnotations != null) { List<AnnotationMirror> annotations = AnnotationUtils.getElementValueArray( requiresAnnotations, "value", AnnotationMirror.class, false); for (AnnotationMirror a : annotations) { result.addAll(getPrecondition(a)); } } // Check type-system specific annotations. Class<PreconditionAnnotation> metaAnnotation = PreconditionAnnotation.class; List<Pair<AnnotationMirror, AnnotationMirror>> declAnnotations = factory.getDeclAnnotationWithMetaAnnotation(element, metaAnnotation); for (Pair<AnnotationMirror, AnnotationMirror> r : declAnnotations) { AnnotationMirror anno = r.first; AnnotationMirror metaAnno = r.second; List<String> expressions = AnnotationUtils.getElementValueArray(anno, "value", String.class, false); String annotationString = AnnotationUtils.getElementValueClassName(metaAnno, "qualifier", false).toString(); for (String expr : expressions) { result.add(Pair.of(expr, annotationString)); } } return result; }