@Override public boolean test(Type arg1, Type arg2) { boolean hasStringOp = types.isSameType(arg1, syms.stringType) || types.isSameType(arg2, syms.stringType); boolean hasVoidOp = arg1.hasTag(TypeTag.VOID) || arg2.hasTag(TypeTag.VOID); return hasStringOp && !hasVoidOp; }
/** * This routine applies following mappings: - if input type is primitive, apply numeric * promotion - if input type is either 'void', 'null' or 'String' leave it untouched - otherwise * return 'Object' */ private Type stringPromotion(Type t) { if (t.isPrimitive()) { return unaryPromotion(t); } else if (t.hasTag(TypeTag.VOID) || t.hasTag(TypeTag.BOT) || types.isSameType(t, syms.stringType)) { return t; } else if (t.hasTag(TypeTag.TYPEVAR)) { return stringPromotion(t.getUpperBound()); } else { return syms.objectType; } }
/** * Returns the upper bound of a type if it has one, or the type itself if not. Correctly handles * wildcards and capture variables. */ public static Type getUpperBound(Type type, Types types) { if (type.hasTag(TypeTag.WILDCARD)) { return types.wildUpperBound(type); } if (type.hasTag(TypeTag.TYPEVAR) && ((TypeVar) type).isCaptured()) { return types.cvarUpperBound(type); } if (type.getUpperBound() != null) { return type.getUpperBound(); } // concrete type, e.g. java.lang.String, or a case we haven't considered return type; }
/** * Perform binary promotion of a pair of types; this routine implements JLS 5.6.2. If the input * types are not supported by unary promotion, if such types are identical to a type C, then C is * returned, otherwise Object is returned. */ Type binaryPromotion(Type t1, Type t2) { Type unboxedT1 = types.unboxedTypeOrType(t1); Type unboxedT2 = types.unboxedTypeOrType(t2); if (unboxedT1.isNumeric() && unboxedT2.isNumeric()) { if (unboxedT1.hasTag(TypeTag.DOUBLE) || unboxedT2.hasTag(TypeTag.DOUBLE)) { return syms.doubleType; } else if (unboxedT1.hasTag(TypeTag.FLOAT) || unboxedT2.hasTag(TypeTag.FLOAT)) { return syms.floatType; } else if (unboxedT1.hasTag(TypeTag.LONG) || unboxedT2.hasTag(TypeTag.LONG)) { return syms.longType; } else { return syms.intType; } } else if (types.isSameType(unboxedT1, unboxedT2)) { return unboxedT1; } else { return syms.objectType; } }