/*******************************************************************************
- * Copyright (c) 2000, 2001, 2002 International Business Machines Corp. and others.
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Common Public License v0.5
+ * are made available under the terms of the Common Public License v1.0
* which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v05.html
+ * http://www.eclipse.org/legal/cpl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
- ******************************************************************************/
+ *******************************************************************************/
package net.sourceforge.phpdt.internal.compiler.ast;
-import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor;
-import net.sourceforge.phpdt.internal.compiler.impl.*;
-import net.sourceforge.phpdt.internal.compiler.codegen.*;
-import net.sourceforge.phpdt.internal.compiler.flow.*;
-import net.sourceforge.phpdt.internal.compiler.lookup.*;
+import net.sourceforge.phpdt.internal.compiler.ASTVisitor;
+import net.sourceforge.phpdt.internal.compiler.flow.FlowContext;
+import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo;
+import net.sourceforge.phpdt.internal.compiler.impl.Constant;
+import net.sourceforge.phpdt.internal.compiler.lookup.ArrayBinding;
+import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope;
+import net.sourceforge.phpdt.internal.compiler.lookup.MethodBinding;
+import net.sourceforge.phpdt.internal.compiler.lookup.ReferenceBinding;
+import net.sourceforge.phpdt.internal.compiler.lookup.Scope;
+import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding;
public class EqualExpression extends BinaryExpression {
left.analyseCode(currentScope, flowContext, flowInfo).unconditionalInits()).asNegatedCondition().unconditionalInits();
}
}
-public final boolean areTypesCastCompatible(BlockScope scope, TypeBinding castTb, TypeBinding expressionTb) {
- //see specifications p.68
+public final boolean areTypesCastCompatible(BlockScope scope, TypeBinding castType, TypeBinding expressionType) {
+ //see specifications 5.5
//A more complete version of this method is provided on
//CastExpression (it deals with constant and need runtime checkcast)
+ if (castType == expressionType) return true;
//========ARRAY===============
- if (expressionTb.isArrayType()) {
- if (castTb.isArrayType()) { //------- (castTb.isArray) expressionTb.isArray -----------
- TypeBinding expressionEltTb = ((ArrayBinding) expressionTb).elementsType(scope);
- if (expressionEltTb.isBaseType())
+ if (expressionType.isArrayType()) {
+ if (castType.isArrayType()) { //------- (castTb.isArray) expressionTb.isArray -----------
+ TypeBinding expressionEltType = ((ArrayBinding) expressionType).elementsType(scope);
+ if (expressionEltType.isBaseType())
// <---stop the recursion-------
- return ((ArrayBinding) castTb).elementsType(scope) == expressionEltTb;
+ return ((ArrayBinding) castType).elementsType(scope) == expressionEltType;
//recursivly on the elts...
- return areTypesCastCompatible(scope, ((ArrayBinding) castTb).elementsType(scope), expressionEltTb);
+ return areTypesCastCompatible(scope, ((ArrayBinding) castType).elementsType(scope), expressionEltType);
}
- if (castTb.isBaseType()) {
+ if (castType.isBaseType()) {
return false;
}
- if (castTb.isClass()) { //------(castTb.isClass) expressionTb.isArray ---------------
- if (scope.isJavaLangObject(castTb))
+ if (castType.isClass()) { //------(castTb.isClass) expressionTb.isArray ---------------
+ if (scope.isJavaLangObject(castType))
return true;
return false;
}
- if (castTb.isInterface()) { //------- (castTb.isInterface) expressionTb.isArray -----------
- if (scope.isJavaLangCloneable(castTb) || scope.isJavaIoSerializable(castTb)) {
+ if (castType.isInterface()) { //------- (castTb.isInterface) expressionTb.isArray -----------
+ if (scope.isJavaLangCloneable(castType) || scope.isJavaIoSerializable(castType)) {
return true;
}
return false;
}
//------------(castType) null--------------
- if (expressionTb == NullBinding) {
- return !castTb.isBaseType();
+ if (expressionType == NullBinding) {
+ return !castType.isBaseType();
}
//========BASETYPE==============
- if (expressionTb.isBaseType()) {
+ if (expressionType.isBaseType()) {
return false;
}
//========REFERENCE TYPE===================
- if (expressionTb.isClass()) {
- if (castTb.isArrayType()) { // ---- (castTb.isArray) expressionTb.isClass -------
- if (scope.isJavaLangObject(expressionTb))
+ if (expressionType.isClass()) {
+ if (castType.isArrayType()) { // ---- (castTb.isArray) expressionTb.isClass -------
+ if (scope.isJavaLangObject(expressionType))
return true;
}
- if (castTb.isBaseType()) {
+ if (castType.isBaseType()) {
return false;
}
- if (castTb.isClass()) { // ----- (castTb.isClass) expressionTb.isClass ------
- if (scope.areTypesCompatible(expressionTb, castTb))
+ if (castType.isClass()) { // ----- (castTb.isClass) expressionTb.isClass ------
+ if (expressionType.isCompatibleWith(castType))
return true;
else {
- if (scope.areTypesCompatible(castTb, expressionTb)) {
+ if (castType.isCompatibleWith(expressionType)) {
return true;
}
return false;
}
}
- if (castTb.isInterface()) { // ----- (castTb.isInterface) expressionTb.isClass -------
- if (((ReferenceBinding) expressionTb).isFinal()) { //no subclass for expressionTb, thus compile-time check is valid
- if (scope.areTypesCompatible(expressionTb, castTb))
+ if (castType.isInterface()) { // ----- (castTb.isInterface) expressionTb.isClass -------
+ if (((ReferenceBinding) expressionType).isFinal()) { //no subclass for expressionTb, thus compile-time check is valid
+ if (expressionType.isCompatibleWith(castType))
return true;
return false;
} else {
return false;
}
- if (expressionTb.isInterface()) {
- if (castTb.isArrayType()) { // ----- (castTb.isArray) expressionTb.isInterface ------
- if (scope.isJavaLangCloneable(expressionTb) || scope.isJavaIoSerializable(expressionTb))
+ if (expressionType.isInterface()) {
+ if (castType.isArrayType()) { // ----- (castTb.isArray) expressionTb.isInterface ------
+ if (scope.isJavaLangCloneable(expressionType) || scope.isJavaIoSerializable(expressionType))
//potential runtime error
{
return true;
}
return false;
}
- if (castTb.isBaseType()) {
+ if (castType.isBaseType()) {
return false;
}
- if (castTb.isClass()) { // ----- (castTb.isClass) expressionTb.isInterface --------
- if (scope.isJavaLangObject(castTb))
+ if (castType.isClass()) { // ----- (castTb.isClass) expressionTb.isInterface --------
+ if (scope.isJavaLangObject(castType))
return true;
- if (((ReferenceBinding) castTb).isFinal()) { //no subclass for castTb, thus compile-time check is valid
- if (scope.areTypesCompatible(castTb, expressionTb)) {
+ if (((ReferenceBinding) castType).isFinal()) { //no subclass for castTb, thus compile-time check is valid
+ if (castType.isCompatibleWith(expressionType)) {
return true;
}
return false;
}
return true;
}
- if (castTb.isInterface()) { // ----- (castTb.isInterface) expressionTb.isInterface -------
- if (castTb != expressionTb && (Scope.compareTypes(castTb, expressionTb) == NotRelated)) {
- MethodBinding[] castTbMethods = ((ReferenceBinding) castTb).methods();
+ if (castType.isInterface()) { // ----- (castTb.isInterface) expressionTb.isInterface -------
+ if (Scope.compareTypes(castType, expressionType) == NotRelated) {
+ MethodBinding[] castTbMethods = ((ReferenceBinding) castType).methods();
int castTbMethodsLength = castTbMethods.length;
- MethodBinding[] expressionTbMethods = ((ReferenceBinding) expressionTb).methods();
+ MethodBinding[] expressionTbMethods = ((ReferenceBinding) expressionType).methods();
int expressionTbMethodsLength = expressionTbMethods.length;
for (int i = 0; i < castTbMethodsLength; i++) {
for (int j = 0; j < expressionTbMethodsLength; j++) {
return false;
}
-public final void computeConstant(TypeBinding leftTb, TypeBinding rightTb) {
- if ((left.constant != NotAConstant) && (right.constant != NotAConstant)) {
- constant =
+public final void computeConstant(TypeBinding leftType, TypeBinding rightType) {
+ if ((this.left.constant != NotAConstant) && (this.right.constant != NotAConstant)) {
+ this.constant =
Constant.computeConstantOperationEQUAL_EQUAL(
left.constant,
- leftTb.id,
+ leftType.id,
EQUAL_EQUAL,
right.constant,
- rightTb.id);
- if (((bits & OperatorMASK) >> OperatorSHIFT) == NOT_EQUAL)
+ rightType.id);
+ if (((this.bits & OperatorMASK) >> OperatorSHIFT) == NOT_EQUAL)
constant = Constant.fromValue(!constant.booleanValue());
} else {
- constant = NotAConstant;
+ this.constant = NotAConstant;
+ // no optimization for null == null
}
}
/**
* Normal == or != code generation.
*
- * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
- * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
+ * @param currentScope net.sourceforge.phpdt.internal.compiler.lookup.BlockScope
+ * @param codeStream net.sourceforge.phpdt.internal.compiler.codegen.CodeStream
* @param valueRequired boolean
*/
-public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
-
- if (constant != NotAConstant) {
- int pc = codeStream.position;
- if (valueRequired)
- codeStream.generateConstant(constant, implicitConversion);
- codeStream.recordPositionsFrom(pc, this.sourceStart);
- return;
- }
- Label falseLabel;
- generateOptimizedBoolean(
- currentScope,
- codeStream,
- null,
- falseLabel = new Label(codeStream),
- valueRequired);
- if (falseLabel.hasForwardReferences()) {
- if (valueRequired){
- // comparison is TRUE
- codeStream.iconst_1();
- if ((bits & ValueForReturnMASK) != 0){
- codeStream.ireturn();
- // comparison is FALSE
- falseLabel.place();
- codeStream.iconst_0();
- } else {
- Label endLabel = new Label(codeStream);
- codeStream.goto_(endLabel);
- codeStream.decrStackSize(1);
- // comparison is FALSE
- falseLabel.place();
- codeStream.iconst_0();
- endLabel.place();
- }
- } else {
- falseLabel.place();
- }
- }
-}
+//public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
+//
+// if (constant != NotAConstant) {
+// int pc = codeStream.position;
+// if (valueRequired)
+// codeStream.generateConstant(constant, implicitConversion);
+// codeStream.recordPositionsFrom(pc, this.sourceStart);
+// return;
+// }
+// Label falseLabel;
+// bits |= OnlyValueRequiredMASK;
+// generateOptimizedBoolean(
+// currentScope,
+// codeStream,
+// null,
+// falseLabel = new Label(codeStream),
+// valueRequired);
+// if (falseLabel.hasForwardReferences()) {
+// if (valueRequired){
+// // comparison is TRUE
+// codeStream.iconst_1();
+// if ((bits & ValueForReturnMASK) != 0){
+// codeStream.ireturn();
+// // comparison is FALSE
+// falseLabel.place();
+// codeStream.iconst_0();
+// } else {
+// Label endLabel = new Label(codeStream);
+// codeStream.goto_(endLabel);
+// codeStream.decrStackSize(1);
+// // comparison is FALSE
+// falseLabel.place();
+// codeStream.iconst_0();
+// endLabel.place();
+// }
+// } else {
+// falseLabel.place();
+// }
+// }
+//}
/**
* Boolean operator code generation
* Optimized operations are: == and !=
*/
-public void generateOptimizedBoolean(BlockScope currentScope, CodeStream codeStream, Label trueLabel, Label falseLabel, boolean valueRequired) {
- if ((constant != Constant.NotAConstant) && (constant.typeID() == T_boolean)) {
- super.generateOptimizedBoolean(currentScope, codeStream, trueLabel, falseLabel, valueRequired);
- return;
- }
- int pc = codeStream.position;
- if (((bits & OperatorMASK) >> OperatorSHIFT) == EQUAL_EQUAL) {
- if ((left.implicitConversion & 0xF) /*compile-time*/ == T_boolean) {
- generateOptimizedBooleanEqual(currentScope, codeStream, trueLabel, falseLabel, valueRequired);
- } else {
- generateOptimizedNonBooleanEqual(currentScope, codeStream, trueLabel, falseLabel, valueRequired);
- }
- } else {
- if ((left.implicitConversion & 0xF) /*compile-time*/ == T_boolean) {
- generateOptimizedBooleanEqual(currentScope, codeStream, falseLabel, trueLabel, valueRequired);
- } else {
- generateOptimizedNonBooleanEqual(currentScope, codeStream, falseLabel, trueLabel, valueRequired);
- }
- }
- codeStream.recordPositionsFrom(pc, this.sourceStart);
-}
+//public void generateOptimizedBoolean(BlockScope currentScope, CodeStream codeStream, Label trueLabel, Label falseLabel, boolean valueRequired) {
+//
+// if (constant != Constant.NotAConstant) {
+// super.generateOptimizedBoolean(currentScope, codeStream, trueLabel, falseLabel, valueRequired);
+// return;
+// }
+// if (((bits & OperatorMASK) >> OperatorSHIFT) == EQUAL_EQUAL) {
+// if ((left.implicitConversion & 0xF) /*compile-time*/ == T_boolean) {
+// generateOptimizedBooleanEqual(currentScope, codeStream, trueLabel, falseLabel, valueRequired);
+// } else {
+// generateOptimizedNonBooleanEqual(currentScope, codeStream, trueLabel, falseLabel, valueRequired);
+// }
+// } else {
+// if ((left.implicitConversion & 0xF) /*compile-time*/ == T_boolean) {
+// generateOptimizedBooleanEqual(currentScope, codeStream, falseLabel, trueLabel, valueRequired);
+// } else {
+// generateOptimizedNonBooleanEqual(currentScope, codeStream, falseLabel, trueLabel, valueRequired);
+// }
+// }
+//}
/**
* Boolean generation for == with boolean operands
*
* Note this code does not optimize conditional constants !!!!
*/
-public void generateOptimizedBooleanEqual(BlockScope currentScope, CodeStream codeStream, Label trueLabel, Label falseLabel, boolean valueRequired) {
- int pc = codeStream.position;
- // optimized cases: true == x, false == x
- if (left.constant != NotAConstant) {
- boolean inline = left.constant.booleanValue();
- right.generateOptimizedBoolean(currentScope, codeStream, (inline ? trueLabel : falseLabel), (inline ? falseLabel : trueLabel), valueRequired);
- codeStream.recordPositionsFrom(pc, this.sourceStart);
- return;
- } // optimized cases: x == true, x == false
- if (right.constant != NotAConstant) {
- boolean inline = right.constant.booleanValue();
- left.generateOptimizedBoolean(currentScope, codeStream, (inline ? trueLabel : falseLabel), (inline ? falseLabel : trueLabel), valueRequired);
- codeStream.recordPositionsFrom(pc, this.sourceStart);
- return;
- }
- // default case
- left.generateCode(currentScope, codeStream, valueRequired);
- right.generateCode(currentScope, codeStream, valueRequired);
- if (valueRequired) {
- if (falseLabel == null) {
- if (trueLabel != null) {
- // implicit falling through the FALSE case
- codeStream.if_icmpeq(trueLabel);
- }
- } else {
- // implicit falling through the TRUE case
- if (trueLabel == null) {
- codeStream.if_icmpne(falseLabel);
- } else {
- // no implicit fall through TRUE/FALSE --> should never occur
- }
- }
- }
- codeStream.recordPositionsFrom(pc, this.sourceStart);
-}
-/**
- * Boolean generation for == with non-boolean operands
- *
- */
-public void generateOptimizedNonBooleanEqual(BlockScope currentScope, CodeStream codeStream, Label trueLabel, Label falseLabel, boolean valueRequired) {
- int pc = codeStream.position;
- Constant inline;
- if ((inline = right.constant) != NotAConstant) {
- // optimized case: x == null
- if (right.constant == NullConstant.Default) {
- left.generateCode(currentScope, codeStream, valueRequired);
- if (valueRequired) {
- if (falseLabel == null) {
- if (trueLabel != null) {
- // implicit falling through the FALSE case
- codeStream.ifnull(trueLabel);
- }
- } else {
- // implicit falling through the TRUE case
- if (trueLabel == null) {
- codeStream.ifnonnull(falseLabel);
- } else {
- // no implicit fall through TRUE/FALSE --> should never occur
- }
- }
- }
- codeStream.recordPositionsFrom(pc, this.sourceStart);
- return;
- }
- // optimized case: x == 0
- if (((left.implicitConversion >> 4) == T_int) && (inline.intValue() == 0)) {
- left.generateCode(currentScope, codeStream, valueRequired);
- if (valueRequired) {
- if (falseLabel == null) {
- if (trueLabel != null) {
- // implicit falling through the FALSE case
- codeStream.ifeq(trueLabel);
- }
- } else {
- // implicit falling through the TRUE case
- if (trueLabel == null) {
- codeStream.ifne(falseLabel);
- } else {
- // no implicit fall through TRUE/FALSE --> should never occur
- }
- }
- }
- codeStream.recordPositionsFrom(pc, this.sourceStart);
- return;
- }
- }
- if ((inline = left.constant) != NotAConstant) {
- // optimized case: null == x
- if (left.constant == NullConstant.Default) {
- right.generateCode(currentScope, codeStream, valueRequired);
- if (valueRequired) {
- if (falseLabel == null) {
- if (trueLabel != null) {
- // implicit falling through the FALSE case
- codeStream.ifnull(trueLabel);
- }
- } else {
- // implicit falling through the TRUE case
- if (trueLabel == null) {
- codeStream.ifnonnull(falseLabel);
- } else {
- // no implicit fall through TRUE/FALSE --> should never occur
- }
- }
- }
- codeStream.recordPositionsFrom(pc, this.sourceStart);
- return;
- }
- // optimized case: 0 == x
- if (((left.implicitConversion >> 4) == T_int)
- && (inline.intValue() == 0)) {
- right.generateCode(currentScope, codeStream, valueRequired);
- if (valueRequired) {
- if (falseLabel == null) {
- if (trueLabel != null) {
- // implicit falling through the FALSE case
- codeStream.ifeq(trueLabel);
- }
- } else {
- // implicit falling through the TRUE case
- if (trueLabel == null) {
- codeStream.ifne(falseLabel);
- } else {
- // no implicit fall through TRUE/FALSE --> should never occur
- }
- }
- }
- codeStream.recordPositionsFrom(pc, this.sourceStart);
- return;
- }
- }
- // default case
- left.generateCode(currentScope, codeStream, valueRequired);
- right.generateCode(currentScope, codeStream, valueRequired);
- if (valueRequired) {
- if (falseLabel == null) {
- if (trueLabel != null) {
- // implicit falling through the FALSE case
- switch (left.implicitConversion >> 4) { // operand runtime type
- case T_int :
- codeStream.if_icmpeq(trueLabel);
- break;
- case T_float :
- codeStream.fcmpl();
- codeStream.ifeq(trueLabel);
- break;
- case T_long :
- codeStream.lcmp();
- codeStream.ifeq(trueLabel);
- break;
- case T_double :
- codeStream.dcmpl();
- codeStream.ifeq(trueLabel);
- break;
- default :
- codeStream.if_acmpeq(trueLabel);
- }
- }
- } else {
- // implicit falling through the TRUE case
- if (trueLabel == null) {
- switch (left.implicitConversion >> 4) { // operand runtime type
- case T_int :
- codeStream.if_icmpne(falseLabel);
- break;
- case T_float :
- codeStream.fcmpl();
- codeStream.ifne(falseLabel);
- break;
- case T_long :
- codeStream.lcmp();
- codeStream.ifne(falseLabel);
- break;
- case T_double :
- codeStream.dcmpl();
- codeStream.ifne(falseLabel);
- break;
- default :
- codeStream.if_acmpne(falseLabel);
- }
- } else {
- // no implicit fall through TRUE/FALSE --> should never occur
- }
- }
- }
- codeStream.recordPositionsFrom(pc, this.sourceStart);
-}
+//public void generateOptimizedBooleanEqual(BlockScope currentScope, CodeStream codeStream, Label trueLabel, Label falseLabel, boolean valueRequired) {
+//
+// // optimized cases: true == x, false == x
+// if (left.constant != NotAConstant) {
+// boolean inline = left.constant.booleanValue();
+// right.generateOptimizedBoolean(currentScope, codeStream, (inline ? trueLabel : falseLabel), (inline ? falseLabel : trueLabel), valueRequired);
+// return;
+// } // optimized cases: x == true, x == false
+// if (right.constant != NotAConstant) {
+// boolean inline = right.constant.booleanValue();
+// left.generateOptimizedBoolean(currentScope, codeStream, (inline ? trueLabel : falseLabel), (inline ? falseLabel : trueLabel), valueRequired);
+// return;
+// }
+// // default case
+// left.generateCode(currentScope, codeStream, valueRequired);
+// right.generateCode(currentScope, codeStream, valueRequired);
+// if (valueRequired) {
+// if (falseLabel == null) {
+// if (trueLabel != null) {
+// // implicit falling through the FALSE case
+// codeStream.if_icmpeq(trueLabel);
+// }
+// } else {
+// // implicit falling through the TRUE case
+// if (trueLabel == null) {
+// codeStream.if_icmpne(falseLabel);
+// } else {
+// // no implicit fall through TRUE/FALSE --> should never occur
+// }
+// }
+// }
+// // reposition the endPC
+// codeStream.updateLastRecordedEndPC(codeStream.position);
+//}
+///**
+// * Boolean generation for == with non-boolean operands
+// *
+// */
+//public void generateOptimizedNonBooleanEqual(BlockScope currentScope, CodeStream codeStream, Label trueLabel, Label falseLabel, boolean valueRequired) {
+//
+// int pc = codeStream.position;
+// Constant inline;
+// if ((inline = right.constant) != NotAConstant) {
+// // optimized case: x == 0
+// if (((left.implicitConversion >> 4) == T_int) && (inline.intValue() == 0)) {
+// left.generateCode(currentScope, codeStream, valueRequired);
+// if (valueRequired) {
+// if (falseLabel == null) {
+// if (trueLabel != null) {
+// // implicit falling through the FALSE case
+// codeStream.ifeq(trueLabel);
+// }
+// } else {
+// // implicit falling through the TRUE case
+// if (trueLabel == null) {
+// codeStream.ifne(falseLabel);
+// } else {
+// // no implicit fall through TRUE/FALSE --> should never occur
+// }
+// }
+// }
+// codeStream.recordPositionsFrom(pc, this.sourceStart);
+// return;
+// }
+// }
+// if ((inline = left.constant) != NotAConstant) {
+// // optimized case: 0 == x
+// if (((left.implicitConversion >> 4) == T_int)
+// && (inline.intValue() == 0)) {
+// right.generateCode(currentScope, codeStream, valueRequired);
+// if (valueRequired) {
+// if (falseLabel == null) {
+// if (trueLabel != null) {
+// // implicit falling through the FALSE case
+// codeStream.ifeq(trueLabel);
+// }
+// } else {
+// // implicit falling through the TRUE case
+// if (trueLabel == null) {
+// codeStream.ifne(falseLabel);
+// } else {
+// // no implicit fall through TRUE/FALSE --> should never occur
+// }
+// }
+// }
+// codeStream.recordPositionsFrom(pc, this.sourceStart);
+// return;
+// }
+// }
+// // null cases
+// // optimized case: x == null
+// if (right instanceof NullLiteral) {
+// if (left instanceof NullLiteral) {
+// // null == null
+// if (valueRequired) {
+// if ((bits & OnlyValueRequiredMASK) != 0) {
+// if (((bits & OperatorMASK) >> OperatorSHIFT) == EQUAL_EQUAL) {
+// codeStream.iconst_1();
+// } else {
+// codeStream.iconst_0();
+// }
+// } else {
+// if (falseLabel == null) {
+// // implicit falling through the FALSE case
+// if (trueLabel != null) {
+// codeStream.goto_(trueLabel);
+// }
+// }
+// }
+// }
+// } else {
+// left.generateCode(currentScope, codeStream, valueRequired);
+// if (valueRequired) {
+// if (falseLabel == null) {
+// if (trueLabel != null) {
+// // implicit falling through the FALSE case
+// codeStream.ifnull(trueLabel);
+// }
+// } else {
+// // implicit falling through the TRUE case
+// if (trueLabel == null) {
+// codeStream.ifnonnull(falseLabel);
+// } else {
+// // no implicit fall through TRUE/FALSE --> should never occur
+// }
+// }
+// }
+// }
+// codeStream.recordPositionsFrom(pc, this.sourceStart);
+// return;
+// } else if (left instanceof NullLiteral) { // optimized case: null == x
+// right.generateCode(currentScope, codeStream, valueRequired);
+// if (valueRequired) {
+// if (falseLabel == null) {
+// if (trueLabel != null) {
+// // implicit falling through the FALSE case
+// codeStream.ifnull(trueLabel);
+// }
+// } else {
+// // implicit falling through the TRUE case
+// if (trueLabel == null) {
+// codeStream.ifnonnull(falseLabel);
+// } else {
+// // no implicit fall through TRUE/FALSE --> should never occur
+// }
+// }
+// }
+// codeStream.recordPositionsFrom(pc, this.sourceStart);
+// return;
+// }
+//
+// // default case
+// left.generateCode(currentScope, codeStream, valueRequired);
+// right.generateCode(currentScope, codeStream, valueRequired);
+// if (valueRequired) {
+// if (falseLabel == null) {
+// if (trueLabel != null) {
+// // implicit falling through the FALSE case
+// switch (left.implicitConversion >> 4) { // operand runtime type
+// case T_int :
+// codeStream.if_icmpeq(trueLabel);
+// break;
+// case T_float :
+// codeStream.fcmpl();
+// codeStream.ifeq(trueLabel);
+// break;
+// case T_long :
+// codeStream.lcmp();
+// codeStream.ifeq(trueLabel);
+// break;
+// case T_double :
+// codeStream.dcmpl();
+// codeStream.ifeq(trueLabel);
+// break;
+// default :
+// codeStream.if_acmpeq(trueLabel);
+// }
+// }
+// } else {
+// // implicit falling through the TRUE case
+// if (trueLabel == null) {
+// switch (left.implicitConversion >> 4) { // operand runtime type
+// case T_int :
+// codeStream.if_icmpne(falseLabel);
+// break;
+// case T_float :
+// codeStream.fcmpl();
+// codeStream.ifne(falseLabel);
+// break;
+// case T_long :
+// codeStream.lcmp();
+// codeStream.ifne(falseLabel);
+// break;
+// case T_double :
+// codeStream.dcmpl();
+// codeStream.ifne(falseLabel);
+// break;
+// default :
+// codeStream.if_acmpne(falseLabel);
+// }
+// } else {
+// // no implicit fall through TRUE/FALSE --> should never occur
+// }
+// }
+// }
+// codeStream.recordPositionsFrom(pc, this.sourceStart);
+//}
public boolean isCompactableOperation() {
return false;
}
public TypeBinding resolveType(BlockScope scope) {
// always return BooleanBinding
- TypeBinding leftTb = left.resolveType(scope);
- TypeBinding rightTb = right.resolveType(scope);
- if (leftTb == null || rightTb == null){
+ TypeBinding leftType = left.resolveType(scope);
+ TypeBinding rightType = right.resolveType(scope);
+ if (leftType == null || rightType == null){
constant = NotAConstant;
return null;
}
// both base type
- if (leftTb.isBaseType() && rightTb.isBaseType()) {
+ if (leftType.isBaseType() && rightType.isBaseType()) {
// the code is an int
// (cast) left == (cast) rigth --> result
// 0000 0000 0000 0000 0000
// <<16 <<12 <<8 <<4 <<0
- int result = ResolveTypeTables[EQUAL_EQUAL][ (leftTb.id << 4) + rightTb.id];
+ int result = ResolveTypeTables[EQUAL_EQUAL][ (leftType.id << 4) + rightType.id];
left.implicitConversion = result >>> 12;
right.implicitConversion = (result >>> 4) & 0x000FF;
bits |= result & 0xF;
if ((result & 0x0000F) == T_undefined) {
constant = Constant.NotAConstant;
- scope.problemReporter().invalidOperator(this, leftTb, rightTb);
+ scope.problemReporter().invalidOperator(this, leftType, rightType);
return null;
}
- computeConstant(leftTb, rightTb);
- this.typeBinding = BooleanBinding;
+ computeConstant(leftType, rightType);
+ this.resolvedType = BooleanBinding;
return BooleanBinding;
}
// Object references
// spec 15.20.3
- if (areTypesCastCompatible(scope, rightTb, leftTb) || areTypesCastCompatible(scope, leftTb, rightTb)) {
+ if (areTypesCastCompatible(scope, rightType, leftType) || areTypesCastCompatible(scope, leftType, rightType)) {
// (special case for String)
- if ((rightTb.id == T_String) && (leftTb.id == T_String))
- computeConstant(leftTb, rightTb);
+ if ((rightType.id == T_String) && (leftType.id == T_String))
+ computeConstant(leftType, rightType);
else
constant = NotAConstant;
- if (rightTb.id == T_String)
+ if (rightType.id == T_String)
right.implicitConversion = String2String;
- if (leftTb.id == T_String)
+ if (leftType.id == T_String)
left.implicitConversion = String2String;
- this.typeBinding = BooleanBinding;
+ this.resolvedType = BooleanBinding;
return BooleanBinding;
}
constant = NotAConstant;
- scope.problemReporter().notCompatibleTypesError(this, leftTb, rightTb);
+ scope.problemReporter().notCompatibleTypesError(this, leftType, rightType);
return null;
}
-public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) {
+public void traverse(ASTVisitor visitor, BlockScope scope) {
if (visitor.visit(this, scope)) {
left.traverse(visitor, scope);
right.traverse(visitor, scope);