feature request 1245255, no uninitialized variable warning for functions with referen...
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / compiler / ast / EqualExpression.java
index 2a6fe06..3788b65 100644 (file)
@@ -1,22 +1,19 @@
 /*******************************************************************************
- * 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.codegen.CodeStream;
-import net.sourceforge.phpdt.internal.compiler.codegen.Label;
+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.impl.NullConstant;
 import net.sourceforge.phpdt.internal.compiler.lookup.ArrayBinding;
 import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope;
 import net.sourceforge.phpdt.internal.compiler.lookup.MethodBinding;
@@ -76,32 +73,33 @@ public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, Fl
                        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;
@@ -111,39 +109,39 @@ public final boolean areTypesCastCompatible(BlockScope scope, TypeBinding castTb
        }
 
        //------------(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 (BlockScope.areTypesCompatible(expressionTb, castTb))
+               if (castType.isClass()) { // ----- (castTb.isClass) expressionTb.isClass ------ 
+                       if (expressionType.isCompatibleWith(castType))
                                return true;
                        else {
-                               if (BlockScope.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 (BlockScope.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 {
@@ -153,34 +151,34 @@ public final boolean areTypesCastCompatible(BlockScope scope, TypeBinding castTb
 
                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 (BlockScope.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++) {
@@ -202,336 +200,357 @@ public final boolean areTypesCastCompatible(BlockScope scope, TypeBinding castTb
 
        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);