@Override public boolean matches(VariableTree variableTree, VisitorState state) { return treeMatcher.matches(variableTree.getType(), state); } };
@Nullable @Override public Type visitVariable(VariableTree tree, Void unused) { return getType(tree.getType()); }
@Override public Description matchVariable(VariableTree tree, VisitorState state) { return checkArrayDimensions(tree, tree.getType(), state); }
private static Map<String, Type> indexTypeByName(List<? extends VariableTree> parameters) { Map<String, Type> result = newHashMap(); for (VariableTree parameter : parameters) { result.put(parameter.getName().toString(), getType(parameter.getType())); } return result; }
@Override public Void visitVariable(VariableTree node, Void aVoid) { if (sym.equals(ASTHelpers.getSymbol(node))) { fix.replace(node.getType(), replacement.getSimpleName()) .addImport(replacement.getCanonicalName()); } return null; } },
@Override public Void visitVariable(VariableTree variableTree, Void v) { if (getSymbol(variableTree).equals(symbol)) { String name = variableTree.getName().toString(); // For a lambda parameter without explicit type, it will return null. String source = state.getSourceForNode(variableTree.getType()); if (newTypeName != null) { possibleFixes.fixByReplacing(variableTree.getType(), newTypeName); } if (newName != null && !newName.equals(name)) { int typeLength = source == null ? 0 : source.length(); int pos = ((JCTree) variableTree).getStartPosition() + state.getSourceForNode(variableTree).indexOf(name, typeLength); possibleFixes.fixByReplacing(pos, pos + name.length(), newName); } } return super.visitVariable(variableTree, v); } }.scan(state.getPath().getCompilationUnit(), null);
public static ParameterTree create(VariableTree variableTree) { Preconditions.checkArgument(isValidParameterTree(variableTree)); Name name = variableTree.getName(); Tree type = variableTree.getType(); boolean isVarargs = isVariableTreeVarArgs(variableTree); return new AutoValue_ParameterTree(name, type, isVarargs); }
/** * Returns a string describing the exception type caught by the given try tree's catch * statement(s), defaulting to {@code "Exception"} if more than one exception type is caught. */ private static String exceptionToString(TryTree tree, VisitorState state) { if (tree.getCatches().size() != 1) { return "Exception"; } Tree exceptionType = tree.getCatches().iterator().next().getParameter().getType(); Type type = ASTHelpers.getType(exceptionType); if (type != null && type.isUnion()) { return "Exception"; } return state.getSourceForNode(exceptionType); }
private static boolean isVariableClassCreator( VariableTree variableTree, VisitorState state, ClassType classType, Symbol parcelableCreatorSymbol) { Tree typeTree = variableTree.getType(); Type type = ASTHelpers.getType(typeTree); Types types = state.getTypes(); Type superType = types.asSuper(type, parcelableCreatorSymbol); if (superType == null) { return false; } List<Type> typeArguments = superType.getTypeArguments(); if (typeArguments.isEmpty()) { // raw creator return true; } return ASTHelpers.isSubtype(classType, Iterables.getOnlyElement(typeArguments), state); } }
/** Return whether the given try-tree will catch the given exception type. */ private boolean tryCatchesException(TryTree tryTree, Type exceptionToCatch, VisitorState state) { Types types = state.getTypes(); return tryTree.getCatches().stream() .anyMatch( (CatchTree catchClause) -> { Type catchesException = getType(catchClause.getParameter().getType()); // Examine all alternative types of a union type. if (catchesException != null && catchesException.isUnion()) { return Streams.stream(((UnionClassType) catchesException).getAlternativeTypes()) .anyMatch(caught -> types.isSuperType(caught, exceptionToCatch)); } // Simple type, just check superclass. return types.isSuperType(catchesException, exceptionToCatch); }); }
@Override public Description matchTry(TryTree tree, VisitorState state) { List<? extends StatementTree> body = tree.getBlock().getStatements(); if (body.isEmpty() || tree.getFinallyBlock() != null || tree.getCatches().size() != 1) { // TODO(cushon): support finally // TODO(cushon): support multiple catch blocks return NO_MATCH; } CatchTree catchTree = getOnlyElement(tree.getCatches()); if (catchTree.getParameter().getType().getKind() == UNION_TYPE) { // TODO(cushon): handle multi-catch return NO_MATCH; } if (!FAIL_METHOD.matches(getLast(body), state)) { return NO_MATCH; } // try body statements, excluding the trailing `fail()` List<? extends StatementTree> throwingStatements = tree.getBlock().getStatements().subList(0, tree.getBlock().getStatements().size() - 1); Optional<Fix> fix = AssertThrowsUtils.tryFailToAssertThrows(tree, throwingStatements, state); return fix.isPresent() ? describeMatch(tree, fix) : NO_MATCH; } }
@Override public UVariableDecl visitVariable(VariableTree tree, Void v) { return UVariableDecl.create( tree.getName(), templateType(tree.getType()), (tree.getInitializer() == null) ? null : template(tree.getInitializer())); }
private static Fix threadLocalFix( VariableTree tree, VisitorState state, final VarSymbol sym, SuggestedFix rename) { SuggestedFix.Builder fix = SuggestedFix.builder() .merge(rename) .replace( tree.getType(), String.format("ThreadLocal<%s>", state.getSourceForNode(tree.getType()))) .prefixWith(tree.getInitializer(), "ThreadLocal.withInitial(() -> ") .postfixWith(tree.getInitializer(), ")"); CompilationUnitTree unit = state.getPath().getCompilationUnit(); unit.accept( new TreeScanner<Void, Void>() { @Override public Void visitIdentifier(IdentifierTree tree, Void unused) { if (Objects.equals(ASTHelpers.getSymbol(tree), sym)) { fix.postfixWith(tree, ".get()"); } return null; } }, null); return fix.build(); } }
@Override public Choice<State<JCVariableDecl>> visitVariable(final VariableTree node, State<?> state) { return chooseSubtrees( state, s -> unifyExpression(node.getInitializer(), s), init -> maker() .VarDef( (JCModifiers) node.getModifiers(), (Name) node.getName(), (JCExpression) node.getType(), init)); }
/** * Renames the given {@link VariableTree} and its usages in the current compilation unit to {@code * replacement}. */ public static SuggestedFix renameVariable( VariableTree tree, final String replacement, VisitorState state) { String name = tree.getName().toString(); int typeEndPos = state.getEndPosition(tree.getType()); // handle implicit lambda parameter types int searchOffset = typeEndPos == -1 ? 0 : (typeEndPos - ((JCTree) tree).getStartPosition()); int pos = ((JCTree) tree).getStartPosition() + state.getSourceForNode(tree).indexOf(name, searchOffset); final SuggestedFix.Builder fix = SuggestedFix.builder().replace(pos, pos + name.length(), replacement); final Symbol.VarSymbol sym = getSymbol(tree); ((JCTree) state.getPath().getCompilationUnit()) .accept( new TreeScanner() { @Override public void visitIdent(JCTree.JCIdent tree) { if (sym.equals(getSymbol(tree))) { fix.replace(tree, replacement); } } }); return fix.build(); }
@Override public Description matchVariable(VariableTree varTree, VisitorState state) { Name varName = varTree.getName(); Matcher<VariableTree> nameSameAsType = Matchers.variableType( (typeTree, s) -> { Symbol typeSymbol = ASTHelpers.getSymbol(typeTree); if (typeSymbol != null) { return typeSymbol.getSimpleName().contentEquals(varName); } return false; }); if (!nameSameAsType.matches(varTree, state)) { return Description.NO_MATCH; } String message = String.format( "Variable named %s has the type %s. Calling methods using \"%s.something\" are " + "difficult to distinguish between static and instance methods.", varName, varTree.getType(), varName); return buildDescription(varTree).setMessage(message).build(); } }
@Override public Choice<Unifier> visitVariable(final VariableTree decl, Unifier unifier) { return Choice.condition(unifier.getBinding(key()) == null, unifier) .thenChoose(unifications(getType(), decl.getType())) .thenChoose(unifications(getInitializer(), decl.getInitializer())) .transform( new Function<Unifier, Unifier>() { @Override public Unifier apply(Unifier unifier) { unifier.putBinding( key(), LocalVarBinding.create(ASTHelpers.getSymbol(decl), decl.getModifiers())); return unifier; } }); }
/** * If the left operand of an int binary expression is an int literal, suggest making it a long. */ private Fix longFix(ExpressionTree expr, VisitorState state) { BinaryTree binExpr = null; while (expr instanceof BinaryTree) { binExpr = (BinaryTree) expr; expr = binExpr.getLeftOperand(); } if (!(expr instanceof LiteralTree) || expr.getKind() != Kind.INT_LITERAL) { return null; } Type intType = state.getSymtab().intType; if (!isSameType(getType(binExpr), intType, state)) { return null; } SuggestedFix.Builder fix = SuggestedFix.builder().postfixWith(expr, "L"); Tree parent = state.getPath().getParentPath().getLeaf(); if (parent instanceof VariableTree && isSameType(getType(parent), intType, state)) { fix.replace(((VariableTree) parent).getType(), "long"); } return fix.build(); }
Tree lhsTree = tree.getType(); Type lhsType = ASTHelpers.getType(lhsTree); if (lhsType == null || ImmutableCollections.isImmutableType(lhsType)) {