Search in sources :

Example 6 with Pair

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

the class FlowExpressionParseUtil method parseMemberSelect.

/**
 * Matches a field access. First of returned pair is object and second is field.
 *
 * @param s expression string
 * @return pair of object and field
 */
private static Pair<String, String> parseMemberSelect(String s) {
    Pair<Pair<String, String>, String> method = parseMethod(s);
    if (method != null && method.second.startsWith(".")) {
        return Pair.of(method.first.first + "(" + method.first.second + ")", method.second.substring(1));
    }
    Pair<Pair<String, String>, String> array = parseArray(s);
    if (array != null && array.second.startsWith(".")) {
        return Pair.of(array.first.first + "[" + array.first.second + "]", array.second.substring(1));
    }
    Pattern memberSelectOfStringPattern = anchored("(" + stringRegex + ")" + "\\.(.*)");
    Matcher m = memberSelectOfStringPattern.matcher(s);
    if (m.matches()) {
        return Pair.of(m.group(1), m.group(2));
    }
    int nextRParenPos = matchingCloseParen(s, 0, '(', ')');
    if (nextRParenPos != -1) {
        if (nextRParenPos + 1 < s.length() && s.charAt(nextRParenPos + 1) == '.') {
            String reciever = s.substring(0, nextRParenPos + 1);
            String remaining = s.substring(nextRParenPos + 2);
            return Pair.of(reciever, remaining);
        } else {
            return null;
        }
    }
    int i = s.indexOf(".");
    if (i == -1) {
        return null;
    }
    String reciever = s.substring(0, i);
    String remaining = s.substring(i + 1);
    return Pair.of(reciever, remaining);
}
Also used : Pattern(java.util.regex.Pattern) Matcher(java.util.regex.Matcher) Pair(org.checkerframework.javacutil.Pair)

Example 7 with Pair

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

the class Analysis method getReturnStatementStores.

public List<Pair<ReturnNode, TransferResult<A, S>>> getReturnStatementStores() {
    List<Pair<ReturnNode, TransferResult<A, S>>> result = new ArrayList<>();
    for (ReturnNode returnNode : cfg.getReturnNodes()) {
        TransferResult<A, S> store = storesAtReturnStatements.get(returnNode);
        result.add(Pair.of(returnNode, store));
    }
    return result;
}
Also used : ReturnNode(org.checkerframework.dataflow.cfg.node.ReturnNode) ArrayList(java.util.ArrayList) Pair(org.checkerframework.javacutil.Pair)

Example 8 with Pair

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

the class KeyForPropagator method propagate.

/**
 * Propagate annotations from the type arguments of one type to another. Which type is the source
 * and destination of the annotations depends on the direction parameter. Only @KeyFor annotations
 * are propagated and only if the type to which it would be propagated contains an @UnknownKeyFor
 * or contains no key for annotations of any kind. If any of the type arguments are wildcards than
 * they are ignored.
 *
 * <p>Note the primary annotations of subtype/supertype are not used.
 *
 * <p>Simple Example:
 *
 * <pre>{@code
 * typeOf(subtype) = ArrayList<@KeyFor("a") String>
 * typeOf(supertype) = List<@UnknownKeyFor String>
 * direction = TO_SUPERTYPE
 * }</pre>
 *
 * The type of supertype after propagate would be: {@code List<@KeyFor("a") String>}
 *
 * <p>A more complex example would be:
 *
 * <pre>{@code
 * typeOf(subtype) = HashMap<@UnknownKeyFor String, @KeyFor("b") List<@KeyFor("c") String>>
 * typeOf(supertype) = Map<@KeyFor("a") String, @KeyFor("b") List<@KeyFor("c") String>>
 * direction = TO_SUBTYPE
 * }</pre>
 *
 * The type of subtype after propagate would be: {@code HashMap<@KeyFor("a") String, @KeyFor("b")
 * List<@KeyFor("c") String>>}
 */
