Search in sources :

Example 11 with JCMethodInvocation

use of com.sun.tools.javac.tree.JCTree.JCMethodInvocation in project error-prone by google.

the class Template method pretty.

protected static Pretty pretty(Context context, final Writer writer) {
    final JCCompilationUnit unit = context.get(JCCompilationUnit.class);
    try {
        final String unitContents = unit.getSourceFile().getCharContent(false).toString();
        return new Pretty(writer, true) {

            {
                // Work-around for b/22196513
                width = 0;
            }

            @Override
            public void visitAnnotation(JCAnnotation anno) {
                if (anno.getArguments().isEmpty()) {
                    try {
                        print("@");
                        printExpr(anno.annotationType);
                    } catch (IOException e) {
                        // the supertype swallows exceptions too
                        throw new RuntimeException(e);
                    }
                } else {
                    super.visitAnnotation(anno);
                }
            }

            @Override
            public void printExpr(JCTree tree, int prec) throws IOException {
                EndPosTable endPositions = unit.endPositions;
                /*
           * Modifiers, and specifically flags like final, appear to just need weird special
           * handling.
           *
           * Note: we can't use {@code TreeInfo.getEndPos()} or {@code JCTree.getEndPosition()}
           * here, because they will return the end position of an enclosing AST node for trees
           * whose real end positions aren't stored.
           */
                int endPos = endPositions.getEndPos(tree);
                boolean hasRealEndPosition = endPos != Position.NOPOS;
                if (tree.getKind() != Kind.MODIFIERS && hasRealEndPosition) {
                    writer.append(unitContents.substring(tree.getStartPosition(), endPos));
                } else {
                    super.printExpr(tree, prec);
                }
            }

            @Override
            public void visitApply(JCMethodInvocation tree) {
                JCExpression select = tree.getMethodSelect();
                if (select != null && select.toString().equals("Refaster.emitCommentBefore")) {
                    String commentLiteral = (String) ((JCLiteral) tree.getArguments().get(0)).getValue();
                    JCExpression expr = tree.getArguments().get(1);
                    try {
                        print("/* " + commentLiteral + " */ ");
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                    expr.accept(this);
                } else {
                    super.visitApply(tree);
                }
            }

            @Override
            public void printStat(JCTree tree) throws IOException {
                if (tree instanceof JCExpressionStatement && ((JCExpressionStatement) tree).getExpression() instanceof JCMethodInvocation) {
                    JCMethodInvocation invocation = (JCMethodInvocation) ((JCExpressionStatement) tree).getExpression();
                    JCExpression select = invocation.getMethodSelect();
                    if (select != null && select.toString().equals("Refaster.emitComment")) {
                        String commentLiteral = (String) ((JCLiteral) invocation.getArguments().get(0)).getValue();
                        print("// " + commentLiteral);
                        return;
                    }
                }
                super.printStat(tree);
            }

            @Override
            public void visitTry(JCTry tree) {
                if (tree.getResources().isEmpty()) {
                    super.visitTry(tree);
                    return;
                }
                try {
                    print("try (");
                    boolean first = true;
                    for (JCTree resource : tree.getResources()) {
                        if (!first) {
                            print(";");
                            println();
                        }
                        printExpr(resource);
                        first = false;
                    }
                    print(")");
                    printStat(tree.body);
                    for (JCCatch catchStmt : tree.getCatches()) {
                        printStat(catchStmt);
                    }
                    if (tree.getFinallyBlock() != null) {
                        print(" finally ");
                        printStat(tree.getFinallyBlock());
                    }
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        };
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}
Also used : JCCompilationUnit(com.sun.tools.javac.tree.JCTree.JCCompilationUnit) JCTree(com.sun.tools.javac.tree.JCTree) IOException(java.io.IOException) JCExpressionStatement(com.sun.tools.javac.tree.JCTree.JCExpressionStatement) Pretty(com.sun.tools.javac.tree.Pretty) JCTry(com.sun.tools.javac.tree.JCTree.JCTry) JCMethodInvocation(com.sun.tools.javac.tree.JCTree.JCMethodInvocation) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) JCCatch(com.sun.tools.javac.tree.JCTree.JCCatch) JCAnnotation(com.sun.tools.javac.tree.JCTree.JCAnnotation) EndPosTable(com.sun.tools.javac.tree.EndPosTable)

Example 12 with JCMethodInvocation

use of com.sun.tools.javac.tree.JCTree.JCMethodInvocation in project lombok by rzwitserloot.

the class JavacHandlerUtil method isConstructorCall.

public static boolean isConstructorCall(final JCStatement statement) {
    if (!(statement instanceof JCExpressionStatement))
        return false;
    JCExpression expr = ((JCExpressionStatement) statement).expr;
    if (!(expr instanceof JCMethodInvocation))
        return false;
    JCExpression invocation = ((JCMethodInvocation) expr).meth;
    String name;
    if (invocation instanceof JCFieldAccess) {
        name = ((JCFieldAccess) invocation).name.toString();
    } else if (invocation instanceof JCIdent) {
        name = ((JCIdent) invocation).name.toString();
    } else {
        name = "";
    }
    return "super".equals(name) || "this".equals(name);
}
Also used : JCMethodInvocation(com.sun.tools.javac.tree.JCTree.JCMethodInvocation) JCIdent(com.sun.tools.javac.tree.JCTree.JCIdent) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) JCFieldAccess(com.sun.tools.javac.tree.JCTree.JCFieldAccess) JCExpressionStatement(com.sun.tools.javac.tree.JCTree.JCExpressionStatement)

Example 13 with JCMethodInvocation

use of com.sun.tools.javac.tree.JCTree.JCMethodInvocation in project lombok by rzwitserloot.

the class JavacHandlerUtil method createFieldAccessor.

static JCExpression createFieldAccessor(JavacTreeMaker maker, JavacNode field, FieldAccess fieldAccess, JCExpression receiver) {
    boolean lookForGetter = lookForGetter(field, fieldAccess);
    GetterMethod getter = lookForGetter ? findGetter(field) : null;
    JCVariableDecl fieldDecl = (JCVariableDecl) field.get();
    if (getter == null) {
        if (receiver == null) {
            if ((fieldDecl.mods.flags & Flags.STATIC) == 0) {
                receiver = maker.Ident(field.toName("this"));
            } else {
                JavacNode containerNode = field.up();
                if (containerNode != null && containerNode.get() instanceof JCClassDecl) {
                    JCClassDecl container = (JCClassDecl) field.up().get();
                    receiver = maker.Ident(container.name);
                }
            }
        }
        return receiver == null ? maker.Ident(fieldDecl.name) : maker.Select(receiver, fieldDecl.name);
    }
    if (receiver == null)
        receiver = maker.Ident(field.toName("this"));
    JCMethodInvocation call = maker.Apply(List.<JCExpression>nil(), maker.Select(receiver, getter.name), List.<JCExpression>nil());
    return call;
}
Also used : JCMethodInvocation(com.sun.tools.javac.tree.JCTree.JCMethodInvocation) JCClassDecl(com.sun.tools.javac.tree.JCTree.JCClassDecl) JavacNode(lombok.javac.JavacNode) JCVariableDecl(com.sun.tools.javac.tree.JCTree.JCVariableDecl)

Example 14 with JCMethodInvocation

use of com.sun.tools.javac.tree.JCTree.JCMethodInvocation in project lombok by rzwitserloot.

the class HandleToString method createToString.

static JCMethodDecl createToString(JavacNode typeNode, Collection<JavacNode> fields, boolean includeFieldNames, boolean callSuper, FieldAccess fieldAccess, JCTree source) {
    JavacTreeMaker maker = typeNode.getTreeMaker();
    JCAnnotation overrideAnnotation = maker.Annotation(genJavaLangTypeRef(typeNode, "Override"), List.<JCExpression>nil());
    JCModifiers mods = maker.Modifiers(Flags.PUBLIC, List.of(overrideAnnotation));
    JCExpression returnType = genJavaLangTypeRef(typeNode, "String");
    boolean first = true;
    String typeName = getTypeName(typeNode);
    String infix = ", ";
    String suffix = ")";
    String prefix;
    if (callSuper) {
        prefix = typeName + "(super=";
    } else if (fields.isEmpty()) {
        prefix = typeName + "()";
    } else if (includeFieldNames) {
        prefix = typeName + "(" + ((JCVariableDecl) fields.iterator().next().get()).name.toString() + "=";
    } else {
        prefix = typeName + "(";
    }
    JCExpression current = maker.Literal(prefix);
    if (callSuper) {
        JCMethodInvocation callToSuper = maker.Apply(List.<JCExpression>nil(), maker.Select(maker.Ident(typeNode.toName("super")), typeNode.toName("toString")), List.<JCExpression>nil());
        current = maker.Binary(CTC_PLUS, current, callToSuper);
        first = false;
    }
    for (JavacNode fieldNode : fields) {
        JCExpression expr;
        JCExpression fieldAccessor = createFieldAccessor(maker, fieldNode, fieldAccess);
        JCExpression fieldType = getFieldType(fieldNode, fieldAccess);
        // The distinction between primitive and object will be useful if we ever add a 'hideNulls' option.
        boolean fieldIsPrimitive = fieldType instanceof JCPrimitiveTypeTree;
        boolean fieldIsPrimitiveArray = fieldType instanceof JCArrayTypeTree && ((JCArrayTypeTree) fieldType).elemtype instanceof JCPrimitiveTypeTree;
        boolean fieldIsObjectArray = !fieldIsPrimitiveArray && fieldType instanceof JCArrayTypeTree;
        @SuppressWarnings("unused") boolean fieldIsObject = !fieldIsPrimitive && !fieldIsPrimitiveArray && !fieldIsObjectArray;
        if (fieldIsPrimitiveArray || fieldIsObjectArray) {
            JCExpression tsMethod = chainDots(typeNode, "java", "util", "Arrays", fieldIsObjectArray ? "deepToString" : "toString");
            expr = maker.Apply(List.<JCExpression>nil(), tsMethod, List.<JCExpression>of(fieldAccessor));
        } else
            expr = fieldAccessor;
        if (first) {
            current = maker.Binary(CTC_PLUS, current, expr);
            first = false;
            continue;
        }
        if (includeFieldNames) {
            current = maker.Binary(CTC_PLUS, current, maker.Literal(infix + fieldNode.getName() + "="));
        } else {
            current = maker.Binary(CTC_PLUS, current, maker.Literal(infix));
        }
        current = maker.Binary(CTC_PLUS, current, expr);
    }
    if (!first)
        current = maker.Binary(CTC_PLUS, current, maker.Literal(suffix));
    JCStatement returnStatement = maker.Return(current);
    JCBlock body = maker.Block(0, List.of(returnStatement));
    return recursiveSetGeneratedBy(maker.MethodDef(mods, typeNode.toName("toString"), returnType, List.<JCTypeParameter>nil(), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), body, null), source, typeNode.getContext());
}
Also used : JCBlock(com.sun.tools.javac.tree.JCTree.JCBlock) JavacTreeMaker(lombok.javac.JavacTreeMaker) ToString(lombok.ToString) JCStatement(com.sun.tools.javac.tree.JCTree.JCStatement) JCVariableDecl(com.sun.tools.javac.tree.JCTree.JCVariableDecl) JCTypeParameter(com.sun.tools.javac.tree.JCTree.JCTypeParameter) JCMethodInvocation(com.sun.tools.javac.tree.JCTree.JCMethodInvocation) JCPrimitiveTypeTree(com.sun.tools.javac.tree.JCTree.JCPrimitiveTypeTree) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) JavacNode(lombok.javac.JavacNode) JCModifiers(com.sun.tools.javac.tree.JCTree.JCModifiers) JCAnnotation(com.sun.tools.javac.tree.JCTree.JCAnnotation) JCArrayTypeTree(com.sun.tools.javac.tree.JCTree.JCArrayTypeTree)

