Search in sources :

Example 36 with ExpressionTree

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

the class UTemplater method visitMethodInvocation.

@Override
public UExpression visitMethodInvocation(MethodInvocationTree tree, Void v) {
    if (anyMatch(ANY_OF, tree.getMethodSelect(), new Unifier(context))) {
        return UAnyOf.create(templateExpressions(tree.getArguments()));
    } else if (anyMatch(IS_INSTANCE, tree.getMethodSelect(), new Unifier(context))) {
        return UInstanceOf.create(template(Iterables.getOnlyElement(tree.getArguments())), templateType(getSingleExplicitTypeArgument(tree)));
    } else if (anyMatch(CLAZZ, tree.getMethodSelect(), new Unifier(context))) {
        Tree typeArg = getSingleExplicitTypeArgument(tree);
        return UMemberSelect.create(templateType(typeArg), "class", UClassType.create("java.lang.Class", template(((JCTree) typeArg).type)));
    } else if (anyMatch(NEW_ARRAY, tree.getMethodSelect(), new Unifier(context))) {
        Tree typeArg = getSingleExplicitTypeArgument(tree);
        ExpressionTree lengthArg = Iterables.getOnlyElement(tree.getArguments());
        return UNewArray.create(templateType(typeArg), ImmutableList.of(template(lengthArg)), null);
    } else if (anyMatch(ENUM_VALUE_OF, tree.getMethodSelect(), new Unifier(context))) {
        Tree typeArg = getSingleExplicitTypeArgument(tree);
        ExpressionTree strArg = Iterables.getOnlyElement(tree.getArguments());
        return UMethodInvocation.create(UMemberSelect.create(templateType(typeArg), "valueOf", UMethodType.create(template(((JCTree) typeArg).type), UClassType.create("java.lang.String"))), template(strArg));
    } else if (anyMatch(AS_VARARGS, tree.getMethodSelect(), new Unifier(context))) {
        ExpressionTree arg = Iterables.getOnlyElement(tree.getArguments());
        checkArgument(ASTHelpers.hasAnnotation(arg, Repeated.class, new VisitorState(context)));
        return template(arg);
    }
    Map<MethodSymbol, PlaceholderMethod> placeholderMethods = context.get(RefasterRuleBuilderScanner.PLACEHOLDER_METHODS_KEY);
    if (placeholderMethods != null && placeholderMethods.containsKey(ASTHelpers.getSymbol(tree))) {
        return UPlaceholderExpression.create(placeholderMethods.get(ASTHelpers.getSymbol(tree)), templateExpressions(tree.getArguments()));
    } else {
        return UMethodInvocation.create(template(tree.getMethodSelect()), templateExpressions(tree.getArguments()));
    }
}
Also used : MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) VisitorState(com.google.errorprone.VisitorState) CompoundAssignmentTree(com.sun.source.tree.CompoundAssignmentTree) LiteralTree(com.sun.source.tree.LiteralTree) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) AssignmentTree(com.sun.source.tree.AssignmentTree) TypeCastTree(com.sun.source.tree.TypeCastTree) LambdaExpressionTree(com.sun.source.tree.LambdaExpressionTree) ForLoopTree(com.sun.source.tree.ForLoopTree) InstanceOfTree(com.sun.source.tree.InstanceOfTree) ParenthesizedTree(com.sun.source.tree.ParenthesizedTree) ConditionalExpressionTree(com.sun.source.tree.ConditionalExpressionTree) MemberSelectTree(com.sun.source.tree.MemberSelectTree) ExpressionStatementTree(com.sun.source.tree.ExpressionStatementTree) ThrowTree(com.sun.source.tree.ThrowTree) BlockTree(com.sun.source.tree.BlockTree) EnhancedForLoopTree(com.sun.source.tree.EnhancedForLoopTree) ReturnTree(com.sun.source.tree.ReturnTree) ArrayTypeTree(com.sun.source.tree.ArrayTypeTree) LabeledStatementTree(com.sun.source.tree.LabeledStatementTree) UnaryTree(com.sun.source.tree.UnaryTree) VariableTree(com.sun.source.tree.VariableTree) TypeParameterTree(com.sun.source.tree.TypeParameterTree) NewClassTree(com.sun.source.tree.NewClassTree) ParameterizedTypeTree(com.sun.source.tree.ParameterizedTypeTree) BreakTree(com.sun.source.tree.BreakTree) Tree(com.sun.source.tree.Tree) ExpressionTree(com.sun.source.tree.ExpressionTree) IntersectionTypeTree(com.sun.source.tree.IntersectionTypeTree) WildcardTree(com.sun.source.tree.WildcardTree) UnionTypeTree(com.sun.source.tree.UnionTypeTree) ArrayAccessTree(com.sun.source.tree.ArrayAccessTree) AnnotatedTypeTree(com.sun.source.tree.AnnotatedTypeTree) IdentifierTree(com.sun.source.tree.IdentifierTree) CatchTree(com.sun.source.tree.CatchTree) NewArrayTree(com.sun.source.tree.NewArrayTree) JCPrimitiveTypeTree(com.sun.tools.javac.tree.JCTree.JCPrimitiveTypeTree) ContinueTree(com.sun.source.tree.ContinueTree) PrimitiveTypeTree(com.sun.source.tree.PrimitiveTypeTree) SynchronizedTree(com.sun.source.tree.SynchronizedTree) AssertTree(com.sun.source.tree.AssertTree) StatementTree(com.sun.source.tree.StatementTree) ModifiersTree(com.sun.source.tree.ModifiersTree) WhileLoopTree(com.sun.source.tree.WhileLoopTree) AnnotationTree(com.sun.source.tree.AnnotationTree) MethodTree(com.sun.source.tree.MethodTree) BinaryTree(com.sun.source.tree.BinaryTree) EmptyStatementTree(com.sun.source.tree.EmptyStatementTree) ClassTree(com.sun.source.tree.ClassTree) IfTree(com.sun.source.tree.IfTree) MemberReferenceTree(com.sun.source.tree.MemberReferenceTree) JCTree(com.sun.tools.javac.tree.JCTree) DoWhileLoopTree(com.sun.source.tree.DoWhileLoopTree) TryTree(com.sun.source.tree.TryTree) LambdaExpressionTree(com.sun.source.tree.LambdaExpressionTree) ConditionalExpressionTree(com.sun.source.tree.ConditionalExpressionTree) ExpressionTree(com.sun.source.tree.ExpressionTree) JCTree(com.sun.tools.javac.tree.JCTree)

