Search in sources :

Example 11 with LambdaExpressionTree

use of com.sun.source.tree.LambdaExpressionTree in project checker-framework by typetools.

the class DependentTypesHelper method standardizeVariable.

public void standardizeVariable(Tree node, AnnotatedTypeMirror type, Element ele) {
    if (!hasDependentType(type)) {
        return;
    }
    TreePath path = factory.getPath(node);
    if (path == null) {
        return;
    }
    switch(ele.getKind()) {
        case PARAMETER:
            Tree enclTree = TreeUtils.enclosingOfKind(path, new HashSet<>(Arrays.asList(Kind.METHOD, Kind.LAMBDA_EXPRESSION)));
            if (enclTree.getKind() == Kind.METHOD) {
                // If the most enclosing tree is a method, the parameter is a method parameter
                MethodTree methodTree = (MethodTree) enclTree;
                TypeMirror enclosingType = ElementUtils.enclosingClass(ele).asType();
                FlowExpressionContext parameterContext = FlowExpressionContext.buildContextForMethodDeclaration(methodTree, enclosingType, factory.getContext());
                standardizeDoNotUseLocals(parameterContext, path, type);
            } else {
                // Otherwise, the parameter is a lambda parameter
                LambdaExpressionTree lambdaTree = (LambdaExpressionTree) enclTree;
                FlowExpressionContext parameterContext = FlowExpressionContext.buildContextForLambda(lambdaTree, path, factory.getContext());
                // TODO: test this.
                // TODO: use path.getParentPath to prevent a StackOverflowError, see Issue
                // #1027.
                standardizeUseLocals(parameterContext, path.getParentPath(), type);
            }
            break;
        case LOCAL_VARIABLE:
        case RESOURCE_VARIABLE:
        case EXCEPTION_PARAMETER:
            TypeMirror enclosingType = ElementUtils.enclosingClass(ele).asType();
            FlowExpressions.Receiver receiver = FlowExpressions.internalReprOfPseudoReceiver(path, enclosingType);
            List<Receiver> params = FlowExpressions.getParametersOfEnclosingMethod(factory, path);
            FlowExpressionContext localContext = new FlowExpressionContext(receiver, params, factory.getContext());
            standardizeUseLocals(localContext, path, type);
            break;
        case FIELD:
            FlowExpressions.Receiver receiverF;
            if (node.getKind() == Tree.Kind.IDENTIFIER) {
                FlowExpressions.Receiver r = FlowExpressions.internalReprOf(factory, (IdentifierTree) node);
                receiverF = r instanceof FlowExpressions.FieldAccess ? ((FlowExpressions.FieldAccess) r).getReceiver() : r;
            } else {
                receiverF = FlowExpressions.internalReprOfImplicitReceiver(ele);
            }
            FlowExpressionContext fieldContext = new FlowExpressionContext(receiverF, null, factory.getContext());
            standardizeDoNotUseLocals(fieldContext, path, type);
            break;
        default:
    }
}
Also used : LambdaExpressionTree(com.sun.source.tree.LambdaExpressionTree) TreePath(com.sun.source.util.TreePath) MethodTree(com.sun.source.tree.MethodTree) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) TypeMirror(javax.lang.model.type.TypeMirror) FlowExpressionContext(org.checkerframework.framework.util.FlowExpressionParseUtil.FlowExpressionContext) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) LambdaExpressionTree(com.sun.source.tree.LambdaExpressionTree) IdentifierTree(com.sun.source.tree.IdentifierTree) MemberSelectTree(com.sun.source.tree.MemberSelectTree) ModifiersTree(com.sun.source.tree.ModifiersTree) AnnotationTree(com.sun.source.tree.AnnotationTree) MethodTree(com.sun.source.tree.MethodTree) VariableTree(com.sun.source.tree.VariableTree) NewClassTree(com.sun.source.tree.NewClassTree) Tree(com.sun.source.tree.Tree) ExpressionTree(com.sun.source.tree.ExpressionTree) FlowExpressions(org.checkerframework.dataflow.analysis.FlowExpressions) Receiver(org.checkerframework.dataflow.analysis.FlowExpressions.Receiver) Receiver(org.checkerframework.dataflow.analysis.FlowExpressions.Receiver)

