Search in sources :

Example 21 with JCMethodInvocation

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

the class BoxedPrimitiveConstructor method buildFix.

private Fix buildFix(NewClassTree tree, VisitorState state) {
    boolean autoboxFix = shouldAutoboxFix(state);
    Types types = state.getTypes();
    Type type = types.unboxedTypeOrType(getType(tree));
    if (types.isSameType(type, state.getSymtab().booleanType)) {
        Object value = literalValue(tree.getArguments().iterator().next());
        if (value instanceof Boolean) {
            return SuggestedFix.replace(tree, literalFix((boolean) value, autoboxFix));
        } else if (value instanceof String) {
            return SuggestedFix.replace(tree, literalFix(Boolean.parseBoolean((String) value), autoboxFix));
        }
    }
    // Primitive constructors are all unary
    JCTree.JCExpression arg = (JCTree.JCExpression) getOnlyElement(tree.getArguments());
    Type argType = getType(arg);
    if (autoboxFix && argType.isPrimitive()) {
        return SuggestedFix.builder().replace(((JCTree) tree).getStartPosition(), arg.getStartPosition(), maybeCast(state, type, argType)).replace(state.getEndPosition(arg), state.getEndPosition(tree), "").build();
    }
    JCTree parent = (JCTree) state.getPath().getParentPath().getParentPath().getLeaf();
    if (TO_STRING.matches(parent, state)) {
        // e.g. new Integer($A).toString() -> String.valueOf($A)
        return SuggestedFix.builder().replace(parent.getStartPosition(), arg.getStartPosition(), "String.valueOf(").replace(state.getEndPosition(arg), state.getEndPosition(parent), ")").build();
    }
    String typeName = state.getSourceForNode(tree.getIdentifier());
    DoubleAndFloatStatus doubleAndFloatStatus = doubleAndFloatStatus(state, type, argType);
    if (HASH_CODE.matches(parent, state)) {
        // e.g. new Integer($A).hashCode() -> Integer.hashCode($A)
        SuggestedFix.Builder fix = SuggestedFix.builder();
        String replacement;
        String optionalCast = "";
        String optionalSuffix = "";
        switch(doubleAndFloatStatus) {
            case PRIMITIVE_DOUBLE_INTO_FLOAT:
                // new Float(double).compareTo($foo) => Float.compare((float) double, foo)
                optionalCast = "(float) ";
                break;
            case BOXED_DOUBLE_INTO_FLOAT:
                // new Float(Double).compareTo($foo) => Float.compare(Double.floatValue(), foo)
                optionalSuffix = ".floatValue()";
                break;
            default:
                break;
        }
        // in Java 7, those don't exist, so we suggest Guava
        if (shouldUseGuavaHashCode(state.context)) {
            fix.addImport("com.google.common.primitives." + typeName + "s");
            replacement = String.format("%ss.hashCode(", typeName);
        } else {
            replacement = String.format("%s.hashCode(", typeName);
        }
        return fix.replace(parent.getStartPosition(), arg.getStartPosition(), replacement + optionalCast).replace(state.getEndPosition(arg), state.getEndPosition(parent), optionalSuffix + ")").build();
    }
    if (COMPARE_TO.matches(parent, state) && ASTHelpers.getReceiver((ExpressionTree) parent).equals(tree)) {
        JCMethodInvocation compareTo = (JCMethodInvocation) parent;
        // e.g. new Integer($A).compareTo($B) -> Integer.compare($A, $B)
        JCTree.JCExpression rhs = getOnlyElement(compareTo.getArguments());
        String optionalCast = "";
        String optionalSuffix = "";
        switch(doubleAndFloatStatus) {
            case PRIMITIVE_DOUBLE_INTO_FLOAT:
                // new Float(double).compareTo($foo) => Float.compare((float) double, foo)
                optionalCast = "(float) ";
                break;
            case BOXED_DOUBLE_INTO_FLOAT:
                // new Float(Double).compareTo($foo) => Float.compare(Double.floatValue(), foo)
                optionalSuffix = ".floatValue()";
                break;
            default:
                break;
        }
        return SuggestedFix.builder().replace(compareTo.getStartPosition(), arg.getStartPosition(), String.format("%s.compare(%s", typeName, optionalCast)).replace(/* startPos= */
        state.getEndPosition(arg), /* endPos= */
        rhs.getStartPosition(), String.format("%s, ", optionalSuffix)).replace(state.getEndPosition(rhs), state.getEndPosition(compareTo), ")").build();
    }
    // Patch new Float(Double) => Float.valueOf(float) by downcasting the double, since
    // neither valueOf(float) nor valueOf(String) match.
    String prefixToArg;
    String suffix = "";
    switch(doubleAndFloatStatus) {
        case PRIMITIVE_DOUBLE_INTO_FLOAT:
            // new Float(double) => Float.valueOf((float) double)
            prefixToArg = String.format("%s.valueOf(%s", typeName, "(float) ");
            break;
        case BOXED_DOUBLE_INTO_FLOAT:
            // new Float(Double) => Double.floatValue()
            prefixToArg = "";
            suffix = ".floatValue(";
            break;
        default:
            prefixToArg = String.format("%s.valueOf(", typeName);
            break;
    }
    return SuggestedFix.builder().replace(((JCTree) tree).getStartPosition(), arg.getStartPosition(), prefixToArg).postfixWith(arg, suffix).build();
}
Also used : Types(com.sun.tools.javac.code.Types) JCTree(com.sun.tools.javac.tree.JCTree) JCMethodInvocation(com.sun.tools.javac.tree.JCTree.JCMethodInvocation) Matchers.toType(com.google.errorprone.matchers.Matchers.toType) ASTHelpers.getType(com.google.errorprone.util.ASTHelpers.getType) ASTHelpers.isSameType(com.google.errorprone.util.ASTHelpers.isSameType) Type(com.sun.tools.javac.code.Type) SuggestedFix(com.google.errorprone.fixes.SuggestedFix)

