Search in sources :

Example 1 with ReceiverParameter

use of com.github.javaparser.ast.body.ReceiverParameter in project checker-framework by typetools.

the class JointJavacJavaParserVisitor method visitVariable.

@Override
public Void visitVariable(VariableTree javacTree, Node javaParserNode) {
    // variable declarations, parameters, and fields.
    if (javaParserNode instanceof VariableDeclarator) {
        // JavaParser uses VariableDeclarator as parts of other declaration types like
        // VariableDeclarationExpr when multiple variables may be declared.
        VariableDeclarator node = (VariableDeclarator) javaParserNode;
        processVariable(javacTree, node);
        // Don't process the variable type when it's the Java keyword "var".
        if (!node.getType().isVarType() && (!node.getType().isClassOrInterfaceType() || !node.getType().asClassOrInterfaceType().getName().asString().equals("var"))) {
            javacTree.getType().accept(this, node.getType());
        }
        // The name expression can be null, even when a name exists.
        if (javacTree.getNameExpression() != null) {
            javacTree.getNameExpression().accept(this, node.getName());
        }
        visitOptional(javacTree.getInitializer(), node.getInitializer());
    } else if (javaParserNode instanceof Parameter) {
        Parameter node = (Parameter) javaParserNode;
        processVariable(javacTree, node);
        if (node.isVarArgs()) {
            ArrayTypeTree arrayType;
            // AnnotatedType depending on whether it has an annotation.
            if (javacTree.getType().getKind() == Tree.Kind.ARRAY_TYPE) {
                arrayType = (ArrayTypeTree) javacTree.getType();
            } else {
                AnnotatedTypeTree annotatedType = (AnnotatedTypeTree) javacTree.getType();
                arrayType = (ArrayTypeTree) annotatedType.getUnderlyingType();
            }
            arrayType.getType().accept(this, node.getType());
        } else {
            // don't process them.
            if (!node.getType().isUnknownType()) {
                javacTree.getType().accept(this, node.getType());
            }
        }
        // The name expression can be null, even when a name exists.
        if (javacTree.getNameExpression() != null) {
            javacTree.getNameExpression().accept(this, node.getName());
        }
        assert javacTree.getInitializer() == null;
    } else if (javaParserNode instanceof ReceiverParameter) {
        ReceiverParameter node = (ReceiverParameter) javaParserNode;
        processVariable(javacTree, node);
        javacTree.getType().accept(this, node.getType());
        // The name expression can be null, even when a name exists.
        if (javacTree.getNameExpression() != null) {
            javacTree.getNameExpression().accept(this, node.getName());
        }
        assert javacTree.getInitializer() == null;
    } else if (javaParserNode instanceof EnumConstantDeclaration) {
        // In javac, an enum constant is expanded as a variable declaration initialized to a
        // constuctor call.
        EnumConstantDeclaration node = (EnumConstantDeclaration) javaParserNode;
        processVariable(javacTree, node);
        if (javacTree.getNameExpression() != null) {
            javacTree.getNameExpression().accept(this, node.getName());
        }
        assert javacTree.getInitializer().getKind() == Tree.Kind.NEW_CLASS;
        NewClassTree constructor = (NewClassTree) javacTree.getInitializer();
        visitLists(constructor.getArguments(), node.getArguments());
        if (constructor.getClassBody() != null) {
            visitAnonymousClassBody(constructor.getClassBody(), node.getClassBody());
        } else {
            assert node.getClassBody().isEmpty();
        }
    } else {
        throwUnexpectedNodeType(javacTree, javaParserNode);
    }
    return null;
}
Also used : AnnotatedTypeTree(com.sun.source.tree.AnnotatedTypeTree) EnumConstantDeclaration(com.github.javaparser.ast.body.EnumConstantDeclaration) ReceiverParameter(com.github.javaparser.ast.body.ReceiverParameter) ReceiverParameter(com.github.javaparser.ast.body.ReceiverParameter) Parameter(com.github.javaparser.ast.body.Parameter) TypeParameter(com.github.javaparser.ast.type.TypeParameter) NewClassTree(com.sun.source.tree.NewClassTree) VariableDeclarator(com.github.javaparser.ast.body.VariableDeclarator) ArrayTypeTree(com.sun.source.tree.ArrayTypeTree)