Example 15 with JCMethodInvocation

use of com.sun.tools.javac.tree.JCTree.JCMethodInvocation in project lombok by rzwitserloot.

the class HandleEqualsAndHashCode method createEquals.

public JCMethodDecl createEquals(JavacNode typeNode, List<JavacNode> fields, boolean callSuper, FieldAccess fieldAccess, boolean needsCanEqual, JCTree source, List<JCAnnotation> onParam) {
    JavacTreeMaker maker = typeNode.getTreeMaker();
    Name oName = typeNode.toName("o");
    Name otherName = typeNode.toName("other");
    Name thisName = typeNode.toName("this");
    JCAnnotation overrideAnnotation = maker.Annotation(genJavaLangTypeRef(typeNode, "Override"), List.<JCExpression>nil());
    JCModifiers mods = maker.Modifiers(Flags.PUBLIC, List.of(overrideAnnotation));
    JCExpression objectType = genJavaLangTypeRef(typeNode, "Object");
    JCExpression returnType = maker.TypeIdent(CTC_BOOLEAN);
    long finalFlag = JavacHandlerUtil.addFinalIfNeeded(0L, typeNode.getContext());
    ListBuffer<JCStatement> statements = new ListBuffer<JCStatement>();
    final List<JCVariableDecl> params = List.of(maker.VarDef(maker.Modifiers(finalFlag | Flags.PARAMETER, onParam), oName, objectType, null));
    /* if (o == this) return true; */
    {
        statements.append(maker.If(maker.Binary(CTC_EQUAL, maker.Ident(oName), maker.Ident(thisName)), returnBool(maker, true), null));
    }
    /* if (!(o instanceof Outer.Inner.MyType)) return false; */
    {
        JCUnary notInstanceOf = maker.Unary(CTC_NOT, maker.Parens(maker.TypeTest(maker.Ident(oName), createTypeReference(typeNode, false))));
        statements.append(maker.If(notInstanceOf, returnBool(maker, false), null));
    }
    /* Outer.Inner.MyType<?> other = (Outer.Inner.MyType<?>) o; */
    {
        if (!fields.isEmpty() || needsCanEqual) {
            final JCExpression selfType1 = createTypeReference(typeNode, true), selfType2 = createTypeReference(typeNode, true);
            statements.append(maker.VarDef(maker.Modifiers(finalFlag), otherName, selfType1, maker.TypeCast(selfType2, maker.Ident(oName))));
        }
    }
    /* if (!other.canEqual((java.lang.Object) this)) return false; */
    {
        if (needsCanEqual) {
            List<JCExpression> exprNil = List.nil();
            JCExpression thisRef = maker.Ident(thisName);
            JCExpression castThisRef = maker.TypeCast(genJavaLangTypeRef(typeNode, "Object"), thisRef);
            JCExpression equalityCheck = maker.Apply(exprNil, maker.Select(maker.Ident(otherName), typeNode.toName("canEqual")), List.of(castThisRef));
            statements.append(maker.If(maker.Unary(CTC_NOT, equalityCheck), returnBool(maker, false), null));
        }
    }
    /* if (!super.equals(o)) return false; */
    if (callSuper) {
        JCMethodInvocation callToSuper = maker.Apply(List.<JCExpression>nil(), maker.Select(maker.Ident(typeNode.toName("super")), typeNode.toName("equals")), List.<JCExpression>of(maker.Ident(oName)));
        JCUnary superNotEqual = maker.Unary(CTC_NOT, callToSuper);
        statements.append(maker.If(superNotEqual, returnBool(maker, false), null));
    }
    Name thisDollar = typeNode.toName("this$");
    Name otherDollar = typeNode.toName("other$");
    for (JavacNode fieldNode : fields) {
        JCExpression fType = getFieldType(fieldNode, fieldAccess);
        JCExpression thisFieldAccessor = createFieldAccessor(maker, fieldNode, fieldAccess);
        JCExpression otherFieldAccessor = createFieldAccessor(maker, fieldNode, fieldAccess, maker.Ident(otherName));
        if (fType instanceof JCPrimitiveTypeTree) {
            switch(((JCPrimitiveTypeTree) fType).getPrimitiveTypeKind()) {
                case FLOAT:
                    /* if (Float.compare(this.fieldName, other.fieldName) != 0) return false; */
                    statements.append(generateCompareFloatOrDouble(thisFieldAccessor, otherFieldAccessor, maker, typeNode, false));
                    break;
                case DOUBLE:
                    /* if (Double.compare(this.fieldName, other.fieldName) != 0) return false; */
                    statements.append(generateCompareFloatOrDouble(thisFieldAccessor, otherFieldAccessor, maker, typeNode, true));
                    break;
                default:
                    /* if (this.fieldName != other.fieldName) return false; */
                    statements.append(maker.If(maker.Binary(CTC_NOT_EQUAL, thisFieldAccessor, otherFieldAccessor), returnBool(maker, false), null));
                    break;
            }
        } else if (fType instanceof JCArrayTypeTree) {
            /* if (!java.util.Arrays.deepEquals(this.fieldName, other.fieldName)) return false; //use equals for primitive arrays. */
            boolean multiDim = ((JCArrayTypeTree) fType).elemtype instanceof JCArrayTypeTree;
            boolean primitiveArray = ((JCArrayTypeTree) fType).elemtype instanceof JCPrimitiveTypeTree;
            boolean useDeepEquals = multiDim || !primitiveArray;
            JCExpression eqMethod = chainDots(typeNode, "java", "util", "Arrays", useDeepEquals ? "deepEquals" : "equals");
            List<JCExpression> args = List.of(thisFieldAccessor, otherFieldAccessor);
            statements.append(maker.If(maker.Unary(CTC_NOT, maker.Apply(List.<JCExpression>nil(), eqMethod, args)), returnBool(maker, false), null));
        } else /* objects */
        {
            /* final java.lang.Object this$fieldName = this.fieldName; */
            /* final java.lang.Object other$fieldName = other.fieldName; */
            /* if (this$fieldName == null ? other$fieldName != null : !this$fieldName.equals(other$fieldName)) return false; */
            Name fieldName = ((JCVariableDecl) fieldNode.get()).name;
            Name thisDollarFieldName = thisDollar.append(fieldName);
            Name otherDollarFieldName = otherDollar.append(fieldName);
            statements.append(maker.VarDef(maker.Modifiers(finalFlag), thisDollarFieldName, genJavaLangTypeRef(typeNode, "Object"), thisFieldAccessor));
            statements.append(maker.VarDef(maker.Modifiers(finalFlag), otherDollarFieldName, genJavaLangTypeRef(typeNode, "Object"), otherFieldAccessor));
            JCExpression thisEqualsNull = maker.Binary(CTC_EQUAL, maker.Ident(thisDollarFieldName), maker.Literal(CTC_BOT, null));
            JCExpression otherNotEqualsNull = maker.Binary(CTC_NOT_EQUAL, maker.Ident(otherDollarFieldName), maker.Literal(CTC_BOT, null));
            JCExpression thisEqualsThat = maker.Apply(List.<JCExpression>nil(), maker.Select(maker.Ident(thisDollarFieldName), typeNode.toName("equals")), List.<JCExpression>of(maker.Ident(otherDollarFieldName)));
            JCExpression fieldsAreNotEqual = maker.Conditional(thisEqualsNull, otherNotEqualsNull, maker.Unary(CTC_NOT, thisEqualsThat));
            statements.append(maker.If(fieldsAreNotEqual, returnBool(maker, false), null));
        }
    }
    /* return true; */
    {
        statements.append(returnBool(maker, true));
    }
    JCBlock body = maker.Block(0, statements.toList());
    return recursiveSetGeneratedBy(maker.MethodDef(mods, typeNode.toName("equals"), returnType, List.<JCTypeParameter>nil(), params, List.<JCExpression>nil(), body, null), source, typeNode.getContext());
}
Also used : JCBlock(com.sun.tools.javac.tree.JCTree.JCBlock) JavacTreeMaker(lombok.javac.JavacTreeMaker) ListBuffer(com.sun.tools.javac.util.ListBuffer) JCStatement(com.sun.tools.javac.tree.JCTree.JCStatement) JCVariableDecl(com.sun.tools.javac.tree.JCTree.JCVariableDecl) Name(com.sun.tools.javac.util.Name) JCTypeParameter(com.sun.tools.javac.tree.JCTree.JCTypeParameter) JCMethodInvocation(com.sun.tools.javac.tree.JCTree.JCMethodInvocation) JCPrimitiveTypeTree(com.sun.tools.javac.tree.JCTree.JCPrimitiveTypeTree) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) JavacNode(lombok.javac.JavacNode) JCModifiers(com.sun.tools.javac.tree.JCTree.JCModifiers) JCUnary(com.sun.tools.javac.tree.JCTree.JCUnary) ArrayList(java.util.ArrayList) List(com.sun.tools.javac.util.List) JCAnnotation(com.sun.tools.javac.tree.JCTree.JCAnnotation) JCArrayTypeTree(com.sun.tools.javac.tree.JCTree.JCArrayTypeTree)

