Search in sources :

Example 66 with VariableTree

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

the class QualifierDefaults method nearestEnclosingExceptLocal.

/**
 * Determines the nearest enclosing element for a tree by climbing the tree toward the root and
 * obtaining the element for the first declaration (variable, method, or class) that encloses
 * the tree. Initializers of local variables are handled in a special way: within an initializer
 * we look for the DefaultQualifier(s) annotation and keep track of the previously visited tree.
 * TODO: explain the behavior better.
 *
 * @param tree the tree
 * @return the nearest enclosing element for a tree
 */
private Element nearestEnclosingExceptLocal(Tree tree) {
    TreePath path = atypeFactory.getPath(tree);
    if (path == null) {
        Element method = atypeFactory.getEnclosingMethod(tree);
        if (method != null) {
            return method;
        } else {
            return TreeUtils.elementFromTree(tree);
        }
    }
    Tree prev = null;
    for (Tree t : path) {
        switch(t.getKind()) {
            case VARIABLE:
                VariableTree vtree = (VariableTree) t;
                ExpressionTree vtreeInit = vtree.getInitializer();
                if (vtreeInit != null && prev == vtreeInit) {
                    Element elt = TreeUtils.elementFromDeclaration((VariableTree) t);
                    DefaultQualifier d = elt.getAnnotation(DefaultQualifier.class);
                    DefaultQualifiers ds = elt.getAnnotation(DefaultQualifiers.class);
                    if (d == null && ds == null) {
                        break;
                    }
                }
                if (prev != null && prev.getKind() == Tree.Kind.MODIFIERS) {
                    // type.
                    break;
                }
                return TreeUtils.elementFromDeclaration((VariableTree) t);
            case METHOD:
                return TreeUtils.elementFromDeclaration((MethodTree) t);
            case CLASS:
            case ENUM:
            case INTERFACE:
            case ANNOTATION_TYPE:
                return TreeUtils.elementFromDeclaration((ClassTree) t);
            // Do nothing.
            default:
        }
        prev = t;
    }
    return null;
}
Also used : TreePath(com.sun.source.util.TreePath) Element(javax.lang.model.element.Element) PackageElement(javax.lang.model.element.PackageElement) TypeParameterElement(javax.lang.model.element.TypeParameterElement) VariableTree(com.sun.source.tree.VariableTree) 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) ExpressionTree(com.sun.source.tree.ExpressionTree) DefaultQualifiers(org.checkerframework.framework.qual.DefaultQualifiers) DefaultQualifier(org.checkerframework.framework.qual.DefaultQualifier)

Example 67 with VariableTree

use of com.sun.source.tree.VariableTree 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.
 *
 * @return type that path leaf is assigned to
 */
public static AnnotatedTypeMirror assignedTo(AnnotatedTypeFactory atypeFactory, TreePath path) {
    Tree assignmentContext = TreeUtils.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);
        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;
    // FIXME: 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;
        ExecutableElement constructorElt = TreeUtils.constructor(newClassTree);
        AnnotatedTypeMirror receiver = atypeFactory.fromNewClass(newClassTree);
        res = assignedToExecutable(atypeFactory, path, constructorElt, receiver, newClassTree.getArguments());
    } else if (assignmentContext instanceof ReturnTree) {
        HashSet<Kind> kinds = new HashSet<>(Arrays.asList(Kind.LAMBDA_EXPRESSION, Kind.METHOD));
        Tree enclosing = TreeUtils.enclosingOfKind(path, kinds);
        if (enclosing.getKind() == Kind.METHOD) {
            res = (atypeFactory.getAnnotatedType((MethodTree) enclosing)).getReturnType();
        } else {
            Pair<AnnotatedDeclaredType, AnnotatedExecutableType> fninf = atypeFactory.getFnInterfaceFromTree((LambdaExpressionTree) enclosing);
            res = fninf.second.getReturnType();
        }
    } else if (assignmentContext instanceof VariableTree) {
        res = assignedToVariable(atypeFactory, assignmentContext);
    } else {
        ErrorReporter.errorAbort("AnnotatedTypes.assignedTo: shouldn't be here!");
        res = null;
    }
    if (res != null && TypesUtils.isPrimitive(res.getUnderlyingType())) {
        return atypeFactory.getBoxedType((AnnotatedPrimitiveType) res);
    } else {
        return res;
    }
}
Also used : MethodTree(com.sun.source.tree.MethodTree) 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) 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) Kind(com.sun.source.tree.Tree.Kind) TypeKind(javax.lang.model.type.TypeKind) AnnotatedDeclaredType(org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType) ReturnTree(com.sun.source.tree.ReturnTree) CompoundAssignmentTree(com.sun.source.tree.CompoundAssignmentTree) 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) NewArrayTree(com.sun.source.tree.NewArrayTree) Tree(com.sun.source.tree.Tree) ConditionalExpressionTree(com.sun.source.tree.ConditionalExpressionTree) ExpressionTree(com.sun.source.tree.ExpressionTree) MemberSelectTree(com.sun.source.tree.MemberSelectTree) 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)