Example 37 with ExpressionTree

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

the class UTemplater method createTemplate.

/**
   * Returns a template based on a method. One-line methods starting with a {@code return} statement
   * are guessed to be expression templates, and all other methods are guessed to be block
   * templates.
   */
public static Template<?> createTemplate(Context context, MethodTree decl) {
    MethodSymbol declSym = ASTHelpers.getSymbol(decl);
    ImmutableClassToInstanceMap<Annotation> annotations = UTemplater.annotationMap(declSym);
    ImmutableMap<String, VarSymbol> freeExpressionVars = freeExpressionVariables(decl);
    Context subContext = new SubContext(context);
    final UTemplater templater = new UTemplater(freeExpressionVars, subContext);
    ImmutableMap<String, UType> expressionVarTypes = ImmutableMap.copyOf(Maps.transformValues(freeExpressionVars, new Function<VarSymbol, UType>() {

        @Override
        public UType apply(VarSymbol sym) {
            return templater.template(sym.type);
        }
    }));
    UType genericType = templater.template(declSym.type);
    List<UTypeVar> typeParameters;
    UMethodType methodType;
    if (genericType instanceof UForAll) {
        UForAll forAllType = (UForAll) genericType;
        typeParameters = forAllType.getTypeVars();
        methodType = (UMethodType) forAllType.getQuantifiedType();
    } else if (genericType instanceof UMethodType) {
        typeParameters = ImmutableList.of();
        methodType = (UMethodType) genericType;
    } else {
        throw new IllegalArgumentException("Expected genericType to be either a ForAll or a UMethodType, but was " + genericType);
    }
    List<? extends StatementTree> bodyStatements = decl.getBody().getStatements();
    if (bodyStatements.size() == 1 && Iterables.getOnlyElement(bodyStatements).getKind() == Kind.RETURN && context.get(REQUIRE_BLOCK_KEY) == null) {
        ExpressionTree expression = ((ReturnTree) Iterables.getOnlyElement(bodyStatements)).getExpression();
        return ExpressionTemplate.create(annotations, typeParameters, expressionVarTypes, templater.template(expression), methodType.getReturnType());
    } else {
        List<UStatement> templateStatements = new ArrayList<>();
        for (StatementTree statement : bodyStatements) {
            templateStatements.add(templater.template(statement));
        }
        return BlockTemplate.create(annotations, typeParameters, expressionVarTypes, templateStatements);
    }
}
Also used : Context(com.sun.tools.javac.util.Context) SubContext(com.google.errorprone.SubContext) ArrayList(java.util.ArrayList) VarSymbol(com.sun.tools.javac.code.Symbol.VarSymbol) ReturnTree(com.sun.source.tree.ReturnTree) Annotation(java.lang.annotation.Annotation) ExpressionStatementTree(com.sun.source.tree.ExpressionStatementTree) LabeledStatementTree(com.sun.source.tree.LabeledStatementTree) StatementTree(com.sun.source.tree.StatementTree) EmptyStatementTree(com.sun.source.tree.EmptyStatementTree) Function(com.google.common.base.Function) MethodSymbol(com.sun.tools.javac.code.Symbol.MethodSymbol) SubContext(com.google.errorprone.SubContext) LambdaExpressionTree(com.sun.source.tree.LambdaExpressionTree) ConditionalExpressionTree(com.sun.source.tree.ConditionalExpressionTree) ExpressionTree(com.sun.source.tree.ExpressionTree)

Example 38 with ExpressionTree

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

the class CompileTimeConstantExpressionMatcherTest method assertCompilerMatchesOnAssignment.