Example 2 with ReceiverParameter

use of com.github.javaparser.ast.body.ReceiverParameter in project checker-framework by typetools.

the class WholeProgramInferenceJavaParserStorage method addExplicitReceiver.

/**
 * Adds an explicit receiver type to a JavaParser method declaration.
 *
 * @param methodDeclaration declaration to add a receiver to
 */
private static void addExplicitReceiver(MethodDeclaration methodDeclaration) {
    if (methodDeclaration.getReceiverParameter().isPresent()) {
        return;
    }
    com.github.javaparser.ast.Node parent = methodDeclaration.getParentNode().get();
    if (!(parent instanceof TypeDeclaration)) {
        return;
    }
    TypeDeclaration<?> parentDecl = (TypeDeclaration<?>) parent;
    ClassOrInterfaceType receiver = new ClassOrInterfaceType();
    receiver.setName(parentDecl.getName());
    if (parentDecl.isClassOrInterfaceDeclaration()) {
        ClassOrInterfaceDeclaration parentClassDecl = parentDecl.asClassOrInterfaceDeclaration();
        if (!parentClassDecl.getTypeParameters().isEmpty()) {
            NodeList<Type> typeArgs = new NodeList<>();
            for (TypeParameter typeParam : parentClassDecl.getTypeParameters()) {
                ClassOrInterfaceType typeArg = new ClassOrInterfaceType();
                typeArg.setName(typeParam.getNameAsString());
                typeArgs.add(typeArg);
            }
            receiver.setTypeArguments(typeArgs);
        }
    }
    methodDeclaration.setReceiverParameter(new ReceiverParameter(receiver, "this"));
}
Also used : ClassOrInterfaceType(com.github.javaparser.ast.type.ClassOrInterfaceType) AnnotatedArrayType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedArrayType) Type(com.github.javaparser.ast.type.Type) TypeParameter(com.github.javaparser.ast.type.TypeParameter) ClassOrInterfaceDeclaration(com.github.javaparser.ast.body.ClassOrInterfaceDeclaration) ReceiverParameter(com.github.javaparser.ast.body.ReceiverParameter) NodeList(com.github.javaparser.ast.NodeList) ClassOrInterfaceType(com.github.javaparser.ast.type.ClassOrInterfaceType) TypeDeclaration(com.github.javaparser.ast.body.TypeDeclaration)

Example 3 with ReceiverParameter

use of com.github.javaparser.ast.body.ReceiverParameter in project checker-framework by typetools.

the class ToIndexFileConverter method visit.

