Search in sources :

Example 6 with BugInCF

use of org.checkerframework.javacutil.BugInCF in project checker-framework by typetools.

the class QualifierDefaults method getTypeVarBoundType.

/**
 * Returns the boundType (UPPER or UNBOUNDED) of the declaration of typeParamElem.
 *
 * @param typeParamElem the type parameter element
 * @return the boundType (UPPER or UNBOUNDED) of the declaration of typeParamElem
 */
// Results are cached in {@link elementToBoundType}.
private BoundType getTypeVarBoundType(final TypeParameterElement typeParamElem) {
    final BoundType prev = elementToBoundType.get(typeParamElem);
    if (prev != null) {
        return prev;
    }
    TreePath declaredTypeVarEle = atypeFactory.getTreeUtils().getPath(typeParamElem);
    Tree typeParamDecl = declaredTypeVarEle == null ? null : declaredTypeVarEle.getLeaf();
    final BoundType boundType;
    if (typeParamDecl == null) {
        // when the compilation unit is no-longer available.
        if (typeParamElem.getBounds().size() == 1 && TypesUtils.isObject(typeParamElem.getBounds().get(0))) {
            // If the bound was Object, then it may or may not have been explicitly written.
            // Assume that it was not.
            boundType = BoundType.UNBOUNDED;
        } else {
            // The bound is not Object, so it must have been explicitly written and thus the
            // type variable has an upper bound.
            boundType = BoundType.UPPER;
        }
    } else {
        if (typeParamDecl.getKind() == Tree.Kind.TYPE_PARAMETER) {
            final TypeParameterTree tptree = (TypeParameterTree) typeParamDecl;
            List<? extends Tree> bnds = tptree.getBounds();
            if (bnds != null && !bnds.isEmpty()) {
                boundType = BoundType.UPPER;
            } else {
                boundType = BoundType.UNBOUNDED;
            }
        } else {
            throw new BugInCF(StringsPlume.joinLines("Unexpected tree type for typeVar Element:", "typeParamElem=" + typeParamElem, typeParamDecl));
        }
    }
    elementToBoundType.put(typeParamElem, boundType);
    return boundType;
}
Also used : TypeParameterTree(com.sun.source.tree.TypeParameterTree) TreePath(com.sun.source.util.TreePath) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) IdentifierTree(com.sun.source.tree.IdentifierTree) MemberSelectTree(com.sun.source.tree.MemberSelectTree) MethodTree(com.sun.source.tree.MethodTree) VariableTree(com.sun.source.tree.VariableTree) TypeParameterTree(com.sun.source.tree.TypeParameterTree) Tree(com.sun.source.tree.Tree) ClassTree(com.sun.source.tree.ClassTree) ExpressionTree(com.sun.source.tree.ExpressionTree) BugInCF(org.checkerframework.javacutil.BugInCF)

Example 7 with BugInCF

use of org.checkerframework.javacutil.BugInCF in project checker-framework by typetools.

the class DependentTypesHelper method atInvocation.

/**
 * Viewpoint-adapts a method or constructor invocation.
 *
 * <p>{@code methodType} has been viewpoint-adapted to the call site, except for any dependent
 * type annotations. (For example, type variables have been substituted and polymorphic qualifiers
 * have been resolved.) This method viewpoint-adapts the dependent type annotations.
 *
 * @param methodType type of the method or constructor invocation; is side-effected by this method
 * @param tree invocation of the method or constructor
 */
