public AnnotatedTypeMirror fromElement()

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);
    }