Example 68 with VariableTree

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

the class IdentifierGlobalScopeNameClashCheck method findVariablesInMethod.

private static void findVariablesInMethod(final String name, final GenerationContext<Void> context) {
    MethodTree enclosingMethod = getEnclosingMethod(context.getCurrentPath());
    if (enclosingMethod == null) {
        // don't see a reason why!?
        return;
    }
    enclosingMethod.accept(new TreeScanner<Void, Void>() {

        private boolean checkStopped;

        @Override
        public Void visitClass(ClassTree arg0, Void arg1) {
            // stop the checks if a new type is encountered
            checkStopped = true;
            return super.visitClass(arg0, arg1);
        }

        @Override
        public Void visitVariable(VariableTree var, Void arg1) {
            if (!checkStopped && var.getName().toString().equals(name)) {
                context.addError(var, "A variable with the same name as your global variable is already defined in this method's scope. " + "Please rename either the local variable/parameter or the global variable.");
            }
            return super.visitVariable(var, arg1);
        }
    }, null);
}
Also used : MethodTree(com.sun.source.tree.MethodTree) ClassTree(com.sun.source.tree.ClassTree) VariableTree(com.sun.source.tree.VariableTree)

Example 69 with VariableTree

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

the class MultipleVariableWriter method visit.

public JS visit(WriterVisitor<JS> visitor, List<VariableTree> trees, GenerationContext<JS> context, boolean isStatement) {
    if (trees.isEmpty()) {
        return context.js().emptyStatement();
    }
    List<NameValue<JS>> vars = new ArrayList<NameValue<JS>>();
    for (VariableTree tree : trees) {
        JS init = null;
        if (tree.getInitializer() != null) {
            init = visitor.scan(tree.getInitializer(), context);
        }
        vars.add(NameValue.of(tree.getName(), init));
    }
    return context.withPosition(trees.get(0), context.js().variableDeclaration(isStatement, vars));
}
Also used : NameValue(org.stjs.generator.javascript.NameValue) ArrayList(java.util.ArrayList) VariableTree(com.sun.source.tree.VariableTree)

Example 70 with VariableTree

use of com.sun.source.tree.VariableTree in project error-prone by google.

the class StreamResourceLeak method addFix.