private void atInvocation(AnnotatedExecutableType methodType, ExpressionTree tree) {
    assert hasDependentAnnotations();
    Element methodElt = TreeUtils.elementFromUse(tree);
    // Because methodType is the type post type variable substitution, it has annotations from
    // both the method declaration and the type arguments at the use of the method. Annotations
    // from type arguments must not be viewpoint-adapted to the call site. For example:
    // Map<String, String> map = ...;
    // List<@KeyFor("this.map") String> list = ...;
    // list.get(0)
    // 
    // methodType is @KeyFor("this.map") String get(int)
    // "this.map" must not be viewpoint-adapted to the invocation because it is not from
    // the method declaration, but added during type variable substitution.
    // 
    // So this implementation gets the declared type of the method, declaredMethodType,
    // viewpoint-adapts all dependent type annotations in declaredMethodType to the call site,
    // and then copies the viewpoint-adapted annotations from methodType except for types that
    // are replaced by type variable substitution. (Those annotations are viewpoint-adapted
    // before type variable substitution.)
    // The annotations on `declaredMethodType` will be copied to `methodType`.
    AnnotatedExecutableType declaredMethodType = (AnnotatedExecutableType) factory.getAnnotatedType(methodElt);
    if (!hasDependentType(declaredMethodType)) {
        return;
    }
    StringToJavaExpression stringToJavaExpr;
    if (tree instanceof MethodInvocationTree) {
        stringToJavaExpr = stringExpr -> StringToJavaExpression.atMethodInvocation(stringExpr, (MethodInvocationTree) tree, factory.getChecker());
        if (debugStringToJavaExpression) {
            System.out.printf("atInvocation(%s, %s) 1 created %s%n", methodType, TreeUtils.toStringTruncated(tree, 65), stringToJavaExpr);
        }
    } else if (tree instanceof NewClassTree) {
        stringToJavaExpr = stringExpr -> StringToJavaExpression.atConstructorInvocation(stringExpr, (NewClassTree) tree, factory.getChecker());
        if (debugStringToJavaExpression) {
            System.out.printf("atInvocation(%s, %s) 2 created %s%n", methodType, TreeUtils.toStringTruncated(tree, 65), stringToJavaExpr);
        }
    } else {
        throw new BugInCF("Unexpected tree: %s kind: %s", tree, tree.getKind());
    }
    convertAnnotatedTypeMirror(stringToJavaExpr, declaredMethodType);
    this.viewpointAdaptedCopier.visit(declaredMethodType, methodType);
}
Also used : BugInCF(org.checkerframework.javacutil.BugInCF) TypeElement(javax.lang.model.element.TypeElement) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) LambdaExpressionTree(com.sun.source.tree.LambdaExpressionTree) Map(java.util.Map) Method(java.lang.reflect.Method) EnumSet(java.util.EnumSet) AnnotatedExecutableType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedExecutableType) TreePath(com.sun.source.util.TreePath) Set(java.util.Set) Element(javax.lang.model.element.Element) MemberSelectTree(com.sun.source.tree.MemberSelectTree) TreeUtils(org.checkerframework.javacutil.TreeUtils) AnnotatedTypeParameterBounds(org.checkerframework.framework.type.AnnotatedTypeParameterBounds) Unknown(org.checkerframework.dataflow.expression.Unknown) TypeKind(javax.lang.model.type.TypeKind) TreeAnnotator(org.checkerframework.framework.type.treeannotator.TreeAnnotator) List(java.util.List) LocalVariable(org.checkerframework.dataflow.expression.LocalVariable) AnnotatedDeclaredType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType) Annotation(java.lang.annotation.Annotation) ModifiersTree(com.sun.source.tree.ModifiersTree) TypesUtils(org.checkerframework.javacutil.TypesUtils) DoubleAnnotatedTypeScanner(org.checkerframework.framework.type.visitor.DoubleAnnotatedTypeScanner) AnnotatedTypeScanner(org.checkerframework.framework.type.visitor.AnnotatedTypeScanner) AnnotationTree(com.sun.source.tree.AnnotationTree) MethodTree(com.sun.source.tree.MethodTree) SourceChecker(org.checkerframework.framework.source.SourceChecker) VariableElement(javax.lang.model.element.VariableElement) VariableTree(com.sun.source.tree.VariableTree) HashMap(java.util.HashMap) Function(java.util.function.Function) ArrayList(java.util.ArrayList) NewClassTree(com.sun.source.tree.NewClassTree) TreePathUtil(org.checkerframework.javacutil.TreePathUtil) AnnotationBuilder(org.checkerframework.javacutil.AnnotationBuilder) Tree(com.sun.source.tree.Tree) AnnotationUtils(org.checkerframework.javacutil.AnnotationUtils) ClassTree(com.sun.source.tree.ClassTree) Nullable(org.checkerframework.checker.nullness.qual.Nullable) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) JavaExpressionParseException(org.checkerframework.framework.util.JavaExpressionParseUtil.JavaExpressionParseException) ElementKind(javax.lang.model.element.ElementKind) ExpressionTree(com.sun.source.tree.ExpressionTree) ExecutableElement(javax.lang.model.element.ExecutableElement) JavaExpression(org.checkerframework.dataflow.expression.JavaExpression) JavaExpressionConverter(org.checkerframework.dataflow.expression.JavaExpressionConverter) JCTree(com.sun.tools.javac.tree.JCTree) AnnotationMirror(javax.lang.model.element.AnnotationMirror) SimpleAnnotatedTypeScanner(org.checkerframework.framework.type.visitor.SimpleAnnotatedTypeScanner) StringToJavaExpression(org.checkerframework.framework.util.StringToJavaExpression) AnnotatedTypeFactory(org.checkerframework.framework.type.AnnotatedTypeFactory) TypeMirror(javax.lang.model.type.TypeMirror) ProcessingEnvironment(javax.annotation.processing.ProcessingEnvironment) FormalParameter(org.checkerframework.dataflow.expression.FormalParameter) Collections(java.util.Collections) ElementUtils(org.checkerframework.javacutil.ElementUtils) CollectionsPlume(org.plumelib.util.CollectionsPlume) AnnotatedExecutableType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedExecutableType) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) TypeElement(javax.lang.model.element.TypeElement) Element(javax.lang.model.element.Element) VariableElement(javax.lang.model.element.VariableElement) ExecutableElement(javax.lang.model.element.ExecutableElement) StringToJavaExpression(org.checkerframework.framework.util.StringToJavaExpression) NewClassTree(com.sun.source.tree.NewClassTree) BugInCF(org.checkerframework.javacutil.BugInCF)