Example 22 with JCMethodInvocation

use of com.sun.tools.javac.tree.JCTree.JCMethodInvocation in project ceylon-compiler by ceylon.

the class JavaPositionsRetriever method getJavaSourceCodeWithCeylonPositions.

public String getJavaSourceCodeWithCeylonPositions() {
    final CharArrayWriter writer = new CharArrayWriter();
    Pretty printer = new Pretty(writer, true) {

        int previousCeylonPosition = -1;

        int previousPositionInString = 0;

        private void outputCeylonPosition(JCTree tree) {
            try {
                int currentCeylonPosition = tree.getPreferredPosition();
                int currentPositionInString = writer.size();
                if (previousCeylonPosition != currentCeylonPosition || previousPositionInString != currentPositionInString) {
                    if (currentCeylonPosition != -1 && currentCeylonPosition != 0) {
                        writer.write("/* " + formatCeylonPosition(currentCeylonPosition) + " */");
                    }
                    previousCeylonPosition = currentCeylonPosition;
                    previousPositionInString = writer.size();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void visitTopLevel(JCCompilationUnit tree) {
            outputCeylonPosition(tree);
            super.visitTopLevel(tree);
        }

        @Override
        public void visitImport(JCImport tree) {
            outputCeylonPosition(tree);
            super.visitImport(tree);
        }

        @Override
        public void visitClassDef(JCClassDecl tree) {
            outputCeylonPosition(tree);
            super.visitClassDef(tree);
        }

        @Override
        public void visitMethodDef(JCMethodDecl tree) {
            outputCeylonPosition(tree);
            super.visitMethodDef(tree);
        }

        @Override
        public void visitVarDef(JCVariableDecl tree) {
            outputCeylonPosition(tree);
            super.visitVarDef(tree);
        }

        @Override
        public void visitSkip(JCSkip tree) {
            outputCeylonPosition(tree);
            super.visitSkip(tree);
        }

        @Override
        public void visitBlock(JCBlock tree) {
            outputCeylonPosition(tree);
            super.visitBlock(tree);
            tree.endpos = currentPosition - 1;
        }

        @Override
        public void visitDoLoop(JCDoWhileLoop tree) {
            outputCeylonPosition(tree);
            super.visitDoLoop(tree);
        }

        @Override
        public void visitWhileLoop(JCWhileLoop tree) {
            outputCeylonPosition(tree);
            super.visitWhileLoop(tree);
        }

        @Override
        public void visitForLoop(JCForLoop tree) {
            outputCeylonPosition(tree);
            super.visitForLoop(tree);
        }

        @Override
        public void visitForeachLoop(JCEnhancedForLoop tree) {
            outputCeylonPosition(tree);
            super.visitForeachLoop(tree);
        }

        @Override
        public void visitLabelled(JCLabeledStatement tree) {
            outputCeylonPosition(tree);
            super.visitLabelled(tree);
        }

        @Override
        public void visitSwitch(JCSwitch tree) {
            outputCeylonPosition(tree);
            super.visitSwitch(tree);
        }

        @Override
        public void visitCase(JCCase tree) {
            outputCeylonPosition(tree);
            super.visitCase(tree);
        }

        @Override
        public void visitSynchronized(JCSynchronized tree) {
            outputCeylonPosition(tree);
            super.visitSynchronized(tree);
        }

        @Override
        public void visitTry(JCTry tree) {
            outputCeylonPosition(tree);
            super.visitTry(tree);
        }

        @Override
        public void visitCatch(JCCatch tree) {
            outputCeylonPosition(tree);
            super.visitCatch(tree);
        }

        @Override
        public void visitConditional(JCConditional tree) {
            outputCeylonPosition(tree);
            super.visitConditional(tree);
        }

        @Override
        public void visitIf(JCIf tree) {
            outputCeylonPosition(tree);
            super.visitIf(tree);
        }

        @Override
        public void visitExec(JCExpressionStatement tree) {
            outputCeylonPosition(tree);
            super.visitExec(tree);
        }

        @Override
        public void visitBreak(JCBreak tree) {
            outputCeylonPosition(tree);
            super.visitBreak(tree);
        }

        @Override
        public void visitContinue(JCContinue tree) {
            outputCeylonPosition(tree);
            super.visitContinue(tree);
        }

        @Override
        public void visitReturn(JCReturn tree) {
            outputCeylonPosition(tree);
            super.visitReturn(tree);
        }

        @Override
        public void visitThrow(JCThrow tree) {
            outputCeylonPosition(tree);
            super.visitThrow(tree);
        }

        @Override
        public void visitAssert(JCAssert tree) {
            outputCeylonPosition(tree);
            super.visitAssert(tree);
        }

        @Override
        public void visitApply(JCMethodInvocation tree) {
            outputCeylonPosition(tree);
            super.visitApply(tree);
        }

        @Override
        public void visitNewClass(JCNewClass tree) {
            outputCeylonPosition(tree);
            super.visitNewClass(tree);
        }

        @Override
        public void visitNewArray(JCNewArray tree) {
            outputCeylonPosition(tree);
            super.visitNewArray(tree);
        }

        @Override
        public void visitParens(JCParens tree) {
            outputCeylonPosition(tree);
            super.visitParens(tree);
        }

        @Override
        public void visitAssign(JCAssign tree) {
            outputCeylonPosition(tree);
            super.visitAssign(tree);
        }

        @Override
        public void visitAssignop(JCAssignOp tree) {
            outputCeylonPosition(tree);
            super.visitAssignop(tree);
        }

        @Override
        public void visitUnary(JCUnary tree) {
            outputCeylonPosition(tree);
            super.visitUnary(tree);
        }

        @Override
        public void visitBinary(JCBinary tree) {
            outputCeylonPosition(tree);
            super.visitBinary(tree);
        }

        @Override
        public void visitTypeCast(JCTypeCast tree) {
            outputCeylonPosition(tree);
            super.visitTypeCast(tree);
        }

        @Override
        public void visitTypeTest(JCInstanceOf tree) {
            outputCeylonPosition(tree);
            super.visitTypeTest(tree);
        }

        @Override
        public void visitIndexed(JCArrayAccess tree) {
            outputCeylonPosition(tree);
            super.visitIndexed(tree);
        }

        @Override
        public void visitSelect(JCFieldAccess tree) {
            outputCeylonPosition(tree);
            super.visitSelect(tree);
        }

        @Override
        public void visitIdent(JCIdent tree) {
            outputCeylonPosition(tree);
            super.visitIdent(tree);
        }

        @Override
        public void visitLiteral(JCLiteral tree) {
            outputCeylonPosition(tree);
            super.visitLiteral(tree);
        }

        @Override
        public void visitTypeIdent(JCPrimitiveTypeTree tree) {
            outputCeylonPosition(tree);
            super.visitTypeIdent(tree);
        }

        @Override
        public void visitTypeArray(JCArrayTypeTree tree) {
            outputCeylonPosition(tree);
            super.visitTypeArray(tree);
        }

        @Override
        public void visitTypeApply(JCTypeApply tree) {
            outputCeylonPosition(tree);
            super.visitTypeApply(tree);
        }

        @Override
        public void visitTypeParameter(JCTypeParameter tree) {
            outputCeylonPosition(tree);
            super.visitTypeParameter(tree);
        }

        @Override
        public void visitWildcard(JCWildcard tree) {
            outputCeylonPosition(tree);
            super.visitWildcard(tree);
        }

        @Override
        public void visitTypeBoundKind(TypeBoundKind tree) {
            outputCeylonPosition(tree);
            super.visitTypeBoundKind(tree);
        }

        @Override
        public void visitErroneous(JCErroneous tree) {
            outputCeylonPosition(tree);
            super.visitErroneous(tree);
        }

        @Override
        public void visitLetExpr(LetExpr tree) {
            outputCeylonPosition(tree);
            super.visitLetExpr(tree);
        }

        @Override
        public void visitModifiers(JCModifiers mods) {
            outputCeylonPosition(mods);
            super.visitModifiers(mods);
        }

        @Override
        public void visitAnnotation(JCAnnotation tree) {
            outputCeylonPosition(tree);
            super.visitAnnotation(tree);
        }

        @Override
        public void visitTree(JCTree tree) {
            outputCeylonPosition(tree);
            super.visitTree(tree);
        }
    };
    printer.visitTopLevel(unit);
    return writer.toString();
}
Also used : JCFieldAccess(com.sun.tools.javac.tree.JCTree.JCFieldAccess) JCTypeApply(com.sun.tools.javac.tree.JCTree.JCTypeApply) JCAssert(com.sun.tools.javac.tree.JCTree.JCAssert) JCPrimitiveTypeTree(com.sun.tools.javac.tree.JCTree.JCPrimitiveTypeTree) JCIf(com.sun.tools.javac.tree.JCTree.JCIf) JCEnhancedForLoop(com.sun.tools.javac.tree.JCTree.JCEnhancedForLoop) JCNewClass(com.sun.tools.javac.tree.JCTree.JCNewClass) JCNewArray(com.sun.tools.javac.tree.JCTree.JCNewArray) JCAnnotation(com.sun.tools.javac.tree.JCTree.JCAnnotation) JCCase(com.sun.tools.javac.tree.JCTree.JCCase) JCThrow(com.sun.tools.javac.tree.JCTree.JCThrow) JCImport(com.sun.tools.javac.tree.JCTree.JCImport) JCWildcard(com.sun.tools.javac.tree.JCTree.JCWildcard) JCClassDecl(com.sun.tools.javac.tree.JCTree.JCClassDecl) JCIdent(com.sun.tools.javac.tree.JCTree.JCIdent) JCMethodDecl(com.sun.tools.javac.tree.JCTree.JCMethodDecl) LetExpr(com.sun.tools.javac.tree.JCTree.LetExpr) JCErroneous(com.sun.tools.javac.tree.JCTree.JCErroneous) JCSynchronized(com.sun.tools.javac.tree.JCTree.JCSynchronized) JCParens(com.sun.tools.javac.tree.JCTree.JCParens) JCDoWhileLoop(com.sun.tools.javac.tree.JCTree.JCDoWhileLoop) JCContinue(com.sun.tools.javac.tree.JCTree.JCContinue) JCInstanceOf(com.sun.tools.javac.tree.JCTree.JCInstanceOf) TypeBoundKind(com.sun.tools.javac.tree.JCTree.TypeBoundKind) JCTypeParameter(com.sun.tools.javac.tree.JCTree.JCTypeParameter) JCMethodInvocation(com.sun.tools.javac.tree.JCTree.JCMethodInvocation) JCUnary(com.sun.tools.javac.tree.JCTree.JCUnary) JCModifiers(com.sun.tools.javac.tree.JCTree.JCModifiers) JCCatch(com.sun.tools.javac.tree.JCTree.JCCatch) JCCompilationUnit(com.sun.tools.javac.tree.JCTree.JCCompilationUnit) JCWhileLoop(com.sun.tools.javac.tree.JCTree.JCWhileLoop) JCReturn(com.sun.tools.javac.tree.JCTree.JCReturn) JCLabeledStatement(com.sun.tools.javac.tree.JCTree.JCLabeledStatement) JCAssign(com.sun.tools.javac.tree.JCTree.JCAssign) JCSkip(com.sun.tools.javac.tree.JCTree.JCSkip) JCConditional(com.sun.tools.javac.tree.JCTree.JCConditional) JCExpressionStatement(com.sun.tools.javac.tree.JCTree.JCExpressionStatement) CharArrayWriter(java.io.CharArrayWriter) JCTypeCast(com.sun.tools.javac.tree.JCTree.JCTypeCast) JCArrayTypeTree(com.sun.tools.javac.tree.JCTree.JCArrayTypeTree) JCBlock(com.sun.tools.javac.tree.JCTree.JCBlock) JCTree(com.sun.tools.javac.tree.JCTree) JCBinary(com.sun.tools.javac.tree.JCTree.JCBinary) JCArrayAccess(com.sun.tools.javac.tree.JCTree.JCArrayAccess) IOException(java.io.IOException) JCForLoop(com.sun.tools.javac.tree.JCTree.JCForLoop) JCVariableDecl(com.sun.tools.javac.tree.JCTree.JCVariableDecl) Pretty(com.sun.tools.javac.tree.Pretty) JCTry(com.sun.tools.javac.tree.JCTree.JCTry) JCSwitch(com.sun.tools.javac.tree.JCTree.JCSwitch) JCLiteral(com.sun.tools.javac.tree.JCTree.JCLiteral) JCAssignOp(com.sun.tools.javac.tree.JCTree.JCAssignOp) JCBreak(com.sun.tools.javac.tree.JCTree.JCBreak)

Example 23 with JCMethodInvocation

use of com.sun.tools.javac.tree.JCTree.JCMethodInvocation in project ceylon-compiler by ceylon.

the class Attr method checkId.

/**
 * Determine type of identifier or select expression and check that
 *  (1) the referenced symbol is not deprecated
 *  (2) the symbol's type is safe (@see checkSafe)
 *  (3) if symbol is a variable, check that its type and kind are
 *      compatible with the prototype and protokind.
 *  (4) if symbol is an instance field of a raw type,
 *      which is being assigned to, issue an unchecked warning if its
 *      type changes under erasure.
 *  (5) if symbol is an instance method of a raw type, issue an
 *      unchecked warning if its argument types change under erasure.
 *  If checks succeed:
 *    If symbol is a constant, return its constant type
 *    else if symbol is a method, return its result type
 *    otherwise return its type.
 *  Otherwise return errType.
 *
 *  @param tree       The syntax tree representing the identifier
 *  @param site       If this is a select, the type of the selected
 *                    expression, otherwise the type of the current class.
 *  @param sym        The symbol representing the identifier.
 *  @param env        The current environment.
 *  @param pkind      The set of expected kinds.
 *  @param pt         The expected type.
 */
Type checkId(JCTree tree, Type site, Symbol sym, Env<AttrContext> env, int pkind, Type pt, boolean useVarargs) {
    if (pt.isErroneous())
        return types.createErrorType(site);
    // The computed type of this identifier occurrence.
    Type owntype;
    switch(sym.kind) {
        case TYP:
            // For types, the computed type equals the symbol's type,
            // except for two situations:
            owntype = sym.type;
            if (owntype.tag == CLASS) {
                Type ownOuter = owntype.getEnclosingType();
                // We recover generic outer type later in visitTypeApply.
                if (owntype.tsym.type.getTypeArguments().nonEmpty()) {
                    owntype = types.erasure(owntype);
                } else // Tree<Point>.Visitor.
                if (ownOuter.tag == CLASS && site != ownOuter) {
                    Type normOuter = site;
                    if (normOuter.tag == CLASS)
                        normOuter = types.asEnclosingSuper(site, ownOuter.tsym);
                    if (// perhaps from an import
                    normOuter == null)
                        normOuter = types.erasure(ownOuter);
                    if (normOuter != ownOuter)
                        owntype = new ClassType(normOuter, List.<Type>nil(), owntype.tsym);
                }
            }
            break;
        case VAR:
            VarSymbol v = (VarSymbol) sym;
            // its type changes under erasure.
            if (allowGenerics && pkind == VAR && v.owner.kind == TYP && (v.flags() & STATIC) == 0 && (site.tag == CLASS || site.tag == TYPEVAR)) {
                Type s = types.asOuterSuper(site, v.owner);
                if (s != null && s.isRaw() && !types.isSameType(v.type, v.erasure(types))) {
                    chk.warnUnchecked(tree.pos(), "unchecked.assign.to.var", v, s);
                }
            }
            // The computed type of a variable is the type of the
            // variable symbol, taken as a member of the site type.
            owntype = (sym.owner.kind == TYP && sym.name != names._this && sym.name != names._super) ? types.memberType(site, sym) : sym.type;
            if (env.info.tvars.nonEmpty()) {
                Type owntype1 = new ForAll(env.info.tvars, owntype);
                for (List<Type> l = env.info.tvars; l.nonEmpty(); l = l.tail) if (!owntype.contains(l.head)) {
                    log.error(tree.pos(), "undetermined.type", owntype1);
                    owntype1 = types.createErrorType(owntype1);
                }
                owntype = owntype1;
            }
            // computed type.
            if (v.getConstValue() != null && isStaticReference(tree))
                owntype = owntype.constType(v.getConstValue());
            if (pkind == VAL) {
                // capture "names as expressions"
                owntype = capture(owntype);
            }
            break;
        case MTH:
            {
                JCMethodInvocation app = (JCMethodInvocation) env.tree;
                owntype = checkMethod(site, sym, env, app.args, pt.getParameterTypes(), pt.getTypeArguments(), env.info.varArgs);
                break;
            }
        case PCK:
        case ERR:
            owntype = sym.type;
            break;
        default:
            throw new AssertionError("unexpected kind: " + sym.kind + " in tree " + tree);
    }
    if (sym.name != names.init) {
        chk.checkDeprecated(tree.pos(), env.info.scope.owner, sym);
        chk.checkSunAPI(tree.pos(), sym);
    }
    // kind are compatible with the prototype and protokind.
    return check(tree, owntype, sym.kind, pkind, pt);
}
Also used : JCMethodInvocation(com.sun.tools.javac.tree.JCTree.JCMethodInvocation) ClassType(com.sun.tools.javac.code.Type.ClassType) MethodType(com.sun.tools.javac.code.Type.MethodType) WildcardType(com.sun.tools.javac.code.Type.WildcardType) Type(com.sun.tools.javac.code.Type) ArrayType(com.sun.tools.javac.code.Type.ArrayType) UnionClassType(com.sun.tools.javac.code.Type.UnionClassType) VarSymbol(com.sun.tools.javac.code.Symbol.VarSymbol) ClassType(com.sun.tools.javac.code.Type.ClassType) UnionClassType(com.sun.tools.javac.code.Type.UnionClassType) ForAll(com.sun.tools.javac.code.Type.ForAll)

Example 24 with JCMethodInvocation

use of com.sun.tools.javac.tree.JCTree.JCMethodInvocation in project ceylon-compiler by ceylon.

the class ClassTransformer method makeMainMethod.

/**
 * Makes a {@code main()} method which calls the given callee
 * (a no-args method or class)
 * @param decl
 * @param callee
 */
private MethodDefinitionBuilder makeMainMethod(Declaration decl, JCExpression callee) {
    // Add a main() method
    MethodDefinitionBuilder methbuilder = MethodDefinitionBuilder.main(this).ignoreModelAnnotations();
    // Add call to process.setupArguments
    JCExpression argsId = makeUnquotedIdent("args");
    JCMethodInvocation processExpr = make().Apply(null, naming.makeLanguageValue("process"), List.<JCTree.JCExpression>nil());
    methbuilder.body(make().Exec(make().Apply(null, makeSelect(processExpr, "setupArguments"), List.<JCTree.JCExpression>of(argsId))));
    // Add call to toplevel method
    methbuilder.body(make().Exec(callee));
    return methbuilder;
}
Also used : JCMethodInvocation(com.sun.tools.javac.tree.JCTree.JCMethodInvocation) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) JCTree(com.sun.tools.javac.tree.JCTree)

Example 25 with JCMethodInvocation

use of com.sun.tools.javac.tree.JCTree.JCMethodInvocation in project ceylon-compiler by ceylon.

the class ExpressionTransformer method transformStringExpression.

public JCExpression transformStringExpression(Tree.StringTemplate expr) {
    at(expr);
    JCExpression builder;
    builder = make().NewClass(null, null, naming.makeFQIdent("java", "lang", "StringBuilder"), List.<JCExpression>nil(), null);
    java.util.List<Tree.StringLiteral> literals = expr.getStringLiterals();
    java.util.List<Tree.Expression> expressions = expr.getExpressions();
    for (int ii = 0; ii < literals.size(); ii += 1) {
        Tree.StringLiteral literal = literals.get(ii);
        if (!literal.getText().isEmpty()) {
            // ignore empty string literals
            at(literal);
            builder = make().Apply(null, makeSelect(builder, "append"), List.<JCExpression>of(transform(literal)));
        }
        if (ii == expressions.size()) {
            // after that because we've already exhausted all the expressions
            break;
        }
        Tree.Expression expression = expressions.get(ii);
        at(expression);
        // Here in both cases we don't need a type cast for erasure
        if (isCeylonBasicType(expression.getTypeModel()) && expression.getUnboxed()) {
            // TODO: Test should be erases to String, long, int, boolean, char, byte, float, double
            // If erases to a Java primitive just call append, don't box it just to call format.
            String method = isCeylonCharacter(expression.getTypeModel()) ? "appendCodePoint" : "append";
            builder = make().Apply(null, makeSelect(builder, method), List.<JCExpression>of(transformExpression(expression, BoxingStrategy.UNBOXED, null)));
        } else {
            JCMethodInvocation formatted = make().Apply(null, makeSelect(transformExpression(expression), "toString"), List.<JCExpression>nil());
            builder = make().Apply(null, makeSelect(builder, "append"), List.<JCExpression>of(formatted));
        }
    }
    return make().Apply(null, makeSelect(builder, "toString"), List.<JCExpression>nil());
}
Also used : JCMethodInvocation(com.sun.tools.javac.tree.JCTree.JCMethodInvocation) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) LetExpression(com.redhat.ceylon.compiler.typechecker.tree.Tree.LetExpression) Expression(com.redhat.ceylon.compiler.typechecker.tree.Tree.Expression) Expression(com.redhat.ceylon.compiler.typechecker.tree.Tree.Expression) JCTree(com.sun.tools.javac.tree.JCTree) Tree(com.redhat.ceylon.compiler.typechecker.tree.Tree)

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