Example 12 with LambdaExpressionTree

use of com.sun.source.tree.LambdaExpressionTree in project st-js by st-js.

the class LambdaAccessFinalInLoopCheck method checkUsageInLambdas.

private void checkUsageInLambdas(VariableTree tree, GenerationContext<Void> context) {
    // this is the block containing the var definition
    TreePath blockPath = context.getCurrentPath().getParentPath();
    blockPath.getLeaf().accept(new TreeScanner<Void, Void>() {

        @Override
        public Void visitLambdaExpression(LambdaExpressionTree lambda, Void arg1) {
            checkVarInLambda(tree.getName(), lambda, context);
            return super.visitLambdaExpression(lambda, arg1);
        }
    }, null);
}
Also used : LambdaExpressionTree(com.sun.source.tree.LambdaExpressionTree) TreePath(com.sun.source.util.TreePath)

Example 13 with LambdaExpressionTree

use of com.sun.source.tree.LambdaExpressionTree in project checker-framework by typetools.

the class GuiEffectVisitor method scanUp.

/**
 * This method is called to traverse the path back up from any anonymous inner class or lambda
 * which has been inferred to be UI affecting and re-run {@code commonAssignmentCheck} as needed
 * on places where the class declaration or lambda expression are being assigned to a variable,
 * passed as a parameter or returned from a method. This is necessary because the normal visitor
 * traversal only checks assignments on the way down the AST, before inference has had a chance to
 * run.
 *
 * @param path the path to traverse up from a UI-affecting class
 */
private void scanUp(TreePath path) {
    Tree tree = path.getLeaf();
    switch(tree.getKind()) {
        case ASSIGNMENT:
            AssignmentTree assignmentTree = (AssignmentTree) tree;
            commonAssignmentCheck(atypeFactory.getAnnotatedType(assignmentTree.getVariable()), atypeFactory.getAnnotatedType(assignmentTree.getExpression()), assignmentTree.getExpression(), "assignment");
            break;
        case VARIABLE:
            VariableTree variableTree = (VariableTree) tree;
            commonAssignmentCheck(atypeFactory.getAnnotatedType(variableTree), atypeFactory.getAnnotatedType(variableTree.getInitializer()), variableTree.getInitializer(), "assignment");
            break;
        case METHOD_INVOCATION:
            MethodInvocationTree invocationTree = (MethodInvocationTree) tree;
            List<? extends ExpressionTree> args = invocationTree.getArguments();
            ParameterizedExecutableType mType = atypeFactory.methodFromUse(invocationTree);
            AnnotatedExecutableType invokedMethod = mType.executableType;
            ExecutableElement method = invokedMethod.getElement();
            CharSequence methodName = ElementUtils.getSimpleNameOrDescription(method);
            List<? extends VariableElement> methodParams = method.getParameters();
            List<AnnotatedTypeMirror> paramTypes = AnnotatedTypes.expandVarArgsParameters(atypeFactory, invokedMethod, invocationTree.getArguments());
            for (int i = 0; i < args.size(); ++i) {
                if (args.get(i).getKind() == Tree.Kind.NEW_CLASS || args.get(i).getKind() == Tree.Kind.LAMBDA_EXPRESSION) {
                    commonAssignmentCheck(paramTypes.get(i), atypeFactory.getAnnotatedType(args.get(i)), args.get(i), "argument", methodParams.get(i), methodName);
                }
            }
            break;
        case RETURN:
            ReturnTree returnTree = (ReturnTree) tree;
            if (returnTree.getExpression().getKind() == Tree.Kind.NEW_CLASS || returnTree.getExpression().getKind() == Tree.Kind.LAMBDA_EXPRESSION) {
                Tree enclosing = TreePathUtil.enclosingMethodOrLambda(path);
                AnnotatedTypeMirror ret = null;
                if (enclosing.getKind() == Tree.Kind.METHOD) {
                    MethodTree enclosingMethod = (MethodTree) enclosing;
                    boolean valid = validateTypeOf(enclosing);
                    if (valid) {
                        ret = atypeFactory.getMethodReturnType(enclosingMethod, returnTree);
                    }
                } else {
                    ret = atypeFactory.getFunctionTypeFromTree((LambdaExpressionTree) enclosing).getReturnType();
                }
                if (ret != null) {
                    commonAssignmentCheck(ret, atypeFactory.getAnnotatedType(returnTree.getExpression()), returnTree.getExpression(), "return");
                }
            }
            break;
        case METHOD:
            // without either being assigned to a field or returned.
            return;
        case CLASS:
            // boundaries
            assert false;
            return;
        default:
            scanUp(path.getParentPath());
    }
}
Also used : MethodTree(com.sun.source.tree.MethodTree) ExecutableElement(javax.lang.model.element.ExecutableElement) VariableTree(com.sun.source.tree.VariableTree) ReturnTree(com.sun.source.tree.ReturnTree) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) AnnotatedExecutableType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedExecutableType) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) ReturnTree(com.sun.source.tree.ReturnTree) MethodTree(com.sun.source.tree.MethodTree) VariableTree(com.sun.source.tree.VariableTree) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) AssignmentTree(com.sun.source.tree.AssignmentTree) NewClassTree(com.sun.source.tree.NewClassTree) LambdaExpressionTree(com.sun.source.tree.LambdaExpressionTree) Tree(com.sun.source.tree.Tree) ClassTree(com.sun.source.tree.ClassTree) ExpressionTree(com.sun.source.tree.ExpressionTree) AssignmentTree(com.sun.source.tree.AssignmentTree) ParameterizedExecutableType(org.checkerframework.framework.type.AnnotatedTypeFactory.ParameterizedExecutableType)

