public static ExpressionTree findValue(AnnotationTree m, String name) { for (ExpressionTree et : m.getArguments()) { if (et.getKind() == Kind.ASSIGNMENT) { AssignmentTree at = (AssignmentTree) et; String varName = ((IdentifierTree) at.getVariable()).getName().toString(); if (varName.equals(name)) { return at.getExpression(); } } if (et instanceof LiteralTree/*XXX*/ && "value".equals(name)) { return et; } } return null; }
@Override public Number visitIdentifier(IdentifierTree node, Void p) { String name = node.getName().toString(); Tree newNode = handleIdentifier(name, node); if (newNode != null) { rewrite(node, newNode); if (NUMBER_LITERAL_KINDS.contains(newNode.getKind())) { return (Number) ((LiteralTree) newNode).getValue(); } } Element e = info.getTrees().getElement(getCurrentPath()); if (e != null && isStaticElement(e) && !inImport) { rewrite(node, make.QualIdent(e)); } return super.visitIdentifier(node, p); }
private String getBundleName(MethodInvocationTree n, int index, String bfn) { if (n.getArguments().size() <= index) { return null; } ExpressionTree t = n.getArguments().get(index); // recognize just string literals + .class references if (t.getKind() == Tree.Kind.STRING_LITERAL) { Object o = ((LiteralTree)t).getValue(); return o == null ? null : o.toString(); } else if (t.getKind() == Tree.Kind.MEMBER_SELECT) { MemberSelectTree mst = (MemberSelectTree)t; if (!mst.getIdentifier().contentEquals("class")) { return null; } return bundleFileFromClass(new TreePath(getCurrentPath(), mst.getExpression()), bfn); } return null; }
@Test public void matches() { // TODO(b/67738557): consolidate helpers for creating fake trees LiteralTree tree = new LiteralTree() { @Override public Kind getKind() { throw new UnsupportedOperationException(); } @Override public <R, D> R accept(TreeVisitor<R, D> visitor, D data) { throw new UnsupportedOperationException(); } @Override public Object getValue() { return "a string literal"; } }; assertTrue(new StringLiteral("a string literal").matches(tree, null)); }
@Override public Description matchMethodInvocation(MethodInvocationTree t, VisitorState state) { if (PRECONDITIONS_CHECK.matches(t, state) && t.getArguments().size() >= 2 && t.getArguments().get(1) instanceof LiteralTree) { LiteralTree formatStringTree = (LiteralTree) t.getArguments().get(1); if (formatStringTree.getValue() instanceof String) { String formatString = (String) formatStringTree.getValue(); int expectedArgs = expectedArguments(formatString); if (expectedArgs < t.getArguments().size() - 2 && BAD_PLACEHOLDER_REGEX.matcher(formatString).find()) { return describe(t, state); } } } return Description.NO_MATCH; }
public Description describe(MethodInvocationTree t, VisitorState state) { LiteralTree formatTree = (LiteralTree) t.getArguments().get(1); String fixedFormatString = BAD_PLACEHOLDER_REGEX.matcher(state.getSourceForNode((JCTree) formatTree)).replaceAll("%s"); if (expectedArguments(fixedFormatString) == t.getArguments().size() - 2) { return describeMatch(formatTree, SuggestedFix.replace(formatTree, fixedFormatString)); } else { int missing = t.getArguments().size() - 2 - expectedArguments(fixedFormatString); StringBuilder builder = new StringBuilder(fixedFormatString); builder.deleteCharAt(builder.length() - 1); builder.append(" [%s"); for (int i = 1; i < missing; i++) { builder.append(", %s"); } builder.append("]\""); return describeMatch(t, SuggestedFix.replace(formatTree, builder.toString())); } }
@Override public boolean matches(BinaryTree tree, VisitorState state) { Type leftType = ((JCTree) tree.getLeftOperand()).type; Types types = state.getTypes(); Symtab symtab = state.getSymtab(); if (!(types.isSameType(leftType, symtab.intType)) && !(types.isSameType(leftType, symtab.byteType)) && !(types.isSameType(leftType, symtab.shortType)) && !(types.isSameType(leftType, symtab.charType))) { return false; } ExpressionTree rightOperand = tree.getRightOperand(); if (rightOperand instanceof LiteralTree) { Object rightValue = ((LiteralTree) rightOperand).getValue(); if (rightValue instanceof Number) { int intValue = ((Number) rightValue).intValue(); return intValue < 0 || intValue > 31; } } return false; }
@Override public Description matchBinary(BinaryTree tree, VisitorState state) { if (!BINARY_TREE_MATCHER.matches(tree, state)) { return Description.NO_MATCH; } /* * For shift amounts in [32, 63], cast the left operand to long. Otherwise change the shift * amount to whatever would actually be used. */ int intValue = ((Number) ((LiteralTree) tree.getRightOperand()).getValue()).intValue(); Fix fix; if (intValue >= 32 && intValue <= 63) { if (tree.getLeftOperand().getKind() == Kind.INT_LITERAL) { fix = SuggestedFix.postfixWith(tree.getLeftOperand(), "L"); } else { fix = SuggestedFix.prefixWith(tree, "(long) "); } } else { // This is the equivalent shift distance according to JLS 15.19. String actualShiftDistance = Integer.toString(intValue & 0x1f); fix = SuggestedFix.replace(tree.getRightOperand(), actualShiftDistance); } return describeMatch(tree, fix); }
private Description matchDivZero(Tree tree, ExpressionTree operand, VisitorState state) { if (!anyOf(kindIs(Kind.DIVIDE), kindIs(Kind.DIVIDE_ASSIGNMENT)).matches(tree, state)) { return Description.NO_MATCH; } if (!kindIs(Kind.INT_LITERAL).matches(operand, state)) { return Description.NO_MATCH; } LiteralTree rightOperand = (LiteralTree) operand; if (((Integer) rightOperand.getValue()) != 0) { return Description.NO_MATCH; } // Find and replace enclosing Statement. StatementTree enclosingStmt = ASTHelpers.findEnclosingNode(state.getPath(), StatementTree.class); return (enclosingStmt != null) ? describeMatch( tree, SuggestedFix.replace(enclosingStmt, "throw new ArithmeticException(\"/ by zero\");")) : describeMatch(tree); }
private ExpressionType isGreaterThanEqualToZero(BinaryTree tree) { ExpressionTree literalOperand; ExpressionType returnType; switch (tree.getKind()) { case GREATER_THAN_EQUAL: literalOperand = tree.getRightOperand(); returnType = ExpressionType.GREATER_THAN_EQUAL; break; case LESS_THAN_EQUAL: literalOperand = tree.getLeftOperand(); returnType = ExpressionType.LESS_THAN_EQUAL; break; default: return ExpressionType.MISMATCH; } if (literalOperand.getKind() != Kind.INT_LITERAL) { return ExpressionType.MISMATCH; } if (!((LiteralTree) literalOperand).getValue().equals(0)) { return ExpressionType.MISMATCH; } return returnType; }
@Override public Description matchNewClass(NewClassTree tree, VisitorState state) { if (ASTHelpers.isSameType( state.getSymtab().stringBuilderType, ASTHelpers.getType(tree.getIdentifier()), state) && tree.getArguments().size() == 1) { ExpressionTree argument = tree.getArguments().get(0); Type type = ((JCTree) argument).type; if (type.getKind() == TypeKind.CHAR) { if (argument.getKind() == Kind.CHAR_LITERAL) { char ch = (Character) ((LiteralTree) argument).getValue(); return describeMatch( tree, SuggestedFix.replace(argument, "\"" + Convert.quote(Character.toString(ch)) + "\"")); } else { return describeMatch( tree, SuggestedFix.replace( tree, "new StringBuilder().append(" + state.getSourceForNode((JCTree) argument) + ")")); } } } return Description.NO_MATCH; }
private Scanner literalHasIdentifierMatching( final boolean shouldMatch, final Matcher<Tree> toMatch) { ScannerTest test = new ScannerTest() { private boolean matched = false; @Override public Void visitLiteral(LiteralTree node, VisitorState visitorState) { visitorState = visitorState.withPath(getCurrentPath()); if (toMatch.matches(node, visitorState)) { matched = true; } return super.visitLiteral(node, visitorState); } @Override void assertDone() { assertEquals(matched, shouldMatch); } }; tests.add(test); return test; }
public Description describe(MethodInvocationTree t, VisitorState state) { LiteralTree formatTree = (LiteralTree) t.getArguments().get(1); String fixedFormatString = state.getSourceForNode((JCTree) formatTree).toString() .replaceAll(BAD_PLACEHOLDER_REGEX, "%s"); SuggestedFix fix = new SuggestedFix(); if (expectedArguments(fixedFormatString) == t.getArguments().size() - 2) { fix.replace(formatTree, fixedFormatString); return describeMatch(formatTree, fix); } else { int missing = t.getArguments().size() - 2 - expectedArguments(fixedFormatString); StringBuilder builder = new StringBuilder(fixedFormatString); builder.deleteCharAt(builder.length() - 1); builder.append(" [%s"); for (int i = 1; i < missing; i++) { builder.append(", %s"); } builder.append("]\""); fix.replace(formatTree, builder.toString()); return describeMatch(t, fix); } }
private boolean isConstantOne(JCExpression exp) { Tree.Kind kind = exp.getKind(); if (kind == Kind.INT_LITERAL || kind == Kind.LONG_LITERAL || kind == Kind.FLOAT_LITERAL || kind == Kind.DOUBLE_LITERAL) { if (exp instanceof LiteralTree) { Object literalValue = ((LiteralTree) exp).getValue(); if (literalValue instanceof Number) { int intValue = ((Number) literalValue).intValue(); if (intValue == 1) { return true; } } } } return false; }
@SuppressWarnings("unchecked") private Description matchDivZero(Tree tree, ExpressionTree operand, VisitorState state) { if (!anyOf(kindIs(Kind.DIVIDE), kindIs(Kind.DIVIDE_ASSIGNMENT)).matches(tree, state)) { return Description.NO_MATCH; } if (!kindIs(Kind.INT_LITERAL).matches(operand, state)) { return Description.NO_MATCH; } LiteralTree rightOperand = (LiteralTree) operand; if (((Integer) rightOperand.getValue()) != 0) { return Description.NO_MATCH; } // Find and replace enclosing Statement. StatementTree enclosingStmt = ASTHelpers.findEnclosingNode(state.getPath(), StatementTree.class); SuggestedFix fix = new SuggestedFix(); if (enclosingStmt != null) { fix = fix.replace(enclosingStmt, "throw new ArithmeticException(\"/ by zero\");"); } return describeMatch(tree, fix); }
/** * Returns true if the node is a constant-time expression. * * A tree is a constant-time expression if it is: * <ol> * <li>a literal tree * <li>a reference to a final variable initialized with a compile time * constant * <li>a String concatenation of two compile time constants * </ol> */ public static boolean isCompileTimeString(ExpressionTree node) { ExpressionTree tree = TreeUtils.skipParens(node); if (tree instanceof LiteralTree) return true; if (TreeUtils.isUseOfElement(tree)) { Element elt = TreeUtils.elementFromUse(tree); return ElementUtils.isCompileTimeConstant(elt); } else if (TreeUtils.isStringConcatenation(tree)) { BinaryTree binOp = (BinaryTree) tree; return isCompileTimeString(binOp.getLeftOperand()) && isCompileTimeString(binOp.getRightOperand()); } else { return false; } }
@Override public Void visitLiteral(LiteralTree tree, AnnotatedTypeMirror type) { if (!type.isAnnotatedInHierarchy(FORMAT)) { String format = null; if (tree.getKind() == Tree.Kind.STRING_LITERAL) { format = (String) tree.getValue(); } else if (tree.getKind() == Tree.Kind.CHAR_LITERAL) { format = Character.toString((Character) tree.getValue()); } if (format != null) { AnnotationMirror anno; try { ConversionCategory[] cs = FormatUtil.formatParameterCategories(format); anno = FormatterAnnotatedTypeFactory.this.treeUtil.categoriesToFormatAnnotation(cs); } catch (IllegalFormatException e) { anno = FormatterAnnotatedTypeFactory.this.treeUtil.exceptionToInvalidFormatAnnotation(e); } type.addAnnotation(anno); } } return super.visitLiteral(tree, type); }
/** * Determine whether all dimensions given in a new array expression have * zero as length. For example "new Object[0][0];". Also true for empty * dimensions, as in "new Object[] {...}". */ private static boolean isNewArrayAllZeroDims(NewArrayTree node) { boolean isAllZeros = true; for (ExpressionTree dim : node.getDimensions()) { if (dim instanceof LiteralTree) { Object val = ((LiteralTree) dim).getValue(); if (!(val instanceof Number) || !(new Integer(0).equals(val))) { isAllZeros = false; break; } } else { isAllZeros = false; break; } } return isAllZeros; }
/** * Case 1: valid regular expression String or char literal. * Adds PartialRegex annotation to String literals that are not valid * regular expressions. */ @Override public Void visitLiteral(LiteralTree tree, AnnotatedTypeMirror type) { if (!type.isAnnotatedInHierarchy(REGEX)) { String regex = null; if (tree.getKind() == Tree.Kind.STRING_LITERAL) { regex = (String) tree.getValue(); } else if (tree.getKind() == Tree.Kind.CHAR_LITERAL) { regex = Character.toString((Character) tree.getValue()); } if (regex != null) { if (isRegex(regex)) { int groupCount = getGroupCount(regex); type.addAnnotation(createRegexAnnotation(groupCount)); } else { type.addAnnotation(createPartialRegexAnnotation(regex)); } } } return super.visitLiteral(tree, type); }
/** * Go through the string patterns and add the greatest lower bound of all matching patterns. */ @Override public Void visitLiteral(LiteralTree tree, AnnotatedTypeMirror type) { if (!stringPatterns.isEmpty() && tree.getKind() == Tree.Kind.STRING_LITERAL) { Set<? extends AnnotationMirror> res = null; String string = (String) tree.getValue(); for (Pattern pattern : stringPatterns.keySet()) { if (pattern.matcher(string).matches()) { if (res == null) { res = stringPatterns.get(pattern); } else { Set<? extends AnnotationMirror> newres = stringPatterns.get(pattern); res = qualHierarchy.greatestLowerBounds(res, newres); } } } if (res != null) { type.addAnnotations(res); } } return super.visitLiteral(tree, type); }
/** * Returns true if the node is a constant-time expression. * * <p>A tree is a constant-time expression if it is: * * <ol> * <li>a literal tree * <li>a reference to a final variable initialized with a compile time constant * <li>a String concatenation of two compile time constants * </ol> */ public static boolean isCompileTimeString(ExpressionTree node) { ExpressionTree tree = TreeUtils.skipParens(node); if (tree instanceof LiteralTree) { return true; } if (TreeUtils.isUseOfElement(tree)) { Element elt = TreeUtils.elementFromUse(tree); return ElementUtils.isCompileTimeConstant(elt); } else if (TreeUtils.isStringConcatenation(tree)) { BinaryTree binOp = (BinaryTree) tree; return isCompileTimeString(binOp.getLeftOperand()) && isCompileTimeString(binOp.getRightOperand()); } else { return false; } }
static String getAnnotationTreeAttributeValue( AnnotationTree annotation, String attributeName ) { AssignmentTree tree = getAnnotationTreeAttribute(annotation, attributeName); if (tree == null) { return null; } else { ExpressionTree expression = tree.getExpression(); if (expression instanceof LiteralTree) { Object value = ((LiteralTree) expression).getValue(); return value == null ? null : value.toString(); } return null; } }
/** */ private StatementTree generateSystemOutPrintln(TreeMaker maker, String arg) { MethodInvocationTree methodInvocation = maker.MethodInvocation( Collections.<ExpressionTree>emptyList(), //type args maker.MemberSelect( maker.MemberSelect( maker.Identifier("System"), "out"), "println"),//NOI18N Collections.<LiteralTree>singletonList( maker.Literal(arg))); //args. return maker.ExpressionStatement(methodInvocation); }
@Override public Tree visitLiteral(LiteralTree tree, Void p) { LiteralTree n = make.Literal(tree.getValue()); model.setType(n, model.getType(tree)); comments.copyComments(tree, n); model.setPos(n, model.getPos(tree)); return n; }
public Boolean visitLiteral(LiteralTree node, TreePath p) { if (p == null) return super.visitLiteral(node, p); LiteralTree lt = (LiteralTree) p.getLeaf(); Object nodeValue = node.getValue(); Object ltValue = lt.getValue(); if (nodeValue == ltValue) return true; if (nodeValue == null || ltValue == null) return false; return nodeValue.equals(ltValue); }
public void testNoExtraEscapesInStringLiteral() throws Exception { testFile = new File(getWorkDir(), "Test.java"); TestUtilities.copyStringToFile(testFile, "package hierbas.del.litoral;\n" + "\n" + "public class Test {\n" + " public static final String C;\n" + "}\n" ); String golden = "package hierbas.del.litoral;\n" + "\n" + "public class Test {\n" + " public static final String C = \"'\";\n" + "}\n"; JavaSource testSource = JavaSource.forFileObject(FileUtil.toFileObject(testFile)); Task<WorkingCopy> task = new Task<WorkingCopy>() { public void run(WorkingCopy workingCopy) throws java.io.IOException { workingCopy.toPhase(Phase.RESOLVED); TreeMaker make = workingCopy.getTreeMaker(); ClassTree clazz = (ClassTree) workingCopy.getCompilationUnit().getTypeDecls().get(0); VariableTree var = (VariableTree) clazz.getMembers().get(1); LiteralTree val = make.Literal("'"); VariableTree nue = make.setInitialValue(var, val); workingCopy.rewrite(var, nue); } }; testSource.runModificationTask(task).commit(); String res = TestUtilities.copyFileToString(testFile); System.err.println(res); assertEquals(golden, res); }
public void testNoExtraEscapesInCharLiteral() throws Exception { testFile = new File(getWorkDir(), "Test.java"); TestUtilities.copyStringToFile(testFile, "package hierbas.del.litoral;\n" + "\n" + "public class Test {\n" + " public static final char C;\n" + "}\n" ); String golden = "package hierbas.del.litoral;\n" + "\n" + "public class Test {\n" + " public static final char C = '\"';\n" + "}\n"; JavaSource testSource = JavaSource.forFileObject(FileUtil.toFileObject(testFile)); Task<WorkingCopy> task = new Task<WorkingCopy>() { public void run(WorkingCopy workingCopy) throws java.io.IOException { workingCopy.toPhase(Phase.RESOLVED); TreeMaker make = workingCopy.getTreeMaker(); ClassTree clazz = (ClassTree) workingCopy.getCompilationUnit().getTypeDecls().get(0); VariableTree var = (VariableTree) clazz.getMembers().get(1); LiteralTree val = make.Literal('"'); VariableTree nue = make.setInitialValue(var, val); workingCopy.rewrite(var, nue); } }; testSource.runModificationTask(task).commit(); String res = TestUtilities.copyFileToString(testFile); System.err.println(res); assertEquals(golden, res); }
public void testPrintMemberReference() throws Exception { testFile = new File(getWorkDir(), "Test.java"); TestUtilities.copyStringToFile(testFile, "package hierbas.del.litoral;\n\n" + "public class Test {\n" + " public static void taragui() {\n" + " Runnable r = null;\n" + " }\n" + "}\n" ); String golden = "package hierbas.del.litoral;\n\n" + "public class Test {\n" + " public static void taragui() {\n" + " Runnable r = Test::taragui;\n" + " }\n" + "}\n"; JavaSource src = getJavaSource(testFile); Task<WorkingCopy> task = new Task<WorkingCopy>() { public void run(final WorkingCopy workingCopy) throws IOException { workingCopy.toPhase(Phase.RESOLVED); CompilationUnitTree cut = workingCopy.getCompilationUnit(); final TreeMaker make = workingCopy.getTreeMaker(); new ErrorAwareTreeScanner<Void, Void>() { @Override public Void visitLiteral(LiteralTree node, Void p) { workingCopy.rewrite(node, make.MemberReference(ReferenceMode.INVOKE, make.Identifier("Test"), "taragui", Collections.<ExpressionTree>emptyList())); return super.visitLiteral(node, p); } }.scan(workingCopy.getCompilationUnit(), null); } }; src.runModificationTask(task).commit(); String res = TestUtilities.copyFileToString(testFile); System.err.println(res); assertEquals(golden, res); }
@Override public Number visitTypeParameter(TypeParameterTree node, Void p) { String name = node.getName().toString(); Tree newNode = handleIdentifier(name, node); if (newNode != null) { rewrite(node, newNode); if (NUMBER_LITERAL_KINDS.contains(newNode.getKind())) { return (Number) ((LiteralTree) newNode).getValue(); } } return super.visitTypeParameter(node, p); }
@Override public Number visitLiteral(LiteralTree node, Void p) { if (node.getValue() instanceof Number) { return (Number) node.getValue(); } return super.visitLiteral(node, p); }
@Override public Void visitLiteral(LiteralTree tree, List<Node> d) { List<Node> below = new ArrayList<Node>(); addCorrespondingType(below); addCorrespondingComments(below); super.visitLiteral(tree, below); d.add(new TreeNode(info, getCurrentPath(), below)); return null; }
@Override public Object visitLiteral(LiteralTree node, Void p) { if (node.getKind() == NULL_LITERAL) { return enhanceProcessing ? NULL : null; } return node.getValue(); }
private List<ProspectiveOperation> getIfListRepresentation( StatementTree tree, boolean last) { IfTree ifTree = (IfTree) tree; List<ProspectiveOperation> ls = new ArrayList<ProspectiveOperation>(); if (ifTree.getElseStatement() == null) { StatementTree then = ifTree.getThenStatement(); if (isOneStatementBlock(then)) { then = ((BlockTree) then).getStatements().get(0); } if (then.getKind() == Tree.Kind.RETURN) { ReturnTree returnTree = (ReturnTree) then; ExpressionTree returnExpression = returnTree.getExpression(); if (returnExpression.getKind() == Tree.Kind.BOOLEAN_LITERAL && ((LiteralTree) returnExpression).getValue().equals(true)) { ls.addAll(ProspectiveOperation.createOperator(ifTree, ProspectiveOperation.OperationType.ANYMATCH, this.preconditionsChecker, this.workingCopy)); } else if (returnExpression.getKind() == Tree.Kind.BOOLEAN_LITERAL && ((LiteralTree) returnExpression).getValue().equals(false)) { ls.addAll(ProspectiveOperation.createOperator(ifTree, ProspectiveOperation.OperationType.NONEMATCH, this.preconditionsChecker, this.workingCopy)); } } else { ls.addAll(ProspectiveOperation.createOperator(ifTree, ProspectiveOperation.OperationType.FILTER, this.preconditionsChecker, this.workingCopy)); ls.addAll(getListRepresentation(ifTree.getThenStatement(), last)); } } else { ls.addAll(ProspectiveOperation.createOperator(ifTree, ProspectiveOperation.OperationType.MAP, this.preconditionsChecker, this.workingCopy)); } return ls; }
@Override public Boolean visitLiteral(LiteralTree node, ConstructorData p) { Object val = node.getValue(); if (val instanceof Boolean) { return (Boolean) val; } else { return null; } }
@Override public String visitLiteral(LiteralTree node, Void p) { if (node.getValue() instanceof String) return "..."; int start = (int) info.getTrees().getSourcePositions().getStartPosition(info.getCompilationUnit(), node); int end = (int) info.getTrees().getSourcePositions().getEndPosition(info.getCompilationUnit(), node); if (start < 0 || end < 0 || end < start) { return node.toString(); } return info.getText().substring(start, end); }
private boolean canBooleanExpressionEvalToTrue(ExpressionTree expressionTree) { if (expressionTree instanceof LiteralTree) { LiteralTree expressionAsLiteral = (LiteralTree) expressionTree; if (expressionAsLiteral.getValue() instanceof Boolean) { return (boolean) expressionAsLiteral.getValue(); } else { throw new RuntimeException("not a boolean expression!"); } } // We are fairly conservative, anything other than 'return false;' is assumed to potentially be // true. // No SAT-solving or any other funny business. return true; }
@Override public Void visitLiteral(LiteralTree node, Void unused) { sync(node); String sourceForNode = getSourceForNode(node, getCurrentPath()); // A negative numeric literal -n is usually represented as unary minus on n, // but that doesn't work for integer or long MIN_VALUE. The parser works // around that by representing it directly as a singed literal (with no // unary minus), but the lexer still expects two tokens. if (sourceForNode.startsWith("-")) { token("-"); sourceForNode = sourceForNode.substring(1).trim(); } token(sourceForNode); return null; }