import eclipse 3.1 M4 compiler
[org.ibex.tool.git] / src / org / eclipse / jdt / internal / compiler / ast / InstanceOfExpression.java
index feacdaf..5a47db8 100644 (file)
@@ -10,7 +10,6 @@
  *******************************************************************************/
 package org.eclipse.jdt.internal.compiler.ast;
 
-import org.eclipse.jdt.core.compiler.CharOperation;
 import org.eclipse.jdt.internal.compiler.ASTVisitor;
 import org.eclipse.jdt.internal.compiler.codegen.*;
 import org.eclipse.jdt.internal.compiler.flow.*;
@@ -38,139 +37,13 @@ public class InstanceOfExpression extends OperatorExpression {
                FlowContext flowContext,
                FlowInfo flowInfo) {
 
-               return expression
+               flowInfo = expression
                        .analyseCode(currentScope, flowContext, flowInfo)
                        .unconditionalInits();
+               expression.checkNullStatus(currentScope, flowContext, flowInfo, FlowInfo.NON_NULL);
+               return flowInfo;
        }
-       /**
-        * Returns false if the instanceof unnecessary
-        */
-       public final boolean checkCastTypesCompatibility(
-               BlockScope scope,
-               TypeBinding castType,
-               TypeBinding expressionType) {
-       
-               //A more complete version of this method is provided on
-               //CastExpression (it deals with constant and need runtime checkcast)
-
-               if (castType == expressionType) return false;
-               
-               //by grammatical construction, the base type check is not necessary
 
-               if (castType == null || expressionType == null) return true;
-       
-               //-----------cast to something which is NOT a base type--------------------------       
-               if (expressionType == NullBinding) {
-                       //      if (castType.isArrayType()){ // 26903 - need checkcast when casting null to array type
-                       //              needRuntimeCheckcast = true;
-                       //      }
-                       return false; //null is compatible with every thing
-               }
-               if (expressionType.isBaseType()) {
-                       scope.problemReporter().notCompatibleTypesError(this, expressionType, castType);
-                       return true;
-               }
-       
-               if (expressionType.isArrayType()) {
-                       if (castType == expressionType) return false; // identity conversion
-       
-                       if (castType.isArrayType()) {
-                               //------- (castType.isArray) expressionType.isArray -----------
-                               TypeBinding exprElementType = ((ArrayBinding) expressionType).elementsType(scope);
-                               if (exprElementType.isBaseType()) {
-                                       // <---stop the recursion------- 
-                                       if (((ArrayBinding) castType).elementsType(scope) != exprElementType)
-                                               scope.problemReporter().notCompatibleTypesError(this, expressionType, castType);
-                                       return true;
-                               }
-                               // recursively on the elements...
-                               return checkCastTypesCompatibility(
-                                       scope,
-                                       ((ArrayBinding) castType).elementsType(scope),
-                                       exprElementType);
-                       } else if (
-                               castType.isClass()) {
-                               //------(castType.isClass) expressionType.isArray ---------------       
-                               if (castType.id == T_Object) {
-                                       return false;
-                               }
-                       } else { //------- (castType.isInterface) expressionType.isArray -----------
-                               if (castType.id == T_JavaLangCloneable || castType.id == T_JavaIoSerializable) {
-                                       return true;
-                               }
-                       }
-                       scope.problemReporter().notCompatibleTypesError(this, expressionType, castType);
-                       return true;
-               }
-       
-               if (expressionType.isClass()) {
-                       if (castType.isArrayType()) {
-                               // ---- (castType.isArray) expressionType.isClass -------
-                               if (expressionType.id == T_Object) { // potential runtime error
-                                       return true;
-                               }
-                       } else if (castType.isClass()) { // ----- (castType.isClass) expressionType.isClass ------
-                               if (expressionType.isCompatibleWith(castType)){ // no runtime error
-                                       return false;
-                               }
-                               if (castType.isCompatibleWith(expressionType)) {
-                                       // potential runtime  error
-                                       return true;
-                               }
-                       } else { // ----- (castType.isInterface) expressionType.isClass -------  
-                               if (expressionType.isCompatibleWith(castType)) 
-                                       return false;
-                               if (!((ReferenceBinding) expressionType).isFinal()) {
-                                   // a subclass may implement the interface ==> no check at compile time
-                                       return true;
-                               }
-                               // no subclass for expressionType, thus compile-time check is valid
-                       }
-                       scope.problemReporter().notCompatibleTypesError(this, expressionType, castType);
-                       return true;
-               }
-       
-               //      if (expressionType.isInterface()) { cannot be anything else
-               if (castType.isArrayType()) {
-                       // ----- (castType.isArray) expressionType.isInterface ------
-                       if (!(expressionType.id == T_JavaLangCloneable
-                                       || expressionType.id == T_JavaIoSerializable)) {// potential runtime error
-                               scope.problemReporter().notCompatibleTypesError(this, expressionType, castType);
-                       }
-                       return true;
-               } else if (castType.isClass()) { // ----- (castType.isClass) expressionType.isInterface --------
-                       if (castType.id == T_Object) { // no runtime error
-                               return false;
-                       }
-                       if (((ReferenceBinding) castType).isFinal()) {
-                               // no subclass for castType, thus compile-time check is valid
-                               if (!castType.isCompatibleWith(expressionType)) {
-                                       // potential runtime error
-                                       scope.problemReporter().notCompatibleTypesError(this, expressionType, castType);
-                                       return true;
-                               }
-                       }
-               } else { // ----- (castType.isInterface) expressionType.isInterface -------
-                       if (expressionType.isCompatibleWith(castType)) { 
-                               return false;
-                       }
-                       if (!castType.isCompatibleWith(expressionType)) {
-                               MethodBinding[] castTypeMethods = ((ReferenceBinding) castType).methods();
-                               MethodBinding[] expressionTypeMethods =
-                                       ((ReferenceBinding) expressionType).methods();
-                               int exprMethodsLength = expressionTypeMethods.length;
-                               for (int i = 0, castMethodsLength = castTypeMethods.length; i < castMethodsLength; i++)
-                                       for (int j = 0; j < exprMethodsLength; j++) {
-                                               if ((castTypeMethods[i].returnType != expressionTypeMethods[j].returnType)
-                                                               && CharOperation.equals(castTypeMethods[i].selector, expressionTypeMethods[j].selector)
-                                                               && castTypeMethods[i].areParametersEqual(expressionTypeMethods[j])) {
-                                                       scope.problemReporter().notCompatibleTypesError(this, expressionType, castType);
-                                               }
-                                       }
-                       }
-               }
-               return true;
-       }
        /**
         * Code generation for instanceOfExpression
         *
@@ -186,8 +59,11 @@ public class InstanceOfExpression extends OperatorExpression {
                int pc = codeStream.position;
                expression.generateCode(currentScope, codeStream, true);
                codeStream.instance_of(type.resolvedType);
-               if (!valueRequired)
+               if (valueRequired) {
+                       codeStream.generateImplicitConversion(implicitConversion);
+               } else {
                        codeStream.pop();
+               }
                codeStream.recordPositionsFrom(pc, this.sourceStart);
        }
 
@@ -196,22 +72,33 @@ public class InstanceOfExpression extends OperatorExpression {
                expression.printExpression(indent, output).append(" instanceof "); //$NON-NLS-1$
                return type.print(0, output);
        }
-       
+       /**
+        * @see org.eclipse.jdt.internal.compiler.ast.Expression#reportIllegalCast(org.eclipse.jdt.internal.compiler.lookup.Scope, org.eclipse.jdt.internal.compiler.lookup.TypeBinding, org.eclipse.jdt.internal.compiler.lookup.TypeBinding)
+        */
+       public void reportIllegalCast(Scope scope, TypeBinding castType, TypeBinding expressionType) {
+               scope.problemReporter().notCompatibleTypesError(this, expressionType, castType);
+       }
        public TypeBinding resolveType(BlockScope scope) {
 
                constant = NotAConstant;
                TypeBinding expressionType = expression.resolveType(scope);
-               TypeBinding checkType = type.resolveType(scope);
-               if (expressionType == null || checkType == null)
+               TypeBinding checkedType = type.resolveType(scope, true /* check bounds*/);
+               if (expressionType == null || checkedType == null)
                        return null;
 
-               boolean necessary = checkCastTypesCompatibility(scope, checkType, expressionType);
-               if (!necessary) {
-                       scope.problemReporter().unnecessaryInstanceof(this, checkType);
+               if (checkedType.isTypeVariable() || checkedType.isBoundParameterizedType() || checkedType.isGenericType()) {
+                       scope.problemReporter().illegalInstanceOfGenericType(checkedType, this);
+               } else {
+                       checkCastTypesCompatibility(scope, checkedType, expressionType, null);
                }
                return this.resolvedType = BooleanBinding;
        }
-
+       /**
+        * @see org.eclipse.jdt.internal.compiler.ast.Expression#tagAsUnnecessaryCast(Scope,TypeBinding)
+        */
+       public void tagAsUnnecessaryCast(Scope scope, TypeBinding castType) {
+               scope.problemReporter().unnecessaryInstanceof(this, castType);
+       }
        public void traverse(ASTVisitor visitor, BlockScope scope) {
 
                if (visitor.visit(this, scope)) {