in src/main/java/com/amazon/checkerframework/checker/data_classification/DataClassificationAnnotatedTypeFactory.java [218:304]
public AnnotatedTypeMirror fromElement(final Element elt) {
// Always prefer the classCache over recomputation.
if (classCache.containsKey(elt)) {
return classCache.get(elt);
}
// Use the tree so that we have access to members
Tree decl = declarationFromElement(elt);
if (decl != null && decl.getKind() == Tree.Kind.CLASS) {
ClassTree tree = (ClassTree) decl;
// Get the type that would have been resolved: the user-written class annotations, if
// there are any.
AnnotatedTypeMirror type = super.fromElement(elt);
classCache.put(elt, type);
// Use an annotation mirror throughout here because that's what
// QualifierHierachy#leastUpperBound requires
AnnotationMirror inferredClassLowerbound =
type.getAnnotationInHierarchy(getCanonicalPublicAnnotation());
// If the class is unannotated, assume public
if (inferredClassLowerbound == null) {
inferredClassLowerbound = getCanonicalPublicAnnotation();
}
// For each member of the class that's a field or a method, update the inferred type
// with either the type
// of the field or the return type of the method.
for (Tree member : tree.getMembers()) {
switch (member.getKind()) {
case METHOD:
MethodTree methodTree = (MethodTree) member;
ExecutableElement execElem = TreeUtils.elementFromDeclaration(methodTree);
if (ElementUtils.isStatic(execElem)) {
break;
}
if (execElem.getReturnType() == null) {
break;
}
AnnotatedTypeMirror.AnnotatedExecutableType methodSignature =
super.fromElement(execElem);
AnnotationMirror returnAnno =
findLeastUpperBoundOfType(
methodSignature.getReturnType(),
getCanonicalPublicAnnotation());
if (returnAnno == null || AnnotationUtils.areSameByName(returnAnno, poly)) {
break;
}
inferredClassLowerbound =
getQualifierHierarchy()
.leastUpperBound(inferredClassLowerbound, returnAnno);
break;
case VARIABLE:
Element fieldElt = TreeUtils.elementFromTree(member);
if (fieldElt == null) {
break;
}
if (ElementUtils.isStatic(fieldElt)) {
break;
}
AnnotationMirror fieldAnno =
findLeastUpperBoundOfType(
super.fromElement(fieldElt),
getCanonicalPublicAnnotation());
if (fieldAnno == null) {
break;
}
inferredClassLowerbound =
getQualifierHierarchy()
.leastUpperBound(inferredClassLowerbound, fieldAnno);
break;
default:
break;
}
}
// Replace the annotation in the type and return it after updating the cache.
type.replaceAnnotation(inferredClassLowerbound);
classCache.put(elt, type);
return type;
}
return super.fromElement(elt);
}