// Helper methods.
private void assertCompilerMatchesOnAssignment(final Map<String, Boolean> expectedMatches, String... lines) {
    final Matcher<ExpressionTree> matcher = new CompileTimeConstantExpressionMatcher();
    final Scanner scanner = new Scanner() {

        @Override
        public Void visitAssignment(AssignmentTree t, VisitorState state) {
            ExpressionTree lhs = t.getVariable();
            if (expectedMatches.containsKey(lhs.toString())) {
                boolean matches = matcher.matches(t.getExpression(), state);
                if (expectedMatches.get(lhs.toString())) {
                    assertTrue("Matcher should match expression" + t.getExpression(), matches);
                } else {
                    assertFalse("Matcher should not match expression" + t.getExpression(), matches);
                }
            }
            return super.visitAssignment(t, state);
        }
    };
    CompilationTestHelper.newInstance(ScannerSupplier.fromScanner(scanner), getClass()).expectResult(Result.OK).addSourceLines("test/CompileTimeConstantExpressionMatcherTestCase.java", lines).doTest();
}
Also used : Scanner(com.google.errorprone.scanner.Scanner) VisitorState(com.google.errorprone.VisitorState) ExpressionTree(com.sun.source.tree.ExpressionTree) AssignmentTree(com.sun.source.tree.AssignmentTree)

Example 39 with ExpressionTree

use of com.sun.source.tree.ExpressionTree in project groovy-cps by cloudbees.

the class Translator method translateMethod.

/**
     * @param e
     *      Method in {@code fqcn} to translate.
     */
