public TypeBinding resolveType(BlockScope scope) { boolean leftIsCast, rightIsCast; if ((leftIsCast = this.left instanceof CastExpression) == true) this.left.bits |= DisableUnnecessaryCastCheck; // will check later on TypeBinding originalLeftType = this.left.resolveType(scope); if ((rightIsCast = this.right instanceof CastExpression) == true) this.right.bits |= DisableUnnecessaryCastCheck; // will check later on TypeBinding originalRightType = this.right.resolveType(scope); // always return BooleanBinding if (originalLeftType == null || originalRightType == null) { this.constant = Constant.NotAConstant; return null; } // autoboxing support boolean use15specifics = scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5; TypeBinding leftType = originalLeftType, rightType = originalRightType; if (use15specifics) { if (leftType != TypeBinding.NULL && leftType.isBaseType()) { if (!rightType.isBaseType()) { rightType = scope.environment().computeBoxingType(rightType); } } else { if (rightType != TypeBinding.NULL && rightType.isBaseType()) { leftType = scope.environment().computeBoxingType(leftType); } } } // both base type if (leftType.isBaseType() && rightType.isBaseType()) { int leftTypeID = leftType.id; int rightTypeID = rightType.id; // the code is an int // (cast) left == (cast) right --> result // 0000 0000 0000 0000 0000 // <<16 <<12 <<8 <<4 <<0 int operatorSignature = OperatorSignatures[EQUAL_EQUAL][(leftTypeID << 4) + rightTypeID]; this.left.computeConversion( scope, TypeBinding.wellKnownType(scope, (operatorSignature >>> 16) & 0x0000F), originalLeftType); this.right.computeConversion( scope, TypeBinding.wellKnownType(scope, (operatorSignature >>> 8) & 0x0000F), originalRightType); this.bits |= operatorSignature & 0xF; if ((operatorSignature & 0x0000F) == T_undefined) { this.constant = Constant.NotAConstant; scope.problemReporter().invalidOperator(this, leftType, rightType); return null; } // check need for operand cast if (leftIsCast || rightIsCast) { CastExpression.checkNeedForArgumentCasts( scope, EQUAL_EQUAL, operatorSignature, this.left, leftType.id, leftIsCast, this.right, rightType.id, rightIsCast); } computeConstant(leftType, rightType); // check whether comparing identical expressions Binding leftDirect = Expression.getDirectBinding(this.left); if (leftDirect != null && leftDirect == Expression.getDirectBinding(this.right)) { if (leftTypeID != TypeIds.T_double && leftTypeID != TypeIds.T_float && (!(this.right instanceof Assignment))) // https://bugs.eclipse.org/bugs/show_bug.cgi?id=281776 scope.problemReporter().comparingIdenticalExpressions(this); } else if (this.constant != Constant.NotAConstant) { // https://bugs.eclipse.org/bugs/show_bug.cgi?id=276740 int operator = (this.bits & OperatorMASK) >> OperatorSHIFT; if ((operator == EQUAL_EQUAL && this.constant == BooleanConstant.fromValue(true)) || (operator == NOT_EQUAL && this.constant == BooleanConstant.fromValue(false))) scope.problemReporter().comparingIdenticalExpressions(this); } return this.resolvedType = TypeBinding.BOOLEAN; } // Object references // spec 15.20.3 if ((!leftType.isBaseType() || leftType == TypeBinding.NULL) // cannot compare: Object == (int)0 && (!rightType.isBaseType() || rightType == TypeBinding.NULL) && (checkCastTypesCompatibility(scope, leftType, rightType, null) || checkCastTypesCompatibility(scope, rightType, leftType, null))) { // (special case for String) if ((rightType.id == T_JavaLangString) && (leftType.id == T_JavaLangString)) { computeConstant(leftType, rightType); } else { this.constant = Constant.NotAConstant; } TypeBinding objectType = scope.getJavaLangObject(); this.left.computeConversion(scope, objectType, leftType); this.right.computeConversion(scope, objectType, rightType); // check need for operand cast boolean unnecessaryLeftCast = (this.left.bits & UnnecessaryCast) != 0; boolean unnecessaryRightCast = (this.right.bits & UnnecessaryCast) != 0; if (unnecessaryLeftCast || unnecessaryRightCast) { TypeBinding alternateLeftType = unnecessaryLeftCast ? ((CastExpression) this.left).expression.resolvedType : leftType; TypeBinding alternateRightType = unnecessaryRightCast ? ((CastExpression) this.right).expression.resolvedType : rightType; if (checkCastTypesCompatibility(scope, alternateLeftType, alternateRightType, null) || checkCastTypesCompatibility(scope, alternateRightType, alternateLeftType, null)) { if (unnecessaryLeftCast) scope.problemReporter().unnecessaryCast((CastExpression) this.left); if (unnecessaryRightCast) scope.problemReporter().unnecessaryCast((CastExpression) this.right); } } // check whether comparing identical expressions Binding leftDirect = Expression.getDirectBinding(this.left); if (leftDirect != null && leftDirect == Expression.getDirectBinding(this.right)) { if (!(this.right instanceof Assignment)) { scope.problemReporter().comparingIdenticalExpressions(this); } } return this.resolvedType = TypeBinding.BOOLEAN; } this.constant = Constant.NotAConstant; scope.problemReporter().notCompatibleTypesError(this, leftType, rightType); return null; }