public void propagate(final AnnotatedDeclaredType subtype, final AnnotatedDeclaredType supertype, PropagationDirection direction, final AnnotatedTypeFactory typeFactory) {
    final TypeElement subtypeElement = (TypeElement) subtype.getUnderlyingType().asElement();
    final TypeElement supertypeElement = (TypeElement) supertype.getUnderlyingType().asElement();
    final Types types = typeFactory.getProcessingEnv().getTypeUtils();
    // Note: The right hand side of this or expression will cover raw types
    if (subtype.getTypeArguments().isEmpty()) {
        return;
    }
    // In either case, there is no reason to propagate
    if (supertype.getTypeArguments().isEmpty()) {
        return;
    }
    Set<Pair<Integer, Integer>> typeParamMappings = TypeArgumentMapper.mapTypeArgumentIndices(subtypeElement, supertypeElement, types);
    final List<AnnotatedTypeMirror> subtypeArgs = subtype.getTypeArguments();
    final List<AnnotatedTypeMirror> supertypeArgs = supertype.getTypeArguments();
    for (final Pair<Integer, Integer> path : typeParamMappings) {
        final AnnotatedTypeMirror subtypeArg = subtypeArgs.get(path.first);
        final AnnotatedTypeMirror supertypeArg = supertypeArgs.get(path.second);
        if (subtypeArg.getKind() == TypeKind.WILDCARD || supertypeArg.getKind() == TypeKind.WILDCARD) {
            continue;
        }
        switch(direction) {
            case TO_SUBTYPE:
                replacer.visit(supertypeArg, subtypeArg);
                break;
            case TO_SUPERTYPE:
                replacer.visit(subtypeArg, supertypeArg);
                break;
            case BOTH:
                // note if they both have an annotation nothing will happen
                replacer.visit(subtypeArg, supertypeArg);
                replacer.visit(supertypeArg, subtypeArg);
                break;
        }
    }
}
Also used : Types(javax.lang.model.util.Types) TypeElement(javax.lang.model.element.TypeElement) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) Pair(org.checkerframework.javacutil.Pair)

Example 9 with Pair

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

the class ContractsFromMethod method getContracts.

// / Helper methods
/**
 * Returns the contracts (of a particular kind) on method or constructor {@code
 * executableElement}.
 *
 * @param <T> the type of {@link Contract} to return
 * @param executableElement the method whose contracts to return
 * @param kind the kind of contracts to retrieve
 * @param clazz the class to determine the return type
 * @return the contracts on {@code executableElement}
 */
private <T extends Contract> Set<T> getContracts(ExecutableElement executableElement, Kind kind, Class<T> clazz) {
    Set<T> result = new LinkedHashSet<>();
    // Check for a single framework-defined contract annotation.
    AnnotationMirror frameworkContractAnno = factory.getDeclAnnotation(executableElement, kind.frameworkContractClass);
    result.addAll(getContract(kind, frameworkContractAnno, clazz));
    // Check for a framework-defined wrapper around contract annotations.
    // The result is RequiresQualifier.List, EnsuresQualifier.List, or EnsuresQualifierIf.List.
    AnnotationMirror frameworkContractListAnno = factory.getDeclAnnotation(executableElement, kind.frameworkContractListClass);
    if (frameworkContractListAnno != null) {
        List<AnnotationMirror> frameworkContractAnnoList = factory.getContractListValues(frameworkContractListAnno);
        for (AnnotationMirror a : frameworkContractAnnoList) {
            result.addAll(getContract(kind, a, clazz));
        }
    }
    // Check for type-system specific annotations.
    List<Pair<AnnotationMirror, AnnotationMirror>> declAnnotations = factory.getDeclAnnotationWithMetaAnnotation(executableElement, kind.metaAnnotation);
    for (Pair<AnnotationMirror, AnnotationMirror> r : declAnnotations) {
        AnnotationMirror anno = r.first;
        // contractAnno is the meta-annotation on anno.
        AnnotationMirror contractAnno = r.second;
        AnnotationMirror enforcedQualifier = getQualifierEnforcedByContractAnnotation(contractAnno, anno);
        if (enforcedQualifier == null) {
            continue;
        }
        List<String> expressions = factory.getContractExpressions(kind, anno);
        Collections.sort(expressions);
        Boolean ensuresQualifierIfResult = factory.getEnsuresQualifierIfResult(kind, anno);
        for (String expr : expressions) {
            T contract = clazz.cast(Contract.create(kind, expr, enforcedQualifier, anno, ensuresQualifierIfResult));
            result.add(contract);
        }
    }
    return result;
}
Also used : LinkedHashSet(java.util.LinkedHashSet) AnnotationMirror(javax.lang.model.element.AnnotationMirror) Pair(org.checkerframework.javacutil.Pair)

Example 10 with Pair

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

the class BaseTypeVisitor method parseAndLocalizeContracts.

