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();
}
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();
}
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);
}
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;
}
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());
}
Aggregations