use of org.checkerframework.framework.stub.AnnotationFileParser.RecordComponentStub in project checker-framework by typetools.
the class AnnotationFileElementTypes method injectRecordComponentType.
/**
* Adds annotations from stub files for the corresponding record components (if the given
* constructor/method is the canonical constructor or a record accessor). Such transfer is
* automatically done by javac usually, but not from stubs.
*
* @param types a Types instance used for checking type equivalence
* @param elt a member. This method does nothing if it's not a method or constructor.
* @param memberType the type corresponding to the element elt; side-effected by this method
*/
public void injectRecordComponentType(Types types, Element elt, AnnotatedExecutableType memberType) {
if (parsing) {
throw new BugInCF("parsing while calling injectRecordComponentType");
}
if (elt.getKind() == ElementKind.METHOD) {
if (((ExecutableElement) elt).getParameters().isEmpty()) {
String recordName = ElementUtils.getQualifiedName(elt.getEnclosingElement());
AnnotationFileParser.RecordStub recordComponentType = annotationFileAnnos.records.get(recordName);
if (recordComponentType != null) {
// If the record component has an annotation in the stub, the component annotation
// replaces any from the same hierarchy on the accessor method, unless there is an
// accessor in the stubs file (which may or may not have an annotation in the same
// hierarchy;
// the user may want to specify the annotation or deliberately not annotate the accessor).
// We thus only replace the method annotation with the component annotation
// if there is no accessor in the stubs file:
RecordComponentStub recordComponentStub = recordComponentType.componentsByName.get(elt.getSimpleName().toString());
if (recordComponentStub != null && !recordComponentStub.hasAccessorInStubs()) {
replaceAnnotations(memberType.getReturnType(), recordComponentStub.type);
}
}
}
} else if (elt.getKind() == ElementKind.CONSTRUCTOR) {
if (AnnotationFileUtil.isCanonicalConstructor((ExecutableElement) elt, types)) {
TypeElement enclosing = (TypeElement) elt.getEnclosingElement();
AnnotationFileParser.RecordStub recordComponentType = annotationFileAnnos.records.get(enclosing.getQualifiedName().toString());
if (recordComponentType != null) {
List<AnnotatedTypeMirror> componentsInCanonicalConstructor = recordComponentType.getComponentsInCanonicalConstructor();
if (componentsInCanonicalConstructor != null) {
for (int i = 0; i < componentsInCanonicalConstructor.size(); i++) {
replaceAnnotations(memberType.getParameterTypes().get(i), componentsInCanonicalConstructor.get(i));
}
}
}
}
}
}
use of org.checkerframework.framework.stub.AnnotationFileParser.RecordComponentStub in project checker-framework by typetools.
the class AnnotationFileElementTypes method getDeclAnnotations.
/**
* Returns the set of declaration annotations for {@code e} containing only annotations explicitly
* written in an annotation file or the empty set if {@code e} does not appear in an annotation
* file.
*
* @param elt element for which annotations are returned
* @return an AnnotatedTypeMirror for {@code e} containing only annotations explicitly written in
* the annotation file and in the element. {@code null} is returned if {@code element} does
* not appear in an annotation file.
*/
public Set<AnnotationMirror> getDeclAnnotations(Element elt) {
if (parsing) {
return Collections.emptySet();
}
parseEnclosingClass(elt);
String eltName = ElementUtils.getQualifiedName(elt);
if (annotationFileAnnos.declAnnos.containsKey(eltName)) {
return annotationFileAnnos.declAnnos.get(eltName);
} else {
// Handle annotations on record declarations.
boolean canTransferAnnotationsToSameName;
// Do nothing unless this element is a record.
Element enclosingType;
switch(elt.getKind()) {
case METHOD:
// Annotations transfer to zero-arg accessor methods of same name:
canTransferAnnotationsToSameName = ((ExecutableElement) elt).getParameters().isEmpty();
enclosingType = elt.getEnclosingElement();
break;
case FIELD:
// Annotations transfer to fields of same name:
canTransferAnnotationsToSameName = true;
enclosingType = elt.getEnclosingElement();
break;
case PARAMETER:
// Annotations transfer to compact canonical constructor parameter of same name:
canTransferAnnotationsToSameName = ElementUtils.isCompactCanonicalRecordConstructor(elt.getEnclosingElement()) && elt.getEnclosingElement().getKind() == ElementKind.CONSTRUCTOR;
enclosingType = elt.getEnclosingElement().getEnclosingElement();
break;
default:
canTransferAnnotationsToSameName = false;
enclosingType = null;
break;
}
if (canTransferAnnotationsToSameName && enclosingType.getKind().toString().equals("RECORD")) {
AnnotationFileParser.RecordStub recordStub = annotationFileAnnos.records.get(enclosingType.getSimpleName().toString());
if (recordStub != null && recordStub.componentsByName.containsKey(elt.getSimpleName().toString())) {
RecordComponentStub recordComponentStub = recordStub.componentsByName.get(elt.getSimpleName().toString());
return recordComponentStub.getAnnotationsForTarget(elt.getKind());
}
}
}
return Collections.emptySet();
}
Aggregations