Aggregations

JCMethodInvocation (com.sun.tools.javac.tree.JCTree.JCMethodInvocation)26 JCExpression (com.sun.tools.javac.tree.JCTree.JCExpression)15 JCTree (com.sun.tools.javac.tree.JCTree)10 JCVariableDecl (com.sun.tools.javac.tree.JCTree.JCVariableDecl)8 JCExpressionStatement (com.sun.tools.javac.tree.JCTree.JCExpressionStatement)7 JCNewClass (com.sun.tools.javac.tree.JCTree.JCNewClass)6 JCStatement (com.sun.tools.javac.tree.JCTree.JCStatement)6 JCFieldAccess (com.sun.tools.javac.tree.JCTree.JCFieldAccess)5 JCMethodDecl (com.sun.tools.javac.tree.JCTree.JCMethodDecl)5 ArrayList (java.util.ArrayList)5 JCAnnotation (com.sun.tools.javac.tree.JCTree.JCAnnotation)4 JCBlock (com.sun.tools.javac.tree.JCTree.JCBlock)4 JCIdent (com.sun.tools.javac.tree.JCTree.JCIdent)4 Name (com.sun.tools.javac.util.Name)4 JavacTreeMaker (lombok.javac.JavacTreeMaker)4 ExpressionTree (com.sun.source.tree.ExpressionTree)3 Symbol (com.sun.tools.javac.code.Symbol)3 ClassSymbol (com.sun.tools.javac.code.Symbol.ClassSymbol)3 MethodSymbol (com.sun.tools.javac.code.Symbol.MethodSymbol)3 Type (com.sun.tools.javac.code.Type)3