private void translateMethod(final CompilationUnitTree cut, ExecutableElement e, JDefinedClass $output, String fqcn, String overloadResolved) {
    String methodName = n(e);
    boolean isPublic = e.getModifiers().contains(Modifier.PUBLIC);
    JMethod delegating = $output.method(isPublic ? JMod.PUBLIC | JMod.STATIC : JMod.STATIC, (JType) null, methodName);
    JMethod m = $output.method(JMod.PRIVATE | JMod.STATIC, (JType) null, overloadResolved);
    Map<String, JTypeVar> typeVars = new HashMap<>();
    e.getTypeParameters().forEach(p -> {
        String name = n(p);
        JTypeVar typeVar = delegating.generify(name);
        JTypeVar typeVar2 = m.generify(name);
        p.getBounds().forEach(b -> {
            JClass binding = (JClass) t(b, typeVars);
            typeVar.bound(binding);
            typeVar2.bound(binding);
        });
        typeVars.put(name, typeVar);
    });
    JType type = t(e.getReturnType(), typeVars);
    delegating.type(type);
    m.type(type);
    List<JVar> delegatingParams = new ArrayList<>();
    List<JVar> params = new ArrayList<>();
    e.getParameters().forEach(p -> {
        JType paramType = t(p.asType(), typeVars);
        delegatingParams.add(e.isVarArgs() && p == e.getParameters().get(e.getParameters().size() - 1) ? delegating.varParam(paramType.elementType(), n(p)) : delegating.param(paramType, n(p)));
        params.add(m.param(paramType, n(p)));
    });
    e.getThrownTypes().forEach(ex -> {
        delegating._throws((JClass) t(ex));
        m._throws((JClass) t(ex));
    });
    boolean returnsVoid = e.getReturnType().getKind() == TypeKind.VOID;
    if (isPublic) {
        // preamble
        /*
                If the call to this method happen outside CPS code, execute normally via DefaultGroovyMethods
             */
        delegating.body()._if(JOp.cand(JOp.not($Caller.staticInvoke("isAsynchronous").tap(inv -> {
            inv.arg(delegatingParams.get(0));
            inv.arg(methodName);
            for (int i = 1; i < delegatingParams.size(); i++) inv.arg(delegatingParams.get(i));
        })), JOp.not($Caller.staticInvoke("isAsynchronous").arg($output.dotclass()).arg(methodName).args(params))))._then().tap(blk -> {
            JClass $WhateverGroovyMethods = codeModel.ref(fqcn);
            JInvocation forward = $WhateverGroovyMethods.staticInvoke(methodName).args(delegatingParams);
            if (returnsVoid) {
                blk.add(forward);
                blk._return();
            } else {
                blk._return(forward);
            }
        });
    }
    JInvocation delegateCall = $output.staticInvoke(overloadResolved);
    if (returnsVoid) {
        delegating.body().add(delegateCall);
    } else {
        delegating.body()._return(delegateCall);
    }
    delegatingParams.forEach(p -> delegateCall.arg(p));
    JVar $b = m.body().decl($Builder, "b", JExpr._new($Builder).arg(JExpr.invoke("loc").arg(methodName)));
    JInvocation f = JExpr._new($CpsFunction);
    // parameter names
    f.arg(codeModel.ref(Arrays.class).staticInvoke("asList").tap(inv -> {
        e.getParameters().forEach(p -> inv.arg(n(p)));
    }));
    // translate the method body into an expression that invokes Builder
    f.arg(trees.getTree(e).getBody().accept(new SimpleTreeVisitor<JExpression, Void>() {

        private JExpression visit(Tree t) {
            if (t == null)
                return JExpr._null();
            return visit(t, null);
        }

        /**
             * Maps a symbol to its source location.
             */
        private JExpression loc(Tree t) {
            long pos = trees.getSourcePositions().getStartPosition(cut, t);
            return JExpr.lit((int) cut.getLineMap().getLineNumber(pos));
        }

        @Override
        public JExpression visitWhileLoop(WhileLoopTree wt, Void __) {
            return $b.invoke("while_").arg(// TODO: label
            JExpr._null()).arg(visit(wt.getCondition())).arg(visit(wt.getStatement()));
        }

        @Override
        public JExpression visitMethodInvocation(MethodInvocationTree mt, Void __) {
            ExpressionTree ms = mt.getMethodSelect();
            JInvocation inv;
            if (ms instanceof MemberSelectTree) {
                MemberSelectTree mst = (MemberSelectTree) ms;
                inv = $b.invoke("functionCall").arg(loc(mt)).arg(visit(mst.getExpression())).arg(n(mst.getIdentifier()));
            } else if (ms instanceof JCIdent) {
                // invocation without object selection, like  foo(bar,zot)
                JCIdent it = (JCIdent) ms;
                if (!it.sym.owner.toString().equals(fqcn)) {
                    // static import
                    inv = $b.invoke("functionCall").arg(loc(mt)).arg($b.invoke("constant").arg(t(it.sym.owner.type).dotclass())).arg(n(it));
                } else {
                    // invocation on this class
                    String overloadResolved = mangledName((Symbol.MethodSymbol) it.sym);
                    Optional<? extends Element> callSite = elements.getTypeElement(fqcn).getEnclosedElements().stream().filter(e -> e.getKind() == ElementKind.METHOD && mangledName((ExecutableElement) e).equals(overloadResolved)).findAny();
                    if (callSite.isPresent()) {
                        ExecutableElement e = (ExecutableElement) callSite.get();
                        if (e.getModifiers().contains(Modifier.PUBLIC) && !e.isVarArgs() && !e.getParameters().stream().anyMatch(p -> types.isAssignable(p.asType(), closureType))) {
                            // Delegate to the standard version.
                            inv = $b.invoke("staticCall").arg(loc(mt)).arg(t(it.sym.owner.type).dotclass()).arg(n(e));
                        } else if (overloadsResolved.containsKey(overloadResolved)) {
                            // Private, so delegate to our mangled version.
                            inv = $b.invoke("staticCall").arg(loc(mt)).arg($output.dotclass()).arg(overloadResolved);
                        } else {
                            throw new IllegalStateException("Not yet translating a " + e.getModifiers() + " method; translatable.txt might need to include: " + fqcn + "." + e);
                        }
                    } else {
                        throw new IllegalStateException("Could not find self-call site " + overloadResolved + " for " + mt);
                    }
                }
            } else {
                // TODO: figure out what can come here
                throw new UnsupportedOperationException(ms.toString());
            }
            mt.getArguments().forEach(a -> inv.arg(visit(a)));
            return inv;
        }

        @Override
        public JExpression visitVariable(VariableTree vt, Void __) {
            return $b.invoke("declareVariable").arg(loc(vt)).arg(erasure(vt).dotclass()).arg(n(vt)).arg(visit(vt.getInitializer()));
        }

        @Override
        public JExpression visitIdentifier(IdentifierTree it, Void __) {
            JCIdent idt = (JCIdent) it;
            return idt.sym.accept(new DefaultSymbolVisitor<JExpression, Void>() {

                @Override
                public JExpression visitClassSymbol(ClassSymbol cs, Void __) {
                    return $b.invoke("constant").arg(t(cs.asType()).dotclass());
                }

                @Override
                public JExpression visitVarSymbol(VarSymbol s, Void __) {
                    return $b.invoke("localVariable").arg(n(s.name));
                }

                @Override
                public JExpression visitSymbol(Symbol s, Void __) {
                    throw new UnsupportedOperationException(s.toString());
                }
            }, __);
        }

        @Override
        public JExpression visitBlock(BlockTree bt, Void __) {
            JInvocation inv = $b.invoke("block");
            bt.getStatements().forEach(s -> inv.arg(visit(s)));
            return inv;
        }

        @Override
        public JExpression visitReturn(ReturnTree rt, Void __) {
            return $b.invoke("return_").arg(visit(rt.getExpression()));
        }

        /**
             * When used outside {@link MethodInvocationTree}, this is property access.
             */
        @Override
        public JExpression visitMemberSelect(MemberSelectTree mt, Void __) {
            return $b.invoke("property").arg(loc(mt)).arg(visit(mt.getExpression())).arg(n(mt.getIdentifier()));
        }

        @Override
        public JExpression visitTypeCast(TypeCastTree tt, Void __) {
            return $b.invoke("cast").arg(loc(tt)).arg(visit(tt.getExpression())).arg(erasure(tt.getType()).dotclass()).arg(JExpr.lit(false));
        }

        @Override
        public JExpression visitIf(IfTree it, Void __) {
            JInvocation inv = $b.invoke("if_").arg(visit(it.getCondition())).arg(visit(it.getThenStatement()));
            if (it.getElseStatement() != null)
                inv.arg(visit(it.getElseStatement()));
            return inv;
        }

        @Override
        public JExpression visitNewClass(NewClassTree nt, Void __) {
            // TODO: outer class
            if (nt.getEnclosingExpression() != null)
                throw new UnsupportedOperationException();
            return $b.invoke("new_").tap(inv -> {
                inv.arg(loc(nt));
                inv.arg(t(((JCTree) nt).type).dotclass());
                nt.getArguments().forEach(et -> inv.arg(visit(et)));
            });
        }

        @Override
        public JExpression visitExpressionStatement(ExpressionStatementTree et, Void __) {
            return visit(et.getExpression());
        }

        @Override
        public JExpression visitLiteral(LiteralTree lt, Void __) {
            return $b.invoke("constant").arg(JExpr.literal(lt.getValue()));
        }

        @Override
        public JExpression visitParenthesized(ParenthesizedTree pt, Void __) {
            return visit(pt.getExpression());
        }

        @Override
        public JExpression visitBinary(BinaryTree bt, Void __) {
            return $b.invoke(opName(bt.getKind())).arg(loc(bt)).arg(visit(bt.getLeftOperand())).arg(visit(bt.getRightOperand()));
        }

        @Override
        public JExpression visitUnary(UnaryTree ut, Void __) {
            return $b.invoke(opName(ut.getKind())).arg(loc(ut)).arg(visit(ut.getExpression()));
        }

        @Override
        public JExpression visitCompoundAssignment(CompoundAssignmentTree ct, Void __) {
            return $b.invoke(opName(ct.getKind())).arg(loc(ct)).arg(visit(ct.getVariable())).arg(visit(ct.getExpression()));
        }

        private String opName(Kind kind) {
            switch(kind) {
                case EQUAL_TO:
                    return "compareEqual";
                case NOT_EQUAL_TO:
                    return "compareNotEqual";
                case LESS_THAN_EQUAL:
                    return "lessThanEqual";
                case LESS_THAN:
                    return "lessThan";
                case GREATER_THAN_EQUAL:
                    return "greaterThanEqual";
                case GREATER_THAN:
                    return "greaterThan";
                case PREFIX_INCREMENT:
                    return "prefixInc";
                case POSTFIX_INCREMENT:
                    return "postfixInc";
                case POSTFIX_DECREMENT:
                    return "postfixDec";
                case LOGICAL_COMPLEMENT:
                    return "not";
                case CONDITIONAL_OR:
                    return "logicalOr";
                case CONDITIONAL_AND:
                    return "logicalAnd";
                case PLUS:
                    return "plus";
                case PLUS_ASSIGNMENT:
                    return "plusEqual";
                case MINUS:
                    return "minus";
                case MINUS_ASSIGNMENT:
                    return "minusEqual";
            }
            throw new UnsupportedOperationException(kind.toString());
        }

        @Override
        public JExpression visitAssignment(AssignmentTree at, Void __) {
            return $b.invoke("assign").arg(loc(at)).arg(visit(at.getVariable())).arg(visit(at.getExpression()));
        }

        @Override
        public JExpression visitNewArray(NewArrayTree nt, Void __) {
            if (nt.getInitializers() != null) {
                return $b.invoke("newArrayFromInitializers").tap(inv -> {
                    nt.getInitializers().forEach(d -> inv.arg(visit(d)));
                });
            } else {
                return $b.invoke("newArray").tap(inv -> {
                    inv.arg(loc(nt));
                    inv.arg(t(nt.getType()).dotclass());
                    nt.getDimensions().forEach(d -> inv.arg(visit(d)));
                });
            }
        }

        @Override
        public JExpression visitForLoop(ForLoopTree ft, Void __) {
            return $b.invoke("forLoop").arg(JExpr._null()).arg($b.invoke("sequence").tap(inv -> ft.getInitializer().forEach(i -> inv.arg(visit(i))))).arg(visit(ft.getCondition())).arg($b.invoke("sequence").tap(inv -> ft.getUpdate().forEach(i -> inv.arg(visit(i))))).arg(visit(ft.getStatement()));
        }

        @Override
        public JExpression visitEnhancedForLoop(EnhancedForLoopTree et, Void __) {
            return $b.invoke("forInLoop").arg(loc(et)).arg(JExpr._null()).arg(erasure(et.getVariable()).dotclass()).arg(n(et.getVariable())).arg(visit(et.getExpression())).arg(visit(et.getStatement()));
        }

        @Override
        public JExpression visitArrayAccess(ArrayAccessTree at, Void __) {
            return $b.invoke("array").arg(loc(at)).arg(visit(at.getExpression())).arg(visit(at.getIndex()));
        }

        @Override
        public JExpression visitBreak(BreakTree node, Void __) {
            if (node.getLabel() != null)
                throw new UnsupportedOperationException();
            return $b.invoke("break_").arg(JExpr._null());
        }

        @Override
        public JExpression visitContinue(ContinueTree node, Void aVoid) {
            if (node.getLabel() != null)
                throw new UnsupportedOperationException();
            return $b.invoke("continue_").arg(JExpr._null());
        }

        @Override
        public JExpression visitInstanceOf(InstanceOfTree it, Void __) {
            return $b.invoke("instanceOf").arg(loc(it)).arg(visit(it.getExpression())).arg($b.invoke("constant").arg(t(it.getType()).dotclass()));
        }

        @Override
        public JExpression visitThrow(ThrowTree tt, Void __) {
            return $b.invoke("throw_").arg(loc(tt)).arg(visit(tt.getExpression()));
        }

        @Override
        public JExpression visitDoWhileLoop(DoWhileLoopTree dt, Void __) {
            return $b.invoke("doWhile").arg(JExpr._null()).arg(visit(dt.getStatement())).arg(visit(dt.getCondition()));
        }

        @Override
        public JExpression visitConditionalExpression(ConditionalExpressionTree ct, Void __) {
            return $b.invoke("ternaryOp").arg(visit(ct.getCondition())).arg(visit(ct.getTrueExpression())).arg(visit(ct.getFalseExpression()));
        }

        @Override
        public JExpression visitTry(TryTree tt, Void __) {
            return $b.invoke("tryCatch").arg(visit(tt.getBlock())).arg(visit(tt.getFinallyBlock())).tap(inv -> tt.getCatches().forEach(ct -> JExpr._new($CatchExpression).arg(t(ct.getParameter()).dotclass()).arg(n(ct.getParameter())).arg(visit(ct.getBlock()))));
        }

        @Override
        protected JExpression defaultAction(Tree node, Void aVoid) {
            throw new UnsupportedOperationException(node.toString());
        }
    }, null));
    JVar $f = m.body().decl($CpsFunction, "f", f);
    m.body()._throw(JExpr._new($CpsCallableInvocation).arg($f).arg(JExpr._null()).args(params));
}
Also used : CompoundAssignmentTree(com.sun.source.tree.CompoundAssignmentTree) Arrays(java.util.Arrays) LiteralTree(com.sun.source.tree.LiteralTree) JCodeModel(com.sun.codemodel.JCodeModel) Modifier(javax.lang.model.element.Modifier) Closure(groovy.lang.Closure) TypeElement(javax.lang.model.element.TypeElement) ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) Elements(javax.lang.model.util.Elements) JExpr(com.sun.codemodel.JExpr) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) AssignmentTree(com.sun.source.tree.AssignmentTree) TypeCastTree(com.sun.source.tree.TypeCastTree) Map(java.util.Map) ForLoopTree(com.sun.source.tree.ForLoopTree) Trees(com.sun.source.util.Trees) InstanceOfTree(com.sun.source.tree.InstanceOfTree) ParenthesizedTree(com.sun.source.tree.ParenthesizedTree) ArrayType(javax.lang.model.type.ArrayType) ConditionalExpressionTree(com.sun.source.tree.ConditionalExpressionTree) DefaultSymbolVisitor(com.sun.tools.javac.code.Types.DefaultSymbolVisitor) Symbol(com.sun.tools.javac.code.Symbol) Set(java.util.Set) Element(javax.lang.model.element.Element) MemberSelectTree(com.sun.source.tree.MemberSelectTree) ExpressionStatementTree(com.sun.source.tree.ExpressionStatementTree) StandardCharsets(java.nio.charset.StandardCharsets) ThrowTree(com.sun.source.tree.ThrowTree) BlockTree(com.sun.source.tree.BlockTree) JCIdent(com.sun.tools.javac.tree.JCTree.JCIdent) EnhancedForLoopTree(com.sun.source.tree.EnhancedForLoopTree) ReturnTree(com.sun.source.tree.ReturnTree) ArrayTypeTree(com.sun.source.tree.ArrayTypeTree) UnaryTree(com.sun.source.tree.UnaryTree) JInvocation(com.sun.codemodel.JInvocation) VariableTree(com.sun.source.tree.VariableTree) TreeSet(java.util.TreeSet) ArrayList(java.util.ArrayList) Kind(com.sun.source.tree.Tree.Kind) NewClassTree(com.sun.source.tree.NewClassTree) ParameterizedTypeTree(com.sun.source.tree.ParameterizedTypeTree) DeclaredType(javax.lang.model.type.DeclaredType) BreakTree(com.sun.source.tree.BreakTree) Tree(com.sun.source.tree.Tree) VarSymbol(com.sun.tools.javac.code.Symbol.VarSymbol) JClassAlreadyExistsException(com.sun.codemodel.JClassAlreadyExistsException) Resources(com.google.common.io.Resources) JDefinedClass(com.sun.codemodel.JDefinedClass) ExpressionTree(com.sun.source.tree.ExpressionTree) IOException(java.io.IOException) TreeMap(java.util.TreeMap) WildcardTree(com.sun.source.tree.WildcardTree) ArrayAccessTree(com.sun.source.tree.ArrayAccessTree) JVar(com.sun.codemodel.JVar) SimpleTypeVisitor6(javax.lang.model.util.SimpleTypeVisitor6) Date(java.util.Date) JMethod(com.sun.codemodel.JMethod) JCFieldAccess(com.sun.tools.javac.tree.JCTree.JCFieldAccess) JExpression(com.sun.codemodel.JExpression) Generated(javax.annotation.Generated) CompilationTask(javax.tools.JavaCompiler.CompilationTask) IdentifierTree(com.sun.source.tree.IdentifierTree) NewArrayTree(com.sun.source.tree.NewArrayTree) WildcardType(javax.lang.model.type.WildcardType) JMod(com.sun.codemodel.JMod) JOp(com.sun.codemodel.JOp) JavacTask(com.sun.source.util.JavacTask) ContinueTree(com.sun.source.tree.ContinueTree) SimpleTreeVisitor(com.sun.source.util.SimpleTreeVisitor) Types(javax.lang.model.util.Types) CompilationUnitTree(com.sun.source.tree.CompilationUnitTree) TypeKind(javax.lang.model.type.TypeKind) TypeVariableSymbol(com.sun.tools.javac.code.Symbol.TypeVariableSymbol) List(java.util.List) ElementScanner7(javax.lang.model.util.ElementScanner7) JType(com.sun.codemodel.JType) PrimitiveTypeTree(com.sun.source.tree.PrimitiveTypeTree) TypeVariable(javax.lang.model.type.TypeVariable) Optional(java.util.Optional) WhileLoopTree(com.sun.source.tree.WhileLoopTree) BinaryTree(com.sun.source.tree.BinaryTree) HashMap(java.util.HashMap) JTypeVar(com.sun.codemodel.JTypeVar) HashSet(java.util.HashSet) CodeWriter(com.sun.codemodel.CodeWriter) ClassTree(com.sun.source.tree.ClassTree) Name(javax.lang.model.element.Name) IfTree(com.sun.source.tree.IfTree) ElementKind(javax.lang.model.element.ElementKind) NoType(javax.lang.model.type.NoType) ExecutableElement(javax.lang.model.element.ExecutableElement) JCTree(com.sun.tools.javac.tree.JCTree) TypeMirror(javax.lang.model.type.TypeMirror) DoWhileLoopTree(com.sun.source.tree.DoWhileLoopTree) TryTree(com.sun.source.tree.TryTree) PrimitiveType(javax.lang.model.type.PrimitiveType) JClass(com.sun.codemodel.JClass) Collections(java.util.Collections) TypeCastTree(com.sun.source.tree.TypeCastTree) HashMap(java.util.HashMap) MemberSelectTree(com.sun.source.tree.MemberSelectTree) ArrayList(java.util.ArrayList) BinaryTree(com.sun.source.tree.BinaryTree) IdentifierTree(com.sun.source.tree.IdentifierTree) ReturnTree(com.sun.source.tree.ReturnTree) CompoundAssignmentTree(com.sun.source.tree.CompoundAssignmentTree) JTypeVar(com.sun.codemodel.JTypeVar) Kind(com.sun.source.tree.Tree.Kind) TypeKind(javax.lang.model.type.TypeKind) ElementKind(javax.lang.model.element.ElementKind) ThrowTree(com.sun.source.tree.ThrowTree) InstanceOfTree(com.sun.source.tree.InstanceOfTree) CompoundAssignmentTree(com.sun.source.tree.CompoundAssignmentTree) LiteralTree(com.sun.source.tree.LiteralTree) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) AssignmentTree(com.sun.source.tree.AssignmentTree) TypeCastTree(com.sun.source.tree.TypeCastTree) ForLoopTree(com.sun.source.tree.ForLoopTree) InstanceOfTree(com.sun.source.tree.InstanceOfTree) ParenthesizedTree(com.sun.source.tree.ParenthesizedTree) ConditionalExpressionTree(com.sun.source.tree.ConditionalExpressionTree) MemberSelectTree(com.sun.source.tree.MemberSelectTree) ExpressionStatementTree(com.sun.source.tree.ExpressionStatementTree) ThrowTree(com.sun.source.tree.ThrowTree) BlockTree(com.sun.source.tree.BlockTree) EnhancedForLoopTree(com.sun.source.tree.EnhancedForLoopTree) ReturnTree(com.sun.source.tree.ReturnTree) ArrayTypeTree(com.sun.source.tree.ArrayTypeTree) UnaryTree(com.sun.source.tree.UnaryTree) VariableTree(com.sun.source.tree.VariableTree) NewClassTree(com.sun.source.tree.NewClassTree) ParameterizedTypeTree(com.sun.source.tree.ParameterizedTypeTree) BreakTree(com.sun.source.tree.BreakTree) Tree(com.sun.source.tree.Tree) ExpressionTree(com.sun.source.tree.ExpressionTree) WildcardTree(com.sun.source.tree.WildcardTree) ArrayAccessTree(com.sun.source.tree.ArrayAccessTree) IdentifierTree(com.sun.source.tree.IdentifierTree) NewArrayTree(com.sun.source.tree.NewArrayTree) ContinueTree(com.sun.source.tree.ContinueTree) CompilationUnitTree(com.sun.source.tree.CompilationUnitTree) PrimitiveTypeTree(com.sun.source.tree.PrimitiveTypeTree) WhileLoopTree(com.sun.source.tree.WhileLoopTree) BinaryTree(com.sun.source.tree.BinaryTree) ClassTree(com.sun.source.tree.ClassTree) IfTree(com.sun.source.tree.IfTree) JCTree(com.sun.tools.javac.tree.JCTree) DoWhileLoopTree(com.sun.source.tree.DoWhileLoopTree) TryTree(com.sun.source.tree.TryTree) CompoundAssignmentTree(com.sun.source.tree.CompoundAssignmentTree) AssignmentTree(com.sun.source.tree.AssignmentTree) EnhancedForLoopTree(com.sun.source.tree.EnhancedForLoopTree) JType(com.sun.codemodel.JType) DoWhileLoopTree(com.sun.source.tree.DoWhileLoopTree) JCIdent(com.sun.tools.javac.tree.JCTree.JCIdent) Optional(java.util.Optional) VarSymbol(com.sun.tools.javac.code.Symbol.VarSymbol) IfTree(com.sun.source.tree.IfTree) Arrays(java.util.Arrays) TryTree(com.sun.source.tree.TryTree) ArrayAccessTree(com.sun.source.tree.ArrayAccessTree) ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) Symbol(com.sun.tools.javac.code.Symbol) VarSymbol(com.sun.tools.javac.code.Symbol.VarSymbol) TypeVariableSymbol(com.sun.tools.javac.code.Symbol.TypeVariableSymbol) ExecutableElement(javax.lang.model.element.ExecutableElement) TypeElement(javax.lang.model.element.TypeElement) Element(javax.lang.model.element.Element) ExecutableElement(javax.lang.model.element.ExecutableElement) VariableTree(com.sun.source.tree.VariableTree) ParenthesizedTree(com.sun.source.tree.ParenthesizedTree) ConditionalExpressionTree(com.sun.source.tree.ConditionalExpressionTree) NewClassTree(com.sun.source.tree.NewClassTree) BreakTree(com.sun.source.tree.BreakTree) LiteralTree(com.sun.source.tree.LiteralTree) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree) ConditionalExpressionTree(com.sun.source.tree.ConditionalExpressionTree) ExpressionTree(com.sun.source.tree.ExpressionTree) BlockTree(com.sun.source.tree.BlockTree) ContinueTree(com.sun.source.tree.ContinueTree) UnaryTree(com.sun.source.tree.UnaryTree) JVar(com.sun.codemodel.JVar) SimpleTreeVisitor(com.sun.source.util.SimpleTreeVisitor) JClass(com.sun.codemodel.JClass) ForLoopTree(com.sun.source.tree.ForLoopTree) EnhancedForLoopTree(com.sun.source.tree.EnhancedForLoopTree) ExpressionStatementTree(com.sun.source.tree.ExpressionStatementTree) JInvocation(com.sun.codemodel.JInvocation) JExpression(com.sun.codemodel.JExpression) NewArrayTree(com.sun.source.tree.NewArrayTree) WhileLoopTree(com.sun.source.tree.WhileLoopTree) DoWhileLoopTree(com.sun.source.tree.DoWhileLoopTree) JMethod(com.sun.codemodel.JMethod)

