/** * Checks if the last argument matches the vararg type. * * @param params * @param args * @return -1 if no match, 0 if the last argument is exactly the vararg type and 1 if of an assignable type */ static int lastArgMatchesVarg(Parameter[] params, ClassNode... args) { if (!isVargs(params)) return -1; // case length ==0 handled already // we have now two cases, // the argument is wrapped in the vargs array or // the argument is an array that can be used for the vargs part directly // we test only the wrapping part, since the non wrapping is done already ClassNode lastParamType = params[params.length - 1].getType(); ClassNode ptype = lastParamType.getComponentType(); ClassNode arg = args[args.length - 1]; if (isNumberType(ptype) && isNumberType(arg) && !ptype.equals(arg)) return -1; return isAssignableTo(arg, ptype) ? min(getDistance(arg, lastParamType), getDistance(arg, ptype)) : -1; }
if (isNumberType(a.redirect()) && isNumberType(b.redirect())) { ClassNode ua = getUnwrapper(a); ClassNode ub = getUnwrapper(b);
private void addPrecisionErrors(ClassNode leftRedirect, ClassNode lhsType, ClassNode inferredrhsType, Expression rightExpression) { if (isNumberType(leftRedirect) && isNumberType(inferredrhsType)) { if (checkPossibleLossOfPrecision(leftRedirect, inferredrhsType, rightExpression)) { addStaticTypeError("Possible loss of precision from " + inferredrhsType + " to " + leftRedirect, rightExpression); return; } } // if left type is array, we should check the right component types if (!lhsType.isArray()) return; ClassNode leftComponentType = lhsType.getComponentType(); ClassNode rightRedirect = rightExpression.getType().redirect(); if (rightRedirect.isArray()) { ClassNode rightComponentType = rightRedirect.getComponentType(); if (!checkCompatibleAssignmentTypes(leftComponentType, rightComponentType)) { addStaticTypeError("Cannot assign value of type " + rightComponentType.toString(false) + " into array of type " + lhsType.toString(false), rightExpression); } } else if (rightExpression instanceof ListExpression) { for (Expression element : ((ListExpression) rightExpression).getExpressions()) { ClassNode rightComponentType = this.getType(element); if (!checkCompatibleAssignmentTypes(leftComponentType, rightComponentType) && !(isNullConstant(element) && !isPrimitiveType(leftComponentType))) { addStaticTypeError("Cannot assign value of type " + rightComponentType.toString(false) + " into array of type " + lhsType.toString(false), rightExpression); } } } }
@Override protected void writePostOrPrefixMethod(int op, String method, Expression expression, Expression orig) { MethodNode mn = orig.getNodeMetaData(StaticTypesMarker.DIRECT_METHOD_CALL_TARGET); WriterController controller = getController(); OperandStack operandStack = controller.getOperandStack(); if (mn!=null) { operandStack.pop(); MethodCallExpression call = new MethodCallExpression( expression, method, ArgumentListExpression.EMPTY_ARGUMENTS ); call.setMethodTarget(mn); call.visit(controller.getAcg()); return; } ClassNode top = operandStack.getTopOperand(); if (ClassHelper.isPrimitiveType(top) && (ClassHelper.isNumberType(top)||char_TYPE.equals(top))) { MethodVisitor mv = controller.getMethodVisitor(); visitInsnByType(top, mv, ICONST_1, LCONST_1, FCONST_1, DCONST_1); if ("next".equals(method)) { visitInsnByType(top, mv, IADD, LADD, FADD, DADD); } else { visitInsnByType(top, mv, ISUB, LSUB, FSUB, DSUB); } return; } super.writePostOrPrefixMethod(op, method, expression, orig); }
protected boolean checkCast(final ClassNode targetType, final Expression source) { boolean sourceIsNull = isNullConstant(source); ClassNode expressionType = getType(source); if (targetType.isArray() && expressionType.isArray()) { return checkCast(targetType.getComponentType(), varX("foo", expressionType.getComponentType())); } else if (targetType.equals(char_TYPE) && expressionType == STRING_TYPE && source instanceof ConstantExpression && source.getText().length() == 1) { // ex: (char) 'c' } else if (targetType.equals(Character_TYPE) && (expressionType == STRING_TYPE || sourceIsNull) && (sourceIsNull || source instanceof ConstantExpression && source.getText().length() == 1)) { // ex : (Character) 'c' } else if (isNumberCategory(getWrapper(targetType)) && (isNumberCategory(getWrapper(expressionType)) || char_TYPE == expressionType)) { // ex: short s = (short) 0 } else if (sourceIsNull && !isPrimitiveType(targetType)) { // ex: (Date)null } else if (char_TYPE == targetType && isPrimitiveType(expressionType) && isNumberType(expressionType)) { // char c = (char) ... } else if (sourceIsNull && isPrimitiveType(targetType) && !boolean_TYPE.equals(targetType)) { return false; } else if ((expressionType.getModifiers() & Opcodes.ACC_FINAL) == 0 && targetType.isInterface()) { return true; } else if ((targetType.getModifiers() & Opcodes.ACC_FINAL) == 0 && expressionType.isInterface()) { return true; } else if (!isAssignableTo(targetType, expressionType) && !implementsInterfaceOrIsSubclassOf(expressionType, targetType)) { return false; } return true; }
if ((isNumberType(rightRedirect) || WideningCategories.isNumberCategory(rightRedirect))) { if (BigDecimal_TYPE == leftRedirect) { if (isNumberType(leftRedirect) && isNumberType(rightRedirect)) return true;
if (NUMBER_OPS.containsKey(name) && isNumberType(receiver) && argumentList.getExpressions().size() == 1 && isNumberType(getType(argumentList.getExpression(0)))) { ClassNode right = getType(argumentList.getExpression(0)); ClassNode resultType = getMathResultType(NUMBER_OPS.get(name), receiver, right, name);
private ClassNode getMathResultType(int op, ClassNode leftRedirect, ClassNode rightRedirect, String operationName) { if (isNumberType(leftRedirect) && isNumberType(rightRedirect)) { if (isOperationInGroup(op)) { if (isIntCategory(leftRedirect) && isIntCategory(rightRedirect)) return int_TYPE;
private void improveExprType(Expression expr) { if (expr instanceof BinaryExpression) { if (ClassHelper.isNumberType(expr.getType())) return; ClassNode type2 = getLHSType(bin.getRightExpression()); if (ClassHelper.isNumberType(type1) && ClassHelper.isNumberType(type2)) { ClassNode prim1 = ClassHelper.getUnwrapper(type1); ClassNode prim2 = ClassHelper.getUnwrapper(type2);
if (a == b || a.equals(b)) return a; if (isPrimitiveType(a) && !isPrimitiveType(b)) { if (isNumberType(a) && isNumberType(b)) { return firstCommonSuperType(ClassHelper.getWrapper(a), b); } else { if (isNumberType(b) && isNumberType(a)) { return firstCommonSuperType(ClassHelper.getWrapper(b), a); } else {
private void improveExprType(Expression expr) { if (expr instanceof BinaryExpression) { if (ClassHelper.isNumberType(expr.getType())) return; ClassNode type2 = getLHSType(bin.getRightExpression()); if (ClassHelper.isNumberType(type1) && ClassHelper.isNumberType(type2)) { ClassNode prim1 = ClassHelper.getUnwrapper(type1); ClassNode prim2 = ClassHelper.getUnwrapper(type2);
if (ClassHelper.isNumberType(type1) && ClassHelper.isNumberType(type2)) { ClassNode prim1 = ClassHelper.getUnwrapper(type1); ClassNode prim2 = ClassHelper.getUnwrapper(type2);
if (ClassHelper.isNumberType(type1) && ClassHelper.isNumberType(type2)) { ClassNode prim1 = ClassHelper.getUnwrapper(type1); ClassNode prim2 = ClassHelper.getUnwrapper(type2);
castToTypeIfNecessary(top, targetType); if (ClassHelper.isNumberType(top) && primTarget && ClassHelper.isNumberType(targetType)) { BytecodeHelper.doCastToPrimitive(mv, top, targetType); } else {
|| ClassHelper.isNumberType(fieldType) || fieldType.getName().startsWith("java.math") || fieldType.getName().equals("groovy.lang.GString")