private static boolean typeIsBoolean(Type type) { return type.getTag() == TypeTag.BOOLEAN; }
/** Returns true if {@code erasure(s) <: erasure(t)}. */ public static boolean isSubtype(Type s, Type t, VisitorState state) { if (s == null || t == null) { return false; } if (SUBTYPE_UNDEFINED.contains(s.getTag()) || SUBTYPE_UNDEFINED.contains(t.getTag())) { return false; } Types types = state.getTypes(); return types.isSubtype(types.erasure(s), types.erasure(t)); }
/** * Implementation of unary numeric promotion rules. * * <p><a href="https://docs.oracle.com/javase/specs/jls/se9/html/jls-5.html#jls-5.6.1">JLS * §5.6.1</a> */ @Nullable private static Type unaryNumericPromotion(Type type, VisitorState state) { Type unboxed = unboxAndEnsureNumeric(type, state); switch (unboxed.getTag()) { case BYTE: case SHORT: case CHAR: return state.getSymtab().intType; case INT: case LONG: case FLOAT: case DOUBLE: return unboxed; default: throw new AssertionError("Should not reach here: " + type); } }
/** * Implementation of binary numeric promotion rules. * * <p><a href="https://docs.oracle.com/javase/specs/jls/se9/html/jls-5.html#jls-5.6.2">JLS * §5.6.2</a> */ @Nullable private static Type binaryNumericPromotion(Type leftType, Type rightType, VisitorState state) { Type unboxedLeft = unboxAndEnsureNumeric(leftType, state); Type unboxedRight = unboxAndEnsureNumeric(rightType, state); Set<TypeTag> tags = EnumSet.of(unboxedLeft.getTag(), unboxedRight.getTag()); if (tags.contains(TypeTag.DOUBLE)) { return state.getSymtab().doubleType; } else if (tags.contains(TypeTag.FLOAT)) { return state.getSymtab().floatType; } else if (tags.contains(TypeTag.LONG)) { return state.getSymtab().longType; } else { return state.getSymtab().intType; } }
private String castArgumentIfNecessary(ExpressionTree tree, VisitorState state) { String source = state.getSourceForNode(tree); Type type = ASTHelpers.getType(tree); if (state.getTypes().unboxedTypeOrType(type).getTag() == typeTag) { return source; } if (tree instanceof LiteralTree) { Optional<String> suffixed = suffixLiteralIfPossible((LiteralTree) tree, state); if (suffixed.isPresent()) { return suffixed.get(); } } if (ASTHelpers.requiresParentheses(tree, state)) { return String.format("(%s) (%s)", typeName, source); } return String.format("(%s) %s", typeName, source); }
private boolean booleanReturnType(MethodInvocationNode node) { Symbol.MethodSymbol methodSymbol = ASTHelpers.getSymbol(node.getTree()); return methodSymbol != null && methodSymbol.getReturnType().getTag() == TypeTag.BOOLEAN; }
/** * Matches if this is a narrowing integral cast between signed types where the expression is a * subtract. */ private boolean matches(TypeCastTree tree, VisitorState state) { Type treeType = ASTHelpers.getType(tree.getType()); // If the cast isn't narrowing to an int then don't implicate it in the bug pattern. if (treeType.getTag() != TypeTag.INT) { return false; } // The expression should be a subtract but remove parentheses. ExpressionTree expression = ASTHelpers.stripParentheses(tree.getExpression()); if (expression.getKind() != Kind.MINUS) { return false; } // Ensure the expression type is wider and signed (ie a long) than the cast type ignoring // boxing. Type expressionType = getTypeOfSubtract((BinaryTree) expression, state); TypeTag expressionTypeTag = state.getTypes().unboxedTypeOrType(expressionType).getTag(); return (expressionTypeTag == TypeTag.LONG); }
@Override public boolean matches(ExpressionTree tree, VisitorState state) { Types types = state.getTypes(); Type classType = state.getSymtab().classType; Type runtimeExceptionType = state.getSymtab().runtimeExceptionType; Type argType = getType(tree); // Make sure that the argument is a Class<Something> (and not null/bottom). if (!isSubtype(argType, classType, state) || argType.getTag() == BOT) { return false; } List<Type> typeArguments = ((ClassType) argType).getTypeArguments(); Type exceptionType = Iterables.getFirst(typeArguments, null); return types.isSubtype(exceptionType, runtimeExceptionType); } };
return; if (state.getTypes().unboxedTypeOrType(paramSym.type).getTag() != TypeTag.BOOLEAN) {
if (target.type.getTag() != TypeTag.VOID) { expectedTypes = expectedTypes.prepend(returnType().inline(inliner)); Type ty = target.type; Type trueTy = cond.truepart.type; Type falseTy = cond.falsepart.type; if (trueTy.getTag() == TypeTag.BOT) { ty = falseTy; } else if (falseTy.getTag() == TypeTag.BOT) { ty = trueTy; } else {
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 boolean matches(ExpressionTree expressionTree, VisitorState state) { if (expressionTree instanceof JCFieldAccess) { Symbol symbol = ASTHelpers.getSymbol(expressionTree); if (symbol.isStatic() && state.getTypes().unboxedTypeOrType(symbol.type).getTag() == TypeTag.BOOLEAN) { return ((value && symbol.getSimpleName().contentEquals("TRUE")) || symbol.getSimpleName().contentEquals("FALSE")); } } return false; } };
return types.unboxedTypeOrType(variableType).getTag() == TypeTag.BOOLEAN ? state.getSymtab().booleanType : binaryNumericPromotion(variableType, expressionType, state);
/** * Checks if the current type tag is equal to the given tag. * @return true if tag is equal to the current type tag. */ public boolean hasTag(TypeTag tag) { return tag == getTag(); }
@Override public TypeTag getTag() { return underlyingType.getTag(); }
return false; if (assignedType.getTag() == TypeTag.CHAR && expression.type.getTag() != TypeTag.CHAR) { print("String.fromCharCode(").print(expression).print(")"); return true; } else if (Util.isNumber(assignedType) && expression.type.getTag() == TypeTag.CHAR) { print("(").print(expression).print(").charCodeAt(0)"); return true; } else if (singlePrecisionFloats() && assignedType.getTag() == TypeTag.FLOAT && expression.type.getTag() == TypeTag.DOUBLE) { print("(<any>Math).fround(").print(expression).print(")"); return true;
/** * Return the class that boxes the given primitive. */ public ClassSymbol boxedClass(Type t) { return reader.enterClass(syms.boxedName[t.getTag().ordinal()]); }
/** * Return the class that boxes the given primitive. */ public ClassSymbol boxedClass(Type t) { return reader.enterClass(syms.boxedName[t.getTag().ordinal()]); }
print(" : any"); } else { if (methodDecl.restype != null && methodDecl.restype.type.getTag() != TypeTag.VOID) { print(" : "); substituteAndPrintType(methodDecl.restype);