Example 40 with ExpressionTree

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

the class DataFlow method expressionDataflow.

/**
   * Run the {@code transfer} dataflow analysis to compute the abstract value of the expression
   * which is the leaf of {@code exprPath}.
   *
   * @return dataflow result for the given expression or {@code null} if the expression is not
   *     part of a method or lambda
   */
@Nullable
public static <A extends AbstractValue<A>, S extends Store<S>, T extends TransferFunction<A, S>> A expressionDataflow(TreePath exprPath, Context context, T transfer) {
    final Tree leaf = exprPath.getLeaf();
    Preconditions.checkArgument(leaf instanceof ExpressionTree, "Leaf of exprPath must be of type ExpressionTree, but was %s", leaf.getClass().getName());
    final ExpressionTree expr = (ExpressionTree) leaf;
    final TreePath enclosingMethodPath = findEnclosingMethodOrLambda(exprPath);
    if (enclosingMethodPath == null) {
        // Currently not supported because it only happens in ~2% of cases.
        return null;
    }
    final Tree method = enclosingMethodPath.getLeaf();
    if (method instanceof MethodTree && ((MethodTree) method).getBody() == null) {
        //   abstract Set<Map.Entry<K, V>> entries();
        return null;
    }
    return methodDataflow(enclosingMethodPath, context, transfer).getAnalysis().getValue(expr);
}
Also used : TreePath(com.sun.source.util.TreePath) MethodTree(com.sun.source.tree.MethodTree) MethodTree(com.sun.source.tree.MethodTree) ExpressionTree(com.sun.source.tree.ExpressionTree) CompilationUnitTree(com.sun.source.tree.CompilationUnitTree) LambdaExpressionTree(com.sun.source.tree.LambdaExpressionTree) Tree(com.sun.source.tree.Tree) ExpressionTree(com.sun.source.tree.ExpressionTree) LambdaExpressionTree(com.sun.source.tree.LambdaExpressionTree) Nullable(javax.annotation.Nullable)

