@Override public ImmutableSet<Integer> onUnannotatedInvocationGetExplicitlyNullablePositions( Context context, Symbol.MethodSymbol methodSymbol, ImmutableSet<Integer> explicitlyNullablePositions) { HashSet<Integer> positions = new HashSet<Integer>(); positions.addAll(explicitlyNullablePositions); for (int i = 0; i < methodSymbol.getParameters().size(); ++i) { if (Nullness.paramHasNullableAnnotation(methodSymbol, i)) { positions.add(i); } } return ImmutableSet.copyOf(positions); }
@Override public ImmutableSet<Integer> onUnannotatedInvocationGetNonNullPositions( NullAway analysis, VisitorState state, Symbol.MethodSymbol methodSymbol, List<? extends ExpressionTree> actualParams, ImmutableSet<Integer> nonNullPositions) { HashSet<Integer> positions = new HashSet<Integer>(); positions.addAll(nonNullPositions); for (int i = 0; i < methodSymbol.getParameters().size(); ++i) { if (Nullness.paramHasNonNullAnnotation(methodSymbol, i)) { positions.add(i); } } return ImmutableSet.copyOf(positions); }
@Nullable private Type visitMethodInvocationOrNewClass( List<? extends ExpressionTree> arguments, MethodSymbol sym, Type type) { int idx = arguments.indexOf(current); if (idx == -1) { return null; } if (type.getParameterTypes().size() <= idx) { if (!sym.isVarArgs()) { if ((sym.flags() & Flags.HYPOTHETICAL) != 0) { // HYPOTHETICAL is also used for signature-polymorphic methods return null; } throw new IllegalStateException( String.format( "saw %d formal parameters and %d actual parameters on non-varargs method %s\n", type.getParameterTypes().size(), arguments.size(), sym)); } idx = type.getParameterTypes().size() - 1; } Type argType = type.getParameterTypes().get(idx); if (sym.isVarArgs() && idx == type.getParameterTypes().size() - 1) { argType = state.getTypes().elemtype(argType); } return argType; }
private static int caseEndPosition(VisitorState state, JCTree.JCCase caseTree) { // if the statement group is a single block statement, handle fall through comments at the // end of the block if (caseTree.stats.size() == 1) { JCTree.JCStatement only = getOnlyElement(caseTree.stats); if (only.hasTag(JCTree.Tag.BLOCK)) { BlockTree blockTree = (BlockTree) only; return blockTree.getStatements().isEmpty() ? ((JCTree) blockTree).getStartPosition() : state.getEndPosition(getLast(blockTree.getStatements())); } } return state.getEndPosition(caseTree); } }
/** * Extracts the appropriate type argument from a specific supertype of the given {@code type}. * This handles the case when a subtype has different type arguments than the expected type. For * example, {@code ClassToInstanceMap<T>} implements {@code Map<Class<? extends T>, T>}. * * @param type the (sub)type from which to extract the type argument * @param superTypeSym the symbol of the supertype on which the type parameter is defined * @param typeArgIndex the index of the type argument to extract from the supertype * @param types the {@link Types} utility class from the {@link VisitorState} * @return the type argument, if defined, or null otherwise */ @Nullable protected static final Type extractTypeArgAsMemberOfSupertype( Type type, Symbol superTypeSym, int typeArgIndex, Types types) { Type collectionType = types.asSuper(type, superTypeSym); if (collectionType == null) { return null; } com.sun.tools.javac.util.List<Type> tyargs = collectionType.getTypeArguments(); if (tyargs.size() <= typeArgIndex) { // Collection is raw, nothing we can do. return null; } return tyargs.get(typeArgIndex); } }
@Override public Type get(VisitorState state) { Type type = typeSupplier.get(state); if (type.getTypeArguments().size() <= n) { return state.getSymtab().objectType; } return type.getTypeArguments().get(n); } };
@Override public Type get(VisitorState state) { JCExpression jcExpression = (JCExpression) expressionSupplier.get(state); if (jcExpression.type.getTypeArguments().size() <= n) { return state.getSymtab().objectType; } return jcExpression.type.getTypeArguments().get(n); } };
for (int i = 0; i < sym.getParameters().size(); ++i) { VarSymbol param = sym.getParameters().get(i); if (param.equals(sym.getParameters().last()) && sym.isVarArgs()) {
@Override public Description matchMethodInvocation( MethodInvocationTree methodInvocationTree, VisitorState state) { if (!MATCHER.matches(methodInvocationTree, state)) { return Description.NO_MATCH; } if (methodInvocationTree.getArguments().size() % 2 == 0) { return Description.NO_MATCH; } List<? extends ExpressionTree> arguments = methodInvocationTree.getArguments(); MethodSymbol methodSymbol = getSymbol(methodInvocationTree); if (methodSymbol == null || !methodSymbol.isVarArgs()) { return Description.NO_MATCH; } Type varArgsArrayType = getLast(methodSymbol.params()).type; Type lastArgType = ASTHelpers.getType(getLast(arguments)); if (arguments.size() == methodSymbol.params().size() && ASTHelpers.isSameType(varArgsArrayType, lastArgType, state)) { return Description.NO_MATCH; } return describeMatch(methodInvocationTree); } }
@Override public boolean matches(ExpressionTree t, VisitorState state) { Type type = ((JCTree) t).type; // Expect a class type. if (!(type instanceof ClassType)) { return false; } // Expect one type argument, the type of the JUnit class runner to use. com.sun.tools.javac.util.List<Type> typeArgs = ((ClassType) type).getTypeArguments(); if (typeArgs.size() != 1) { return false; } Type runnerType = typeArgs.get(0); for (String testRunner : TEST_RUNNERS) { Symbol parent = state.getSymbolFromString(testRunner); if (parent == null) { continue; } if (runnerType.tsym.isSubClass(parent, state.getTypes())) { return true; } } return false; } };
private Description check(Tree tree, List<? extends Tree> arguments, VisitorState state) { Symbol sym = ASTHelpers.getSymbol(tree); if (!(sym instanceof MethodSymbol)) { return Description.NO_MATCH; } MethodSymbol methodSymbol = (MethodSymbol) sym; int expected = methodSymbol.getTypeParameters().size(); int actual = arguments.size(); if (actual <= expected) { return Description.NO_MATCH; } for (MethodSymbol superMethod : ASTHelpers.findSuperMethods(methodSymbol, state.getTypes())) { if (!superMethod.getTypeParameters().isEmpty()) { // Exempt methods that override generic methods to preserve the substitutability of the // two types. return Description.NO_MATCH; } } return describeMatch(tree, buildFix(tree, arguments, state)); }
@Override public boolean apply(MethodSymbol methodSymbol) { return !methodSymbol.isStatic() && ((methodSymbol.flags() & Flags.SYNTHETIC) == 0) && ((methodSymbol.flags() & Flags.ABSTRACT) == 0) && methodSymbol.getParameters().size() == 1 && types.isSameType( methodSymbol.getParameters().get(0).type, state.getSymtab().objectType); } };
@Override public Description matchMethod(MethodTree node, VisitorState state) { Symbol.MethodSymbol method = ASTHelpers.getSymbol(node); if (method == null) { return Description.NO_MATCH; } List<Integer> compileTimeConstantAnnotationIndexes = new ArrayList<>(); for (int i = 0; i < method.getParameters().size(); i++) { if (hasCompileTimeConstantAnnotation(state, method.getParameters().get(i))) { compileTimeConstantAnnotationIndexes.add(i); } } if (compileTimeConstantAnnotationIndexes.isEmpty()) { return Description.NO_MATCH; } for (Symbol.MethodSymbol superMethod : ASTHelpers.findSuperMethods(method, state.getTypes())) { for (Integer index : compileTimeConstantAnnotationIndexes) { if (!hasCompileTimeConstantAnnotation(state, superMethod.getParameters().get(index))) { return buildDescription(node) .setMessage( "Method with @CompileTimeConstant parameter can't override method without it.") .build(); } } } return Description.NO_MATCH; }
try { boolean exactlyOneParamWithNoType = lambda.params.size() == 1 && lambda.params.get(0).vartype == null; if (!exactlyOneParamWithNoType) { print("(");
public Description describe(MethodTree tree, VisitorState state) { SuggestedFix.Builder builder = null; MethodSymbol method = ASTHelpers.getSymbol(tree); if (supermethod == null) { throw new IllegalStateException("Matching supermethod was not found"); } for (int x = 0; x < method.params().size(); x++) { Type methodParamType = method.params().get(x).type; Type supermethodParamType = supermethod.params().get(x).type; if (methodParamType.tsym.name.contentEquals(supermethodParamType.tsym.name) && !state.getTypes().isSameType(methodParamType, supermethodParamType)) { VariableTree param = tree.getParameters().get(x); // TODO(user): Name is most likely more qualified than necessary. Name replacement = supermethodParamType.tsym.getQualifiedName(); if (builder == null) { builder = SuggestedFix.builder(); } builder.replace(param, replacement + " " + param.getName()); } } return (builder != null) ? describeMatch(tree, builder.build()) : describeMatch(tree); } }
JCTree inlineBody(Inliner inliner) throws CouldNotResolveImportException { if (getBody() instanceof UPlaceholderExpression) { UPlaceholderExpression body = (UPlaceholderExpression) getBody(); Optional<List<JCStatement>> blockBinding = inliner.getOptionalBinding(body.placeholder().blockKey()); if (blockBinding.isPresent()) { // this lambda is of the form args -> blockPlaceholder(); List<JCStatement> blockInlined = UPlaceholderExpression.copier(body.arguments(), inliner) .copy(blockBinding.get(), inliner); if (blockInlined.size() == 1) { if (blockInlined.get(0) instanceof JCReturn) { return ((JCReturn) blockInlined.get(0)).getExpression(); } else if (blockInlined.get(0) instanceof JCExpressionStatement) { return ((JCExpressionStatement) blockInlined.get(0)).getExpression(); } } return inliner.maker().Block(0, blockInlined); } } return getBody().inline(inliner); }
/** * Searches the annotation list for {@code @Test(expected=...)}. If found, deletes the exception * attribute from the annotation, and returns its value. */ private static JCExpression deleteExpectedException( SuggestedFix.Builder fix, List<JCAnnotation> annotations, VisitorState state) { Type testAnnotation = state.getTypeFromString(JUnitMatchers.JUNIT4_TEST_ANNOTATION); for (JCAnnotation annotationTree : annotations) { if (!ASTHelpers.isSameType(testAnnotation, annotationTree.type, state)) { continue; } com.sun.tools.javac.util.List<JCExpression> arguments = annotationTree.getArguments(); for (JCExpression arg : arguments) { if (!arg.hasTag(Tag.ASSIGN)) { continue; } JCAssign assign = (JCAssign) arg; if (assign.lhs.hasTag(Tag.IDENT) && ((JCIdent) assign.lhs).getName().contentEquals("expected")) { if (arguments.size() == 1) { fix.replace(annotationTree, "@Test"); } else { removeFromList(fix, state, arguments, assign); } return assign.rhs; } } } return null; }
if (genericsArgument.getTypeArguments().size() != 2) { return emptyFix();
return NO_MATCH; if (tree.getArguments().size() != sym.getParameters().size()) {
static Type getTargetType(VisitorState state) { Tree parent = state.getPath().getParentPath().getLeaf(); Type type; if (parent instanceof VariableTree || parent instanceof AssignmentTree) { type = ASTHelpers.getType(parent); } else if (parent instanceof ReturnTree || parent instanceof LambdaExpressionTree) { type = getMethodOrLambdaReturnType(state); } else if (parent instanceof MethodInvocationTree) { MethodInvocationTree tree = (MethodInvocationTree) parent; int idx = tree.getArguments().indexOf(state.getPath().getLeaf()); if (idx == -1) { return null; } Type methodType = ASTHelpers.getType(tree.getMethodSelect()); if (idx >= methodType.getParameterTypes().size()) { return null; } return methodType.getParameterTypes().get(idx); } else { return null; } Tree tree = state.getPath().getLeaf(); if (tree instanceof MemberReferenceTree) { type = state.getTypes().findDescriptorType(ASTHelpers.getType(tree)).getReturnType(); } return type; }