X-Git-Url: http://git.megacz.com/?p=org.ibex.tool.git;a=blobdiff_plain;f=src%2Forg%2Feclipse%2Fjdt%2Finternal%2Fcompiler%2Fast%2FInstanceOfExpression.java;fp=src%2Forg%2Feclipse%2Fjdt%2Finternal%2Fcompiler%2Fast%2FInstanceOfExpression.java;h=5a47db8ffe60942e26dbf60f8a6b74397db666d4;hp=feacdaf8708f320eaf501391703e08900d3db56a;hb=c17753cd9e62cd1a71df3d88af908de0425ac33d;hpb=040fa5af2cd00017cf3575950cdaade34a6d7f6c diff --git a/src/org/eclipse/jdt/internal/compiler/ast/InstanceOfExpression.java b/src/org/eclipse/jdt/internal/compiler/ast/InstanceOfExpression.java index feacdaf..5a47db8 100644 --- a/src/org/eclipse/jdt/internal/compiler/ast/InstanceOfExpression.java +++ b/src/org/eclipse/jdt/internal/compiler/ast/InstanceOfExpression.java @@ -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)) {