public boolean isPrimitive() { return symbol.type.isPrimitive(); }
@Override public Choice<Unifier> visitType(Type target, Unifier unifier) { // This is only called when we're trying to unify overloads, in which case // type variables don't matter. return Choice.condition(!target.isPrimitive(), unifier); }
@Override public boolean matches(Tree t, VisitorState state) { Type type = getType(t); return type != null && type.isPrimitive(); } };
@Override public Description matchBinary(BinaryTree tree, VisitorState state) { if (!matchWithinClass) { return Description.NO_MATCH; } ExpressionTree leftOperand = tree.getLeftOperand(); ExpressionTree rightOperand = tree.getRightOperand(); Type leftType = ASTHelpers.getType(leftOperand); Type rightType = ASTHelpers.getType(rightOperand); if (leftType == null || rightType == null) { throw new RuntimeException(); } if (leftType.isPrimitive() && !rightType.isPrimitive()) { return doUnboxingCheck(state, rightOperand); } if (rightType.isPrimitive() && !leftType.isPrimitive()) { return doUnboxingCheck(state, leftOperand); } return Description.NO_MATCH; }
/** * Determines if the invocation can be safely converted to JUnit 4 based on its argument types. */ private boolean canBeConvertedToJUnit4(VisitorState state, List<Type> argumentTypes) { // Delta argument is used. if (argumentTypes.size() > 2) { return true; } Type firstType = argumentTypes.get(0); Type secondType = argumentTypes.get(1); // Neither argument is floating-point. if (!isFloatingPoint(state, firstType) && !isFloatingPoint(state, secondType)) { return true; } // One argument is not numeric. if (!isNumeric(state, firstType) || !isNumeric(state, secondType)) { return true; } // Neither argument is primitive. if (!firstType.isPrimitive() && !secondType.isPrimitive()) { return true; } return false; }
/** Classifies bad casts. */ private static String identifyBadCast(Type lhs, Type rhs, Types types) { if (!lhs.isPrimitive()) { return null; } if (types.isConvertible(rhs, lhs)) { // Exemption if the rhs is convertible to the lhs. // This allows, e.g.: <byte> &= <byte> since the narrowing conversion can never be // detected. // This also allows, for example, char += char, which could overflow, but this is no // different than any other integral addition. return null; } return String.format( "Compound assignments from %s to %s hide lossy casts", prettyType(rhs), prettyType(lhs)); }
@Override public boolean matches(Tree t, VisitorState state) { Type type = getType(t); return type != null && state.getTypes().unboxedTypeOrType(type).isPrimitive(); } };
private Description check(Type type, List<? extends AnnotationTree> annotations) { if (type == null) { return NO_MATCH; } if (!type.isPrimitive()) { return NO_MATCH; } AnnotationTree annotation = ASTHelpers.getAnnotationWithSimpleName(annotations, "Nullable"); if (annotation == null) { return NO_MATCH; } return describeMatch(annotation, SuggestedFix.delete(annotation)); } }
/** * if any expression has non-primitive type, we should check that it can't be null as it is * getting unboxed * * @param expressions expressions to check * @return error Description if an error is found, otherwise NO_MATCH */ private Description doUnboxingCheck(VisitorState state, ExpressionTree... expressions) { for (ExpressionTree tree : expressions) { Type type = ASTHelpers.getType(tree); if (type == null) { throw new RuntimeException("was not expecting null type"); } if (!type.isPrimitive()) { if (mayBeNullExpr(state, tree)) { return createErrorDescription( MessageTypes.UNBOX_NULLABLE, tree, "unboxing of a @Nullable value", state.getPath()); } } } return Description.NO_MATCH; }
@Override public boolean matches(Tree t, VisitorState state) { Type type = getType(t); return type != null && state.getTypes().isArray(type) && state.getTypes().elemtype(type).isPrimitive(); } };
private Description matchDereference( ExpressionTree baseExpression, ExpressionTree derefExpression, VisitorState state) { Symbol dereferenced = ASTHelpers.getSymbol(baseExpression); if (dereferenced == null || dereferenced.type.isPrimitive() || !kindMayDeferenceNull(dereferenced.getKind())) { // we know we don't have a null dereference here return Description.NO_MATCH; } if (mayBeNullExpr(state, baseExpression)) { String message = "dereferenced expression " + baseExpression.toString() + " is @Nullable"; return createErrorDescriptionForNullAssignment( MessageTypes.DEREFERENCE_NULLABLE, derefExpression, message, baseExpression, state.getPath()); } return Description.NO_MATCH; }
ConditionalExpressionTree conditionalExpression, VisitorState state) { Type expressionType = checkNotNull(ASTHelpers.getType(conditionalExpression)); if (!expressionType.isPrimitive()) { return NO_MATCH; if (trueType.isPrimitive() || falseType.isPrimitive()) { return NO_MATCH; return NO_MATCH; if (targetType.type().isPrimitive()) { return NO_MATCH;
static ClassAndMethod make(MethodSymbol methodSymbol, @Nullable Types types) { // TODO(b/71812955): consider just wrapping methodSymbol instead of copying everything out. ImmutableList<String> annotations = MoreAnnotations.getDeclarationAndTypeAttributes(methodSymbol) .map(Object::toString) .collect(toImmutableList()); ClassSymbol clazzSymbol = (ClassSymbol) methodSymbol.owner; return new ClassAndMethod( clazzSymbol.getQualifiedName().toString(), methodSymbol.getSimpleName().toString(), annotations, methodSymbol.isStatic(), methodSymbol.getReturnType().isPrimitive(), methodSymbol.getReturnType().getTag() == BOOLEAN, hasGenericResult(methodSymbol), knownNonNullMethod(methodSymbol, clazzSymbol, types)); }
@Override public Description matchConditionalExpression( ConditionalExpressionTree conditionalExpression, VisitorState state) { if (conditionalExpression.getFalseExpression().getKind() != Kind.NULL_LITERAL && conditionalExpression.getTrueExpression().getKind() != Kind.NULL_LITERAL) { return NO_MATCH; } ASTHelpers.TargetType targetType = ASTHelpers.targetType(state); if (targetType == null || !targetType.type().isPrimitive()) { return NO_MATCH; } return describeMatch(conditionalExpression); } }
@Override public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState state) { if (!ARRAYS_AS_LIST_SINGLE_ARRAY.matches(tree, state)) { return NO_MATCH; } ExpressionTree array = Iterables.getOnlyElement(tree.getArguments()); Type componentType = ((ArrayType) ASTHelpers.getType(array)).getComponentType(); if (!componentType.isPrimitive()) { return NO_MATCH; } String guavaUtils = GUAVA_UTILS.get(componentType.getKind()); if (guavaUtils == null) { return NO_MATCH; } Fix fix = SuggestedFix.builder() .addImport("com.google.common.primitives." + guavaUtils) .replace(tree.getMethodSelect(), guavaUtils + ".asList") .build(); return describeMatch(tree, fix); } }
private Description checkReturnExpression( Tree tree, ExpressionTree retExpr, Symbol.MethodSymbol methodSymbol, VisitorState state) { Type returnType = methodSymbol.getReturnType(); if (returnType.isPrimitive()) { // check for unboxing return doUnboxingCheck(state, retExpr); } if (returnType.toString().equals("java.lang.Void")) { return Description.NO_MATCH; } if (NullabilityUtil.isUnannotated(methodSymbol, config) || Nullness.hasNullableAnnotation(methodSymbol)) { return Description.NO_MATCH; } if (mayBeNullExpr(state, retExpr)) { String message = "returning @Nullable expression from method with @NonNull return type"; return createErrorDescriptionForNullAssignment( MessageTypes.RETURN_NULLABLE, tree, message, retExpr, state.getPath()); } return Description.NO_MATCH; }
private Description checkImmutable( VariableTree tree, VisitorState state, VarSymbol sym, String name) { Type type = sym.type; if (type == null) { return Description.NO_MATCH; } switch (name) { case "serialVersionUID": // mandated by the Serializable API return Description.NO_MATCH; default: break; } if (Ascii.toUpperCase(name).equals(name)) { return Description.NO_MATCH; } if (state.getTypes().unboxedTypeOrType(type).isPrimitive() || ASTHelpers.isSameType(type, state.getSymtab().stringType, state) || type.tsym.getKind() == ElementKind.ENUM) { String constName = upperCaseReplace(name); return buildDescription(tree) .setMessage( String.format( "%ss are immutable, field should be named '%s'", sym.type.tsym.getSimpleName(), constName)) .addFix(SuggestedFixes.renameVariable(tree, constName, state)) .build(); } return Description.NO_MATCH; }
if (assigned == null || assigned.getKind() != ElementKind.FIELD || assigned.type.isPrimitive()) { return Description.NO_MATCH; // not a field of nullable type
@Override public Description matchAssignment(AssignmentTree tree, VisitorState state) { if (!matchWithinClass) { return Description.NO_MATCH; } Type lhsType = ASTHelpers.getType(tree.getVariable()); if (lhsType != null && lhsType.isPrimitive()) { return doUnboxingCheck(state, tree.getExpression()); } Symbol assigned = ASTHelpers.getSymbol(tree.getVariable()); if (assigned == null || assigned.getKind() != ElementKind.FIELD) { // not a field of nullable type return Description.NO_MATCH; } if (Nullness.hasNullableAnnotation(assigned)) { // field already annotated return Description.NO_MATCH; } ExpressionTree expression = tree.getExpression(); if (mayBeNullExpr(state, expression)) { String message = "assigning @Nullable expression to @NonNull field"; return createErrorDescriptionForNullAssignment( MessageTypes.ASSIGN_FIELD_NULLABLE, tree, message, expression, state.getPath()); } return Description.NO_MATCH; }
|| !types.elemtype(varargsArgumentType).isPrimitive()) { return false;