Example 14 with LambdaExpressionTree

use of com.sun.source.tree.LambdaExpressionTree in project checker-framework by typetools.

the class GuiEffectVisitor method visitMethodInvocation.

// Check that the invoked effect is <= permitted effect (effStack.peek())
@Override
public Void visitMethodInvocation(MethodInvocationTree node, Void p) {
    if (debugSpew) {
        System.err.println("For invocation " + node + " in " + currentMethods.peek().getName());
    }
    // Target method annotations
    ExecutableElement methodElt = TreeUtils.elementFromUse(node);
    if (debugSpew) {
        System.err.println("methodElt found");
    }
    Tree callerTree = TreePathUtil.enclosingMethodOrLambda(getCurrentPath());
    if (callerTree == null) {
        // Static initializer; let's assume this is safe to have the UI effect
        if (debugSpew) {
            System.err.println("No enclosing method: likely static initializer");
        }
        return super.visitMethodInvocation(node, p);
    }
    if (debugSpew) {
        System.err.println("callerTree found: " + callerTree.getKind());
    }
    Effect targetEffect = atypeFactory.getComputedEffectAtCallsite(node, receiverType, methodElt);
    Effect callerEffect = null;
    if (callerTree.getKind() == Tree.Kind.METHOD) {
        ExecutableElement callerElt = TreeUtils.elementFromDeclaration((MethodTree) callerTree);
        if (debugSpew) {
            System.err.println("callerElt found");
        }
        callerEffect = atypeFactory.getDeclaredEffect(callerElt);
        final DeclaredType callerReceiverType = classType.getUnderlyingType();
        assert callerReceiverType != null;
        final TypeElement callerReceiverElt = (TypeElement) callerReceiverType.asElement();
        // long.
        if (TypesUtils.isAnonymous(callerReceiverType) && // Skip if already inferred @UI
        !effStack.peek().isUI() && // Ignore if explicitly annotated
        !atypeFactory.fromElement(callerReceiverElt).hasAnnotation(AlwaysSafe.class) && !atypeFactory.fromElement(callerReceiverElt).hasAnnotation(UI.class)) {
            boolean overridesPolymorphic = false;
            Map<AnnotatedTypeMirror.AnnotatedDeclaredType, ExecutableElement> overriddenMethods = AnnotatedTypes.overriddenMethods(elements, atypeFactory, callerElt);
            for (Map.Entry<AnnotatedTypeMirror.AnnotatedDeclaredType, ExecutableElement> pair : overriddenMethods.entrySet()) {
                AnnotatedTypeMirror.AnnotatedDeclaredType overriddenType = pair.getKey();
                AnnotatedExecutableType overriddenMethod = AnnotatedTypes.asMemberOf(types, atypeFactory, overriddenType, pair.getValue());
                if (atypeFactory.getDeclAnnotation(overriddenMethod.getElement(), PolyUIEffect.class) != null && atypeFactory.getDeclAnnotation(overriddenType.getUnderlyingType().asElement(), PolyUIType.class) != null) {
                    overridesPolymorphic = true;
                    break;
                }
            }
            // @UI anon class
            if (overridesPolymorphic && targetEffect.isUI()) {
                // Mark the anonymous class as @UI
                atypeFactory.constrainAnonymousClassToUI(callerReceiverElt);
                // Then re-calculate this method's effect (it might still not be an
                // @PolyUIEffect method).
                callerEffect = atypeFactory.getDeclaredEffect(callerElt);
                effStack.pop();
                effStack.push(callerEffect);
            }
        }
        // --- the traversal goes straight from the class to the initializer.
        assert (currentMethods.peek() == null || callerEffect.equals(effStack.peek()));
    } else if (callerTree.getKind() == Tree.Kind.LAMBDA_EXPRESSION) {
        callerEffect = atypeFactory.getInferedEffectForLambdaExpression((LambdaExpressionTree) callerTree);
        // lambda
        if (targetEffect.isUI() && callerEffect.isPoly()) {
            atypeFactory.constrainLambdaToUI((LambdaExpressionTree) callerTree);
            callerEffect = new Effect(UIEffect.class);
        }
    }
    assert callerEffect != null;
    if (!Effect.lessThanOrEqualTo(targetEffect, callerEffect)) {
        checker.reportError(node, "call.ui", targetEffect, callerEffect);
        if (debugSpew) {
            System.err.println("Issuing error for node: " + node);
        }
    }
    if (debugSpew) {
        System.err.println("Successfully finished main non-recursive checkinv of invocation " + node);
    }
    return super.visitMethodInvocation(node, p);
}
Also used : TypeElement(javax.lang.model.element.TypeElement) ExecutableElement(javax.lang.model.element.ExecutableElement) AnnotatedDeclaredType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) AnnotatedExecutableType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedExecutableType) LambdaExpressionTree(com.sun.source.tree.LambdaExpressionTree) AnnotatedDeclaredType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType) ReturnTree(com.sun.source.tree.ReturnTree) MethodTree(com.sun.source.tree.MethodTree) VariableTree(com.sun.source.tree.VariableTree) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) AssignmentTree(com.sun.source.tree.AssignmentTree) NewClassTree(com.sun.source.tree.NewClassTree) LambdaExpressionTree(com.sun.source.tree.LambdaExpressionTree) Tree(com.sun.source.tree.Tree) ClassTree(com.sun.source.tree.ClassTree) ExpressionTree(com.sun.source.tree.ExpressionTree) SafeEffect(org.checkerframework.checker.guieffect.qual.SafeEffect) PolyUIEffect(org.checkerframework.checker.guieffect.qual.PolyUIEffect) UIEffect(org.checkerframework.checker.guieffect.qual.UIEffect) Map(java.util.Map) DeclaredType(javax.lang.model.type.DeclaredType) AnnotatedDeclaredType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType) AlwaysSafe(org.checkerframework.checker.guieffect.qual.AlwaysSafe)