Example 8 with BugInCF

use of org.checkerframework.javacutil.BugInCF in project checker-framework by typetools.

the class AnnotatedTypes method addTypeVarMappings.

private static void addTypeVarMappings(Types types, AnnotatedTypeFactory atypeFactory, AnnotatedTypeMirror t, TypeElement enclosingClassOfElem, Map<TypeVariable, AnnotatedTypeMirror> mappings) {
    if (enclosingClassOfElem.getTypeParameters().isEmpty()) {
        return;
    }
    AnnotatedDeclaredType enclosingType = atypeFactory.getAnnotatedType(enclosingClassOfElem);
    AnnotatedDeclaredType base = (AnnotatedDeclaredType) asOuterSuper(types, atypeFactory, t, enclosingType);
    base = (AnnotatedDeclaredType) atypeFactory.applyCaptureConversion(base);
    final List<AnnotatedTypeVariable> ownerParams = new ArrayList<>(enclosingType.getTypeArguments().size());
    for (final AnnotatedTypeMirror typeParam : enclosingType.getTypeArguments()) {
        if (typeParam.getKind() != TypeKind.TYPEVAR) {
            throw new BugInCF(StringsPlume.joinLines("Type arguments of a declaration should be type variables.", "  enclosingClassOfElem=" + enclosingClassOfElem, "  enclosingType=" + enclosingType, "  typeMirror=" + t));
        }
        ownerParams.add((AnnotatedTypeVariable) typeParam);
    }
    List<AnnotatedTypeMirror> baseParams = base.getTypeArguments();
    if (ownerParams.size() != baseParams.size() && !base.isUnderlyingTypeRaw()) {
        throw new BugInCF(StringsPlume.joinLines("Unexpected number of parameters.", "enclosingType=" + enclosingType, "baseType=" + base));
    }
    if (!ownerParams.isEmpty() && baseParams.isEmpty() && base.isUnderlyingTypeRaw()) {
        // If base type was raw and the type arguments are missing, set them to the erased
        // type of the type variable (which is the erased type of the upper bound).
        baseParams = CollectionsPlume.mapList(AnnotatedTypeVariable::getErased, ownerParams);
    }
    for (int i = 0; i < ownerParams.size(); ++i) {
        mappings.put(ownerParams.get(i).getUnderlyingType(), baseParams.get(i));
    }
}
Also used : AnnotatedDeclaredType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType) ArrayList(java.util.ArrayList) BugInCF(org.checkerframework.javacutil.BugInCF) AnnotatedTypeVariable(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror)

Example 9 with BugInCF

use of org.checkerframework.javacutil.BugInCF in project checker-framework by typetools.

the class AnnotatedTypes method findTypeArguments.

/**
 * Given a method or constructor invocation, return a mapping of the type variables to their type
 * arguments, if any exist.
 *
 * <p>It uses the method or constructor invocation type arguments if they were specified and
 * otherwise it infers them based on the passed arguments or the return type context, according to
 * JLS 15.12.2.
 *
 * @param atypeFactory the annotated type factory
 * @param expr the method or constructor invocation tree; the passed argument has to be a subtype
 *     of MethodInvocationTree or NewClassTree
 * @param elt the element corresponding to the tree
 * @param preType the (partially annotated) type corresponding to the tree - the result of
 *     AnnotatedTypes.asMemberOf with the receiver and elt
 * @return the mapping of the type variables to type arguments for this method or constructor
 *     invocation
 */