Aggregations

ExpressionTree (com.sun.source.tree.ExpressionTree)78 MethodInvocationTree (com.sun.source.tree.MethodInvocationTree)27 Tree (com.sun.source.tree.Tree)18 Type (com.sun.tools.javac.code.Type)18 SuggestedFix (com.google.errorprone.fixes.SuggestedFix)16 Symbol (com.sun.tools.javac.code.Symbol)14 MethodSymbol (com.sun.tools.javac.code.Symbol.MethodSymbol)14 JCTree (com.sun.tools.javac.tree.JCTree)14 Fix (com.google.errorprone.fixes.Fix)13 VariableTree (com.sun.source.tree.VariableTree)13 JCFieldAccess (com.sun.tools.javac.tree.JCTree.JCFieldAccess)13 IdentifierTree (com.sun.source.tree.IdentifierTree)12 MemberSelectTree (com.sun.source.tree.MemberSelectTree)12 VarSymbol (com.sun.tools.javac.code.Symbol.VarSymbol)11 VisitorState (com.google.errorprone.VisitorState)9 AssignmentTree (com.sun.source.tree.AssignmentTree)9 BinaryTree (com.sun.source.tree.BinaryTree)9 ExpressionStatementTree (com.sun.source.tree.ExpressionStatementTree)8 MethodTree (com.sun.source.tree.MethodTree)8 TreePath (com.sun.source.util.TreePath)8