Example 15 with LambdaExpressionTree

use of com.sun.source.tree.LambdaExpressionTree in project checker-framework by typetools.

the class TypeArgInferenceUtil method assignedTo.

/**
 * Returns the annotated type that the leaf of path is assigned to, if it is within an assignment
 * context. Returns the annotated type that the method invocation at the leaf is assigned to. If
 * the result is a primitive, return the boxed version.
 *
 * @param atypeFactory the type factory, for looking up types
 * @param path the path whole leaf to look up a type for
 * @return the type of path's leaf
 */
// AST node comparisons
@SuppressWarnings("interning:not.interned")
public static AnnotatedTypeMirror assignedTo(AnnotatedTypeFactory atypeFactory, TreePath path) {
    Tree assignmentContext = TreePathUtil.getAssignmentContext(path);
    AnnotatedTypeMirror res;
    if (assignmentContext == null) {
        res = null;
    } else if (assignmentContext instanceof AssignmentTree) {
        ExpressionTree variable = ((AssignmentTree) assignmentContext).getVariable();
        res = atypeFactory.getAnnotatedType(variable);
    } else if (assignmentContext instanceof CompoundAssignmentTree) {
        ExpressionTree variable = ((CompoundAssignmentTree) assignmentContext).getVariable();
        res = atypeFactory.getAnnotatedType(variable);
    } else if (assignmentContext instanceof MethodInvocationTree) {
        MethodInvocationTree methodInvocation = (MethodInvocationTree) assignmentContext;
        // TODO move to getAssignmentContext
        if (methodInvocation.getMethodSelect() instanceof MemberSelectTree && ((MemberSelectTree) methodInvocation.getMethodSelect()).getExpression() == path.getLeaf()) {
            return null;
        }
        ExecutableElement methodElt = TreeUtils.elementFromUse(methodInvocation);
        AnnotatedTypeMirror receiver = atypeFactory.getReceiverType(methodInvocation);
        if (TreeUtils.isSuperConstructorCall(methodInvocation)) {
            receiver = atypeFactory.getSelfType(methodInvocation);
        }
        res = assignedToExecutable(atypeFactory, path, methodElt, receiver, methodInvocation.getArguments());
    } else if (assignmentContext instanceof NewArrayTree) {
        // TODO: I left the previous implementation below, it definitely caused infinite loops
        // TODO: if you called it from places like the TreeAnnotator.
        res = null;
    // TODO: This may cause infinite loop
    // AnnotatedTypeMirror type =
    // atypeFactory.getAnnotatedType((NewArrayTree)assignmentContext);
    // type = AnnotatedTypes.innerMostType(type);
    // return type;
    } else if (assignmentContext instanceof NewClassTree) {
        // This need to be basically like MethodTree
        NewClassTree newClassTree = (NewClassTree) assignmentContext;
        if (newClassTree.getEnclosingExpression() instanceof NewClassTree && (newClassTree.getEnclosingExpression() == path.getLeaf())) {
            return null;
        }
        ExecutableElement constructorElt = TreeUtils.constructor(newClassTree);
        AnnotatedTypeMirror receiver = atypeFactory.fromNewClass(newClassTree);
        res = assignedToExecutable(atypeFactory, path, constructorElt, receiver, newClassTree.getArguments());
    } else if (assignmentContext instanceof ReturnTree) {
        HashSet<Tree.Kind> kinds = new HashSet<>(Arrays.asList(Tree.Kind.LAMBDA_EXPRESSION, Tree.Kind.METHOD));
        Tree enclosing = TreePathUtil.enclosingOfKind(path, kinds);
        if (enclosing.getKind() == Tree.Kind.METHOD) {
            res = atypeFactory.getAnnotatedType((MethodTree) enclosing).getReturnType();
        } else {
            AnnotatedExecutableType fninf = atypeFactory.getFunctionTypeFromTree((LambdaExpressionTree) enclosing);
            res = fninf.getReturnType();
        }
    } else if (assignmentContext instanceof VariableTree) {
        res = assignedToVariable(atypeFactory, assignmentContext);
    } else {
        throw new BugInCF("AnnotatedTypes.assignedTo: shouldn't be here");
    }
    if (res != null && TypesUtils.isPrimitive(res.getUnderlyingType())) {
        return atypeFactory.getBoxedType((AnnotatedPrimitiveType) res);
    } else {
        return res;
    }
}
Also used : MemberSelectTree(com.sun.source.tree.MemberSelectTree) ExecutableElement(javax.lang.model.element.ExecutableElement) VariableTree(com.sun.source.tree.VariableTree) NewClassTree(com.sun.source.tree.NewClassTree) ReturnTree(com.sun.source.tree.ReturnTree) BugInCF(org.checkerframework.javacutil.BugInCF) AnnotatedTypeMirror(org.checkerframework.framework.type.AnnotatedTypeMirror) CompoundAssignmentTree(com.sun.source.tree.CompoundAssignmentTree) AnnotatedExecutableType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedExecutableType) NewArrayTree(com.sun.source.tree.NewArrayTree) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) TypeKind(javax.lang.model.type.TypeKind) CompoundAssignmentTree(com.sun.source.tree.CompoundAssignmentTree) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) AssignmentTree(com.sun.source.tree.AssignmentTree) LambdaExpressionTree(com.sun.source.tree.LambdaExpressionTree) NewArrayTree(com.sun.source.tree.NewArrayTree) ConditionalExpressionTree(com.sun.source.tree.ConditionalExpressionTree) MemberSelectTree(com.sun.source.tree.MemberSelectTree) ReturnTree(com.sun.source.tree.ReturnTree) MethodTree(com.sun.source.tree.MethodTree) VariableTree(com.sun.source.tree.VariableTree) NewClassTree(com.sun.source.tree.NewClassTree) Tree(com.sun.source.tree.Tree) ExpressionTree(com.sun.source.tree.ExpressionTree) LambdaExpressionTree(com.sun.source.tree.LambdaExpressionTree) ConditionalExpressionTree(com.sun.source.tree.ConditionalExpressionTree) ExpressionTree(com.sun.source.tree.ExpressionTree) CompoundAssignmentTree(com.sun.source.tree.CompoundAssignmentTree) AssignmentTree(com.sun.source.tree.AssignmentTree) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet)