@Override
protected void addFix(Description.Builder description, ExpressionTree tree, VisitorState state) {
    TreePath parentPath = state.getPath().getParentPath();
    Tree parent = parentPath.getLeaf();
    SuggestedFix.Builder fix = SuggestedFix.builder();
    String streamType = SuggestedFixes.prettyType(state, fix, ASTHelpers.getReturnType(tree));
    if (parent instanceof MemberSelectTree) {
        StatementTree statement = state.findEnclosing(StatementTree.class);
        if (statement instanceof VariableTree) {
            // Variables need to be declared outside the try-with-resources:
            // e.g. `int count = Files.lines(p).count();`
            // -> `int count; try (Stream<String> stream = Files.lines(p)) { count = stream.count(); }`
            VariableTree var = (VariableTree) statement;
            int pos = ((JCTree) var).getStartPosition();
            int initPos = ((JCTree) var.getInitializer()).getStartPosition();
            int eqPos = pos + state.getSourceForNode(var).substring(0, initPos - pos).lastIndexOf('=');
            fix.replace(eqPos, initPos, String.format(";\ntry (%s stream = %s) {\n%s =", streamType, state.getSourceForNode(tree), var.getName().toString()));
        } else {
            // the non-variable case, e.g. `return Files.lines(p).count()`
            // -> try (Stream<Stream> stream = Files.lines(p)) { return stream.count(); }`
            fix.prefixWith(statement, String.format("try (%s stream = %s) {\n", streamType, state.getSourceForNode(tree)));
        }
        fix.replace(tree, "stream");
        fix.postfixWith(statement, "}");
        description.addFix(fix.build());
    } else if (parent instanceof VariableTree) {
        // If the stream is assigned to a variable, wrap the variable in a try-with-resources
        // that includes all statements in the same block that reference the variable.
        Tree grandParent = parentPath.getParentPath().getLeaf();
        if (!(grandParent instanceof BlockTree)) {
            return;
        }
        List<? extends StatementTree> statements = ((BlockTree) grandParent).getStatements();
        int idx = statements.indexOf(parent);
        int lastUse = idx;
        for (int i = idx + 1; i < statements.size(); i++) {
            boolean[] found = { false };
            statements.get(i).accept(new TreeScanner<Void, Void>() {

                @Override
                public Void visitIdentifier(IdentifierTree tree, Void unused) {
                    if (Objects.equals(ASTHelpers.getSymbol(tree), ASTHelpers.getSymbol(parent))) {
                        found[0] = true;
                    }
                    return null;
                }
            }, null);
            if (found[0]) {
                lastUse = i;
            }
        }
        fix.prefixWith(parent, "try (");
        fix.replace(state.getEndPosition(((VariableTree) parent).getInitializer()), state.getEndPosition(parent), ") {");
        fix.postfixWith(statements.get(lastUse), "}");
        description.addFix(fix.build());
    } else if (parent instanceof EnhancedForLoopTree) {
        // If the stream is used in a loop (e.g. directory streams), wrap the loop in
        // try-with-resources.
        fix.prefixWith(parent, String.format("try (%s stream = %s) {\n", streamType, state.getSourceForNode(tree)));
        fix.replace(tree, "stream");
        fix.postfixWith(parent, "}");
        description.addFix(fix.build());
    } else if (parent instanceof MethodInvocationTree) {
        // If the stream is used in a method that is called in an expression statement, wrap it in
        // try-with-resources.
        Tree grandParent = parentPath.getParentPath().getLeaf();
        if (!(grandParent instanceof ExpressionStatementTree)) {
            return;
        }
        fix.prefixWith(parent, String.format("try (%s stream = %s) {\n", streamType, state.getSourceForNode(tree)));
        fix.replace(tree, "stream");
        fix.postfixWith(grandParent, "}");
        description.addFix(fix.build());
    }
}
Also used : MemberSelectTree(com.sun.source.tree.MemberSelectTree) VariableTree(com.sun.source.tree.VariableTree) JCTree(com.sun.tools.javac.tree.JCTree) IdentifierTree(com.sun.source.tree.IdentifierTree) ExpressionStatementTree(com.sun.source.tree.ExpressionStatementTree) ExpressionStatementTree(com.sun.source.tree.ExpressionStatementTree) StatementTree(com.sun.source.tree.StatementTree) TreePath(com.sun.source.util.TreePath) SuggestedFix(com.google.errorprone.fixes.SuggestedFix) TreeScanner(com.sun.source.util.TreeScanner) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) VariableTree(com.sun.source.tree.VariableTree) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) IdentifierTree(com.sun.source.tree.IdentifierTree) Tree(com.sun.source.tree.Tree) ExpressionTree(com.sun.source.tree.ExpressionTree) MemberSelectTree(com.sun.source.tree.MemberSelectTree) JCTree(com.sun.tools.javac.tree.JCTree) ExpressionStatementTree(com.sun.source.tree.ExpressionStatementTree) BlockTree(com.sun.source.tree.BlockTree) StatementTree(com.sun.source.tree.StatementTree) EnhancedForLoopTree(com.sun.source.tree.EnhancedForLoopTree) BlockTree(com.sun.source.tree.BlockTree) List(java.util.List) EnhancedForLoopTree(com.sun.source.tree.EnhancedForLoopTree)

Aggregations

VariableTree (com.sun.source.tree.VariableTree)86 Tree (com.sun.source.tree.Tree)43 ClassTree (com.sun.source.tree.ClassTree)37 MethodTree (com.sun.source.tree.MethodTree)37 ExpressionTree (com.sun.source.tree.ExpressionTree)34 MethodInvocationTree (com.sun.source.tree.MethodInvocationTree)25 NewClassTree (com.sun.source.tree.NewClassTree)23 TreePath (com.sun.source.util.TreePath)23 IdentifierTree (com.sun.source.tree.IdentifierTree)22 JCTree (com.sun.tools.javac.tree.JCTree)21 MemberSelectTree (com.sun.source.tree.MemberSelectTree)19 AssignmentTree (com.sun.source.tree.AssignmentTree)17 ArrayList (java.util.ArrayList)17 BlockTree (com.sun.source.tree.BlockTree)16 CompilationUnitTree (com.sun.source.tree.CompilationUnitTree)13 Type (com.sun.tools.javac.code.Type)13 LambdaExpressionTree (com.sun.source.tree.LambdaExpressionTree)12 ReturnTree (com.sun.source.tree.ReturnTree)12 StatementTree (com.sun.source.tree.StatementTree)12 VarSymbol (com.sun.tools.javac.code.Symbol.VarSymbol)12