/**
 * Localizes some contracts -- that is, viewpoint-adapts them to some method body, according to
 * the value of {@link #methodTree}.
 *
 * <p>The input is a set of {@link Contract}s, each of which contains an expression string and an
 * annotation. In a {@link Contract}, Java expressions are exactly as written in source code, not
 * standardized or viewpoint-adapted.
 *
 * <p>The output is a set of pairs of {@link JavaExpression} (parsed expression string) and
 * standardized annotation (with respect to the path of {@link #methodTree}. This method discards
 * any contract whose expression cannot be parsed into a JavaExpression.
 *
 * @param contractSet a set of contracts
 * @param methodType the type of the method that the contracts are for
 * @return pairs of (expression, AnnotationMirror), which are localized contracts
 */
private Set<Pair<JavaExpression, AnnotationMirror>> parseAndLocalizeContracts(Set<? extends Contract> contractSet, AnnotatedExecutableType methodType) {
    if (contractSet.isEmpty()) {
        return Collections.emptySet();
    }
    // This is the path to a place where the contract is being used, which might or might not be
    // where the contract was defined.  For example, methodTree might be an overriding
    // definition, and the contract might be for a superclass.
    MethodTree methodTree = this.methodTree;
    StringToJavaExpression stringToJavaExpr = expression -> {
        JavaExpression javaExpr = StringToJavaExpression.atMethodDecl(expression, methodType.getElement(), checker);
        // viewpoint-adapt it to methodTree.
        return javaExpr.atMethodBody(methodTree);
    };
    Set<Pair<JavaExpression, AnnotationMirror>> result = new HashSet<>(contractSet.size());
    for (Contract p : contractSet) {
        String expressionString = p.expressionString;
        AnnotationMirror annotation = p.viewpointAdaptDependentTypeAnnotation(atypeFactory, stringToJavaExpr, methodTree);
        JavaExpression exprJe;
        try {
            // TODO: currently, these expressions are parsed many times.
            // This could be optimized to store the result the first time.
            // (same for other annotations)
            exprJe = stringToJavaExpr.toJavaExpression(expressionString);
        } catch (JavaExpressionParseException e) {
            // report errors here
            checker.report(methodTree, e.getDiagMessage());
            continue;
        }
        result.add(Pair.of(exprJe, annotation));
    }
    return result;
}
Also used : AnnotationEqualityVisitor(org.checkerframework.framework.ajava.AnnotationEqualityVisitor) CompoundAssignmentTree(com.sun.source.tree.CompoundAssignmentTree) Arrays(java.util.Arrays) TransferResult(org.checkerframework.dataflow.analysis.TransferResult) AnnotatedArrayType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedArrayType) Modifier(javax.lang.model.element.Modifier) QualifierHierarchy(org.checkerframework.framework.type.QualifierHierarchy) TypeElement(javax.lang.model.element.TypeElement) ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) DefaultPrettyPrinter(com.github.javaparser.printer.DefaultPrettyPrinter) GenericAnnotatedTypeFactory(org.checkerframework.framework.type.GenericAnnotatedTypeFactory) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) AssignmentTree(com.sun.source.tree.AssignmentTree) TypeCastTree(com.sun.source.tree.TypeCastTree) Vector(java.util.Vector) LambdaExpressionTree(com.sun.source.tree.LambdaExpressionTree) Map(java.util.Map) InstanceOfTree(com.sun.source.tree.InstanceOfTree) EnumSet(java.util.EnumSet) SideEffectFree(org.checkerframework.dataflow.qual.SideEffectFree) AnnotatedExecutableType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedExecutableType) ConditionalExpressionTree(com.sun.source.tree.ConditionalExpressionTree) TreePath(com.sun.source.util.TreePath) Pure(org.checkerframework.dataflow.qual.Pure) Set(java.util.Set) AnnotatedWildcardType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedWildcardType) Element(javax.lang.model.element.Element) MemberSelectTree(com.sun.source.tree.MemberSelectTree) TreeUtils(org.checkerframework.javacutil.TreeUtils) TreeScanner(com.sun.source.util.TreeScanner) ParameterizedExecutableType(org.checkerframework.framework.type.AnnotatedTypeFactory.ParameterizedExecutableType) Unused(org.checkerframework.framework.qual.Unused) ThrowTree(com.sun.source.tree.ThrowTree) JCIdent(com.sun.tools.javac.tree.JCTree.JCIdent) AnnotationValue(javax.lang.model.element.AnnotationValue) EnhancedForLoopTree(com.sun.source.tree.EnhancedForLoopTree) TypesUtils(org.checkerframework.javacutil.TypesUtils) AnnotatedPrimitiveType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedPrimitiveType) ReturnTree(com.sun.source.tree.ReturnTree) PurityResult(org.checkerframework.dataflow.util.PurityChecker.PurityResult) ArrayTypeTree(com.sun.source.tree.ArrayTypeTree) ConditionalPostcondition(org.checkerframework.framework.util.Contract.ConditionalPostcondition) UnaryTree(com.sun.source.tree.UnaryTree) CFAbstractValue(org.checkerframework.framework.flow.CFAbstractValue) VariableElement(javax.lang.model.element.VariableElement) VariableTree(com.sun.source.tree.VariableTree) BooleanLiteralNode(org.checkerframework.dataflow.cfg.node.BooleanLiteralNode) ReferenceKind(com.sun.tools.javac.tree.JCTree.JCMemberReference.ReferenceKind) TypeParameterTree(com.sun.source.tree.TypeParameterTree) ArrayList(java.util.ArrayList) CompilerMessageKey(org.checkerframework.checker.compilermsgs.qual.CompilerMessageKey) NewClassTree(com.sun.source.tree.NewClassTree) ParameterizedTypeTree(com.sun.source.tree.ParameterizedTypeTree) Precondition(org.checkerframework.framework.util.Contract.Precondition) FindDistinct(org.checkerframework.checker.interning.qual.FindDistinct) SwitchExpressionScanner(org.checkerframework.javacutil.SwitchExpressionScanner) TreeInfo(com.sun.tools.javac.tree.TreeInfo) DeclaredType(javax.lang.model.type.DeclaredType) TreePathUtil(org.checkerframework.javacutil.TreePathUtil) ElementFilter(javax.lang.model.util.ElementFilter) Tree(com.sun.source.tree.Tree) LinkedHashSet(java.util.LinkedHashSet) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) SourceVisitor(org.checkerframework.framework.source.SourceVisitor) QualifierPolymorphism(org.checkerframework.framework.type.poly.QualifierPolymorphism) FieldInvariants(org.checkerframework.framework.util.FieldInvariants) ExpressionTree(com.sun.source.tree.ExpressionTree) IOException(java.io.IOException) Target(java.lang.annotation.Target) AnnotationMirror(javax.lang.model.element.AnnotationMirror) StringToJavaExpression(org.checkerframework.framework.util.StringToJavaExpression) ParseProblemException(com.github.javaparser.ParseProblemException) DiagMessage(org.checkerframework.framework.source.DiagMessage) SourcePositions(com.sun.source.util.SourcePositions) IntersectionTypeTree(com.sun.source.tree.IntersectionTypeTree) FunctionalSwitchExpressionScanner(org.checkerframework.javacutil.SwitchExpressionScanner.FunctionalSwitchExpressionScanner) ElementUtils(org.checkerframework.javacutil.ElementUtils) ContractsFromMethod(org.checkerframework.framework.util.ContractsFromMethod) CollectionsPlume(org.plumelib.util.CollectionsPlume) PurityUtils(org.checkerframework.dataflow.util.PurityUtils) JointVisitorWithDefaultAction(org.checkerframework.framework.ajava.JointVisitorWithDefaultAction) AnnotatedIntersectionType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedIntersectionType) BugInCF(org.checkerframework.javacutil.BugInCF) PurityChecker(org.checkerframework.dataflow.util.PurityChecker) JCFieldAccess(com.sun.tools.javac.tree.JCTree.JCFieldAccess) AnnotatedTypeTree(com.sun.source.tree.AnnotatedTypeTree) InsertAjavaAnnotations(org.checkerframework.framework.ajava.InsertAjavaAnnotations) JCMemberReference(com.sun.tools.javac.tree.JCTree.JCMemberReference) IdentifierTree(com.sun.source.tree.IdentifierTree) CatchTree(com.sun.source.tree.CatchTree) NewArrayTree(com.sun.source.tree.NewArrayTree) CompilationUnit(com.github.javaparser.ast.CompilationUnit) Pair(org.checkerframework.javacutil.Pair) ArraysPlume(org.plumelib.util.ArraysPlume) ReferenceMode(com.sun.source.tree.MemberReferenceTree.ReferenceMode) Analysis(org.checkerframework.dataflow.analysis.Analysis) WholeProgramInference(org.checkerframework.common.wholeprograminference.WholeProgramInference) ExpectedTreesVisitor(org.checkerframework.framework.ajava.ExpectedTreesVisitor) CFAbstractStore(org.checkerframework.framework.flow.CFAbstractStore) Contract(org.checkerframework.framework.util.Contract) CompilationUnitTree(com.sun.source.tree.CompilationUnitTree) AnnotatedTypeParameterBounds(org.checkerframework.framework.type.AnnotatedTypeParameterBounds) TypeKind(javax.lang.model.type.TypeKind) List(java.util.List) LocalVariable(org.checkerframework.dataflow.expression.LocalVariable) AnnotatedDeclaredType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType) TypeHierarchy(org.checkerframework.framework.type.TypeHierarchy) Annotation(java.lang.annotation.Annotation) ModifiersTree(com.sun.source.tree.ModifiersTree) AnnotatedTypes(org.checkerframework.framework.util.AnnotatedTypes) Postcondition(org.checkerframework.framework.util.Contract.Postcondition) AnnotatedTypeVariable(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedTypeVariable) AnnotationTree(com.sun.source.tree.AnnotationTree) MethodTree(com.sun.source.tree.MethodTree) HashMap(java.util.HashMap) HashSet(java.util.HashSet) Kind(javax.tools.Diagnostic.Kind) AnnotationBuilder(org.checkerframework.javacutil.AnnotationBuilder) AnnotationUtils(org.checkerframework.javacutil.AnnotationUtils) ClassTree(com.sun.source.tree.ClassTree) Nullable(org.checkerframework.checker.nullness.qual.Nullable) Name(javax.lang.model.element.Name) JavaExpressionParseException(org.checkerframework.framework.util.JavaExpressionParseUtil.JavaExpressionParseException) ElementKind(javax.lang.model.element.ElementKind) MemberReferenceTree(com.sun.source.tree.MemberReferenceTree) ExecutableElement(javax.lang.model.element.ExecutableElement) ReturnNode(org.checkerframework.dataflow.cfg.node.ReturnNode) JavaExpression(org.checkerframework.dataflow.expression.JavaExpression) JCTree(com.sun.tools.javac.tree.JCTree) ElementType(java.lang.annotation.ElementType) SimpleAnnotatedTypeScanner(org.checkerframework.framework.type.visitor.SimpleAnnotatedTypeScanner) JavaExpressionScanner(org.checkerframework.dataflow.expression.JavaExpressionScanner) AnnotatedTypeFactory(org.checkerframework.framework.type.AnnotatedTypeFactory) AnnotatedUnionType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedUnionType) TypeMirror(javax.lang.model.type.TypeMirror) StringJoiner(java.util.StringJoiner) ProcessingEnvironment(javax.annotation.processing.ProcessingEnvironment) Deterministic(org.checkerframework.dataflow.qual.Deterministic) JavaParserUtil(org.checkerframework.framework.util.JavaParserUtil) Collections(java.util.Collections) Node(org.checkerframework.dataflow.cfg.node.Node) DefaultQualifier(org.checkerframework.framework.qual.DefaultQualifier) InputStream(java.io.InputStream) AnnotationMirror(javax.lang.model.element.AnnotationMirror) StringToJavaExpression(org.checkerframework.framework.util.StringToJavaExpression) JavaExpression(org.checkerframework.dataflow.expression.JavaExpression) MethodTree(com.sun.source.tree.MethodTree) StringToJavaExpression(org.checkerframework.framework.util.StringToJavaExpression) JavaExpressionParseException(org.checkerframework.framework.util.JavaExpressionParseUtil.JavaExpressionParseException) Contract(org.checkerframework.framework.util.Contract) Pair(org.checkerframework.javacutil.Pair) LinkedHashSet(java.util.LinkedHashSet) HashSet(java.util.HashSet)

Aggregations

Pair (org.checkerframework.javacutil.Pair)31 AnnotationMirror (javax.lang.model.element.AnnotationMirror)12 ArrayList (java.util.ArrayList)11 LinkedHashSet (java.util.LinkedHashSet)8 TypeElement (javax.lang.model.element.TypeElement)7 TypeMirror (javax.lang.model.type.TypeMirror)7 MethodTree (com.sun.source.tree.MethodTree)6 Tree (com.sun.source.tree.Tree)6 HashMap (java.util.HashMap)6 ExecutableElement (javax.lang.model.element.ExecutableElement)6 VariableElement (javax.lang.model.element.VariableElement)6 ClassTree (com.sun.source.tree.ClassTree)5 VariableTree (com.sun.source.tree.VariableTree)5 ExpressionTree (com.sun.source.tree.ExpressionTree)4 NewClassTree (com.sun.source.tree.NewClassTree)4 LinkedHashMap (java.util.LinkedHashMap)4 Map (java.util.Map)4 Element (javax.lang.model.element.Element)4 Nullable (org.checkerframework.checker.nullness.qual.Nullable)4 Receiver (org.checkerframework.dataflow.analysis.FlowExpressions.Receiver)4