Search in sources :

Example 1 with ErrorTypeKindException

use of org.checkerframework.framework.util.element.ElementAnnotationUtil.ErrorTypeKindException in project checker-framework by typetools.

the class AnnotationFileParser method processCallableDeclaration.

/**
 * Process a method or constructor declaration: copy its annotations to {@code
 * #annotationFileAnnos}.
 *
 * @param decl a method or constructor declaration, as read from an annotation file
 * @param elt the method or constructor's element
 * @return type variables for the method
 */
private List<AnnotatedTypeVariable> processCallableDeclaration(CallableDeclaration<?> decl, ExecutableElement elt) {
    if (!isAnnotatedForThisChecker(decl.getAnnotations())) {
        return null;
    }
    // Declaration annotations
    recordDeclAnnotation(elt, decl.getAnnotations(), decl);
    if (decl.isMethodDeclaration()) {
        // AnnotationFileParser parses all annotations in type annotation position as type
        // annotations.
        recordDeclAnnotation(elt, ((MethodDeclaration) decl).getType().getAnnotations(), decl);
    }
    markAsFromStubFile(elt);
    AnnotatedExecutableType methodType = atypeFactory.fromElement(elt);
    AnnotatedExecutableType origMethodType = warnIfStubRedundantWithBytecode ? methodType.deepCopy() : null;
    // Type Parameters
    annotateTypeParameters(decl, elt, methodType.getTypeVariables(), decl.getTypeParameters());
    typeParameters.addAll(methodType.getTypeVariables());
    // Return type, from declaration annotations on the method or constructor
    if (decl.isMethodDeclaration()) {
        MethodDeclaration methodDeclaration = (MethodDeclaration) decl;
        if (methodDeclaration.getParameters().isEmpty()) {
            String qualRecordName = ElementUtils.getQualifiedName(elt.getEnclosingElement());
            RecordStub recordStub = annotationFileAnnos.records.get(qualRecordName);
            if (recordStub != null) {
                RecordComponentStub recordComponentStub = recordStub.componentsByName.get(methodDeclaration.getNameAsString());
                if (recordComponentStub != null) {
                    recordComponentStub.hasAccessorInStubs = true;
                }
            }
        }
        try {
            annotate(methodType.getReturnType(), methodDeclaration.getType(), decl.getAnnotations(), decl);
        } catch (ErrorTypeKindException e) {
        // Do nothing, per https://github.com/typetools/checker-framework/issues/244 .
        }
    } else {
        assert decl.isConstructorDeclaration();
        if (AnnotationFileUtil.isCanonicalConstructor(elt, atypeFactory.types)) {
            // If this is the (user-written) canonical constructor, record that the component
            // annotations should not be automatically transferred:
            String qualRecordName = ElementUtils.getQualifiedName(elt.getEnclosingElement());
            if (annotationFileAnnos.records.containsKey(qualRecordName)) {
                ArrayList<AnnotatedTypeMirror> annotatedParameters = new ArrayList<>();
                List<? extends VariableElement> parameters = elt.getParameters();
                for (int i = 0; i < parameters.size(); i++) {
                    VariableElement parameter = parameters.get(i);
                    AnnotatedTypeMirror atm = AnnotatedTypeMirror.createType(parameter.asType(), atypeFactory, false);
                    annotate(atm, decl.getParameter(i).getAnnotations(), decl.getParameter(i));
                    annotatedParameters.add(atm);
                }
                annotationFileAnnos.records.get(qualRecordName).componentsInCanonicalConstructor = annotatedParameters;
            }
        }
        annotate(methodType.getReturnType(), decl.getAnnotations(), decl);
    }
    // Parameters
    processParameters(decl, elt, methodType);
    // Receiver
    if (decl.getReceiverParameter().isPresent()) {
        ReceiverParameter receiverParameter = decl.getReceiverParameter().get();
        if (methodType.getReceiverType() == null) {
            if (decl.isConstructorDeclaration()) {
                warn(receiverParameter, "parseParameter: constructor %s of a top-level class cannot have receiver" + " annotations %s", methodType, decl.getReceiverParameter().get().getAnnotations());
            } else {
                warn(receiverParameter, "parseParameter: static method %s cannot have receiver annotations %s", methodType, decl.getReceiverParameter().get().getAnnotations());
            }
        } else {
            // Add declaration annotations.
            annotate(methodType.getReceiverType(), decl.getReceiverParameter().get().getAnnotations(), receiverParameter);
            // Add type annotations.
            annotate(methodType.getReceiverType(), decl.getReceiverParameter().get().getType(), decl.getReceiverParameter().get().getAnnotations(), receiverParameter);
        }
    }
    if (warnIfStubRedundantWithBytecode && methodType.toString().equals(origMethodType.toString()) && fileType != AnnotationFileType.BUILTIN_STUB) {
        warn(decl, String.format("redundant stub file specification for %s", ElementUtils.getQualifiedName(elt)));
    }
    // Store the type.
    putMerge(annotationFileAnnos.atypes, elt, methodType);
    if (fileType.isStub()) {
        typeParameters.removeAll(methodType.getTypeVariables());
    }
    return methodType.getTypeVariables();
}
Also used : MethodDeclaration(com.github.javaparser.ast.body.MethodDeclaration) ArrayList(java.util.ArrayList) VariableElement(javax.lang.model.element.VariableElement) ErrorTypeKindException(org.checkerframework.framework.util.element.ElementAnnotationUtil.ErrorTypeKindException) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) AnnotatedExecutableType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedExecutableType) ReceiverParameter(com.github.javaparser.ast.body.ReceiverParameter)

Aggregations

MethodDeclaration (com.github.javaparser.ast.body.MethodDeclaration)1 ReceiverParameter (com.github.javaparser.ast.body.ReceiverParameter)1 ArrayList (java.util.ArrayList)1 VariableElement (javax.lang.model.element.VariableElement)1 AnnotatedTypeMirror (org.checkerframework.framework.type.AnnotatedTypeMirror)1 AnnotatedExecutableType (org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedExecutableType)1 ErrorTypeKindException (org.checkerframework.framework.util.element.ElementAnnotationUtil.ErrorTypeKindException)1