Aggregations

LambdaExpressionTree (com.sun.source.tree.LambdaExpressionTree)22 MethodTree (com.sun.source.tree.MethodTree)19 VariableTree (com.sun.source.tree.VariableTree)15 ExpressionTree (com.sun.source.tree.ExpressionTree)14 Tree (com.sun.source.tree.Tree)13 MethodInvocationTree (com.sun.source.tree.MethodInvocationTree)12 NewClassTree (com.sun.source.tree.NewClassTree)11 ClassTree (com.sun.source.tree.ClassTree)10 ReturnTree (com.sun.source.tree.ReturnTree)9 AssignmentTree (com.sun.source.tree.AssignmentTree)8 AnnotatedTypeMirror (org.checkerframework.framework.type.AnnotatedTypeMirror)7 AnnotationTree (com.sun.source.tree.AnnotationTree)6 MemberReferenceTree (com.sun.source.tree.MemberReferenceTree)6 MemberSelectTree (com.sun.source.tree.MemberSelectTree)6 AnnotatedExecutableType (org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedExecutableType)6 TreePath (com.sun.source.util.TreePath)5 CFGMethod (org.checkerframework.dataflow.cfg.UnderlyingAST.CFGMethod)5 CompilationUnitTree (com.sun.source.tree.CompilationUnitTree)4 CompoundAssignmentTree (com.sun.source.tree.CompoundAssignmentTree)4 ConditionalExpressionTree (com.sun.source.tree.ConditionalExpressionTree)4