public static Map<TypeVariable, AnnotatedTypeMirror> findTypeArguments(final ProcessingEnvironment processingEnv, final AnnotatedTypeFactory atypeFactory, final ExpressionTree expr, final ExecutableElement elt, final AnnotatedExecutableType preType) {
    // Is the method a generic method?
    if (elt.getTypeParameters().isEmpty()) {
        return Collections.emptyMap();
    }
    List<? extends Tree> targs;
    if (expr instanceof MethodInvocationTree) {
        targs = ((MethodInvocationTree) expr).getTypeArguments();
    } else if (expr instanceof NewClassTree) {
        targs = ((NewClassTree) expr).getTypeArguments();
    } else if (expr instanceof MemberReferenceTree) {
        targs = ((MemberReferenceTree) expr).getTypeArguments();
        if (targs == null) {
            // TODO: Add type argument inference as part of fix for #979
            return new HashMap<>();
        }
    } else {
        // This case should never happen.
        throw new BugInCF("AnnotatedTypes.findTypeArguments: unexpected tree: " + expr);
    }
    // Has the user supplied type arguments?
    if (!targs.isEmpty()) {
        List<? extends AnnotatedTypeVariable> tvars = preType.getTypeVariables();
        Map<TypeVariable, AnnotatedTypeMirror> typeArguments = new HashMap<>();
        for (int i = 0; i < elt.getTypeParameters().size(); ++i) {
            AnnotatedTypeVariable typeVar = tvars.get(i);
            AnnotatedTypeMirror typeArg = atypeFactory.getAnnotatedTypeFromTypeTree(targs.get(i));
            // TODO: the call to getTypeParameterDeclaration shouldn't be necessary - typeVar
            // already should be a declaration.
            typeArguments.put(typeVar.getUnderlyingType(), typeArg);
        }
        return typeArguments;
    } else {
        return atypeFactory.getTypeArgumentInference().inferTypeArgs(atypeFactory, expr, elt, preType);
    }
}
Also used : HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) TypeVariable(javax.lang.model.type.TypeVariable) AnnotatedTypeVariable(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) MemberReferenceTree(com.sun.source.tree.MemberReferenceTree) NewClassTree(com.sun.source.tree.NewClassTree) BugInCF(org.checkerframework.javacutil.BugInCF) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) AnnotatedTypeVariable(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable)

Example 10 with BugInCF

use of org.checkerframework.javacutil.BugInCF in project checker-framework by typetools.

the class AnnotatedTypes method findEffectiveAnnotations.

/**
 * When comparing types against the bounds of a type variable, we may encounter other type
 * variables, wildcards, and intersections in those bounds. This method traverses the bounds until
 * it finds a concrete type from which it can pull an annotation. This occurs for every hierarchy
 * in QualifierHierarchy.
 *
 * @return the set of effective annotation mirrors in all hierarchies
 */
public static Set<AnnotationMirror> findEffectiveAnnotations(final QualifierHierarchy qualifierHierarchy, final AnnotatedTypeMirror toSearch) {
    AnnotatedTypeMirror source = toSearch;
    TypeKind kind = source.getKind();
    while (kind == TypeKind.TYPEVAR || kind == TypeKind.WILDCARD || kind == TypeKind.INTERSECTION) {
        switch(source.getKind()) {
            case TYPEVAR:
                source = ((AnnotatedTypeVariable) source).getUpperBound();
                break;
            case WILDCARD:
                source = ((AnnotatedWildcardType) source).getExtendsBound();
                break;
            case INTERSECTION:
                // if there are multiple conflicting annotations, choose the lowest
                final Set<AnnotationMirror> glb = glbOfBounds((AnnotatedIntersectionType) source, qualifierHierarchy);
                return glb;
            default:
                throw new BugInCF("Unexpected AnnotatedTypeMirror with no primary annotation;" + " toSearch=" + toSearch + " source=" + source);
        }
        kind = source.getKind();
    }
    return source.getAnnotations();
}
Also used : AnnotationMirror(javax.lang.model.element.AnnotationMirror) TypeKind(javax.lang.model.type.TypeKind) BugInCF(org.checkerframework.javacutil.BugInCF) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror)

Aggregations

BugInCF (org.checkerframework.javacutil.BugInCF)127 AnnotatedTypeMirror (org.checkerframework.framework.type.AnnotatedTypeMirror)29 ArrayList (java.util.ArrayList)28 AnnotationMirror (javax.lang.model.element.AnnotationMirror)26 TypeElement (javax.lang.model.element.TypeElement)26 TypeMirror (javax.lang.model.type.TypeMirror)25 ExecutableElement (javax.lang.model.element.ExecutableElement)24 MethodTree (com.sun.source.tree.MethodTree)20 ExpressionTree (com.sun.source.tree.ExpressionTree)18 VariableTree (com.sun.source.tree.VariableTree)18 Element (javax.lang.model.element.Element)18 ClassTree (com.sun.source.tree.ClassTree)17 MethodInvocationTree (com.sun.source.tree.MethodInvocationTree)17 NewClassTree (com.sun.source.tree.NewClassTree)17 LambdaExpressionTree (com.sun.source.tree.LambdaExpressionTree)16 IOException (java.io.IOException)16 Tree (com.sun.source.tree.Tree)15 Map (java.util.Map)15 List (java.util.List)14 VariableElement (javax.lang.model.element.VariableElement)14