@Override
public Void visit(MethodDeclaration decl, AElement elem) {
    Type type = decl.getType();
    List<Parameter> params = decl.getParameters();
    List<TypeParameter> typeParams = decl.getTypeParameters();
    Optional<ReceiverParameter> rcvrParam = decl.getReceiverParameter();
    BlockStmt body = decl.getBody().orElse(null);
    StringBuilder sb = new StringBuilder(decl.getNameAsString()).append('(');
    AClass clazz = (AClass) elem;
    AMethod method;
    if (params != null) {
        for (Parameter param : params) {
            Type ptype = param.getType();
            sb.append(getJVML(ptype));
        }
    }
    sb.append(')').append(getJVML(type));
    method = clazz.methods.getVivify(sb.toString());
    visitDecl(decl, method);
    visitType(type, method.returnType);
    if (params != null) {
        for (int i = 0; i < params.size(); i++) {
            Parameter param = params.get(i);
            AField field = method.parameters.getVivify(i);
            visitType(param.getType(), field.type);
        }
    }
    if (rcvrParam.isPresent()) {
        for (AnnotationExpr expr : rcvrParam.get().getAnnotations()) {
            Annotation anno = extractAnnotation(expr);
            method.receiver.type.tlAnnotationsHere.add(anno);
        }
    }
    if (typeParams != null) {
        for (int i = 0; i < typeParams.size(); i++) {
            TypeParameter typeParam = typeParams.get(i);
            List<ClassOrInterfaceType> bounds = typeParam.getTypeBound();
            if (bounds != null) {
                for (int j = 0; j < bounds.size(); j++) {
                    ClassOrInterfaceType bound = bounds.get(j);
                    BoundLocation loc = new BoundLocation(i, j);
                    bound.accept(this, method.bounds.getVivify(loc));
                }
            }
        }
    }
    return body == null ? null : body.accept(this, method);
}
Also used : TypeParameter(com.github.javaparser.ast.type.TypeParameter) AnnotationExpr(com.github.javaparser.ast.expr.AnnotationExpr) BlockStmt(com.github.javaparser.ast.stmt.BlockStmt) ClassOrInterfaceType(com.github.javaparser.ast.type.ClassOrInterfaceType) Annotation(scenelib.annotations.Annotation) AField(scenelib.annotations.el.AField) ClassOrInterfaceType(com.github.javaparser.ast.type.ClassOrInterfaceType) Type(com.github.javaparser.ast.type.Type) ReferenceType(com.github.javaparser.ast.type.ReferenceType) VoidType(com.github.javaparser.ast.type.VoidType) ArrayType(com.github.javaparser.ast.type.ArrayType) PrimitiveType(com.github.javaparser.ast.type.PrimitiveType) WildcardType(com.github.javaparser.ast.type.WildcardType) ReceiverParameter(com.github.javaparser.ast.body.ReceiverParameter) ReceiverParameter(com.github.javaparser.ast.body.ReceiverParameter) Parameter(com.github.javaparser.ast.body.Parameter) TypeParameter(com.github.javaparser.ast.type.TypeParameter) AClass(scenelib.annotations.el.AClass) BoundLocation(scenelib.annotations.el.BoundLocation) AMethod(scenelib.annotations.el.AMethod)

Example 4 with ReceiverParameter

use of com.github.javaparser.ast.body.ReceiverParameter 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)

Example 5 with ReceiverParameter

use of com.github.javaparser.ast.body.ReceiverParameter in project checker-framework by typetools.

the class DoubleJavaParserVisitor method visit.

@Override
public void visit(final ReceiverParameter node1, final Node other) {
    ReceiverParameter node2 = (ReceiverParameter) other;
    defaultAction(node1, node2);
    node1.getName().accept(this, node2.getName());
    node1.getType().accept(this, node2.getType());
}
Also used : ReceiverParameter(com.github.javaparser.ast.body.ReceiverParameter)

Aggregations

ReceiverParameter (com.github.javaparser.ast.body.ReceiverParameter)5 TypeParameter (com.github.javaparser.ast.type.TypeParameter)3 Parameter (com.github.javaparser.ast.body.Parameter)2 ClassOrInterfaceType (com.github.javaparser.ast.type.ClassOrInterfaceType)2 Type (com.github.javaparser.ast.type.Type)2 NodeList (com.github.javaparser.ast.NodeList)1 ClassOrInterfaceDeclaration (com.github.javaparser.ast.body.ClassOrInterfaceDeclaration)1 EnumConstantDeclaration (com.github.javaparser.ast.body.EnumConstantDeclaration)1 MethodDeclaration (com.github.javaparser.ast.body.MethodDeclaration)1 TypeDeclaration (com.github.javaparser.ast.body.TypeDeclaration)1 VariableDeclarator (com.github.javaparser.ast.body.VariableDeclarator)1 AnnotationExpr (com.github.javaparser.ast.expr.AnnotationExpr)1 BlockStmt (com.github.javaparser.ast.stmt.BlockStmt)1 ArrayType (com.github.javaparser.ast.type.ArrayType)1 PrimitiveType (com.github.javaparser.ast.type.PrimitiveType)1 ReferenceType (com.github.javaparser.ast.type.ReferenceType)1 VoidType (com.github.javaparser.ast.type.VoidType)1 WildcardType (com.github.javaparser.ast.type.WildcardType)1 AnnotatedTypeTree (com.sun.source.tree.AnnotatedTypeTree)1 ArrayTypeTree (com.sun.source.tree.ArrayTypeTree)1