<s> package org . eclipse . jdt . internal . compiler . ast ; import java . util . ArrayList ; import org . eclipse . jdt . core . compiler . CharOperation ; import org . eclipse . jdt . internal . compiler . ASTVisitor ; import org . eclipse . jdt . internal . compiler . classfmt . ClassFileConstants ; import org . eclipse . jdt . internal . compiler . codegen . BranchLabel ; import org . eclipse . jdt . internal . compiler . codegen . CodeStream ; import org . eclipse . jdt . internal . compiler . flow . FlowContext ; import org . eclipse . jdt . internal . compiler . flow . FlowInfo ; import org . eclipse . jdt . internal . compiler . impl . Constant ; import org . eclipse . jdt . internal . compiler . impl . ReferenceContext ; import org . eclipse . jdt . internal . compiler . lookup . ArrayBinding ; import org . eclipse . jdt . internal . compiler . lookup . BaseTypeBinding ; import org . eclipse . jdt . internal . compiler . lookup . Binding ; import org . eclipse . jdt . internal . compiler . lookup . BlockScope ; import org . eclipse . jdt . internal . compiler . lookup . ClassScope ; import org . eclipse . jdt . internal . compiler . lookup . FieldBinding ; import org . eclipse . jdt . internal . compiler . lookup . LocalVariableBinding ; import org . eclipse . jdt . internal . compiler . lookup . MethodBinding ; import org . eclipse . jdt . internal . compiler . lookup . ReferenceBinding ; import org . eclipse . jdt . internal . compiler . lookup . Scope ; import org . eclipse . jdt . internal . compiler . lookup . TagBits ; import org . eclipse . jdt . internal . compiler . lookup . TypeBinding ; import org . eclipse . jdt . internal . compiler . lookup . TypeIds ; import org . eclipse . jdt . internal . compiler . lookup . TypeVariableBinding ; import org . eclipse . jdt . internal . compiler . lookup . WildcardBinding ; import org . eclipse . jdt . internal . compiler . problem . ShouldNotImplement ; import org . eclipse . jdt . internal . compiler . util . Messages ; public abstract class Expression extends Statement { public Constant constant ; public int statementEnd = - 1 ; public int implicitConversion ; public TypeBinding resolvedType ; public static final boolean isConstantValueRepresentable ( Constant constant , int constantTypeID , int targetTypeID ) { if ( targetTypeID == constantTypeID ) return true ; switch ( targetTypeID ) { case T_char : switch ( constantTypeID ) { case T_char : return true ; case T_double : return constant . doubleValue ( ) == constant . charValue ( ) ; case T_float : return constant . floatValue ( ) == constant . charValue ( ) ; case T_int : return constant . intValue ( ) == constant . charValue ( ) ; case T_short : return constant . shortValue ( ) == constant . charValue ( ) ; case T_byte : return constant . byteValue ( ) == constant . charValue ( ) ; case T_long : return constant . longValue ( ) == constant . charValue ( ) ; default : return false ; } case T_float : switch ( constantTypeID ) { case T_char : return constant . charValue ( ) == constant . floatValue ( ) ; case T_double : return constant . doubleValue ( ) == constant . floatValue ( ) ; case T_float : return true ; case T_int : return constant . intValue ( ) == constant . floatValue ( ) ; case T_short : return constant . shortValue ( ) == constant . floatValue ( ) ; case T_byte : return constant . byteValue ( ) == constant . floatValue ( ) ; case T_long : return constant . longValue ( ) == constant . floatValue ( ) ; default : return false ; } case T_double : switch ( constantTypeID ) { case T_char : return constant . charValue ( ) == constant . doubleValue ( ) ; case T_double : return true ; case T_float : return constant . floatValue ( ) == constant . doubleValue ( ) ; case T_int : return constant . intValue ( ) == constant . doubleValue ( ) ; case T_short : return constant . shortValue ( ) == constant . doubleValue ( ) ; case T_byte : return constant . byteValue ( ) == constant . doubleValue ( ) ; case T_long : return constant . longValue ( ) == constant . doubleValue ( ) ; default : return false ; } case T_byte : switch ( constantTypeID ) { case T_char : return constant . charValue ( ) == constant . byteValue ( ) ; case T_double : return constant . doubleValue ( ) == constant . byteValue ( ) ; case T_float : return constant . floatValue ( ) == constant . byteValue ( ) ; case T_int : return constant . intValue ( ) == constant . byteValue ( ) ; case T_short : return constant . shortValue ( ) == constant . byteValue ( ) ; case T_byte : return true ; case T_long : return constant . longValue ( ) == constant . byteValue ( ) ; default : return false ; } case T_short : switch ( constantTypeID ) { case T_char : return constant . charValue ( ) == constant . shortValue ( ) ; case T_double : return constant . doubleValue ( ) == constant . shortValue ( ) ; case T_float : return constant . floatValue ( ) == constant . shortValue ( ) ; case T_int : return constant . intValue ( ) == constant . shortValue ( ) ; case T_short : return true ; case T_byte : return constant . byteValue ( ) == constant . shortValue ( ) ; case T_long : return constant . longValue ( ) == constant . shortValue ( ) ; default : return false ; } case T_int : switch ( constantTypeID ) { case T_char : return constant . charValue ( ) == constant . intValue ( ) ; case T_double : return constant . doubleValue ( ) == constant . intValue ( ) ; case T_float : return constant . floatValue ( ) == constant . intValue ( ) ; case T_int : return true ; case T_short : return constant . shortValue ( ) == constant . intValue ( ) ; case T_byte : return constant . byteValue ( ) == constant . intValue ( ) ; case T_long : return constant . longValue ( ) == constant . intValue ( ) ; default : return false ; } case T_long : switch ( constantTypeID ) { case T_char : return constant . charValue ( ) == constant . longValue ( ) ; case T_double : return constant . doubleValue ( ) == constant . longValue ( ) ; case T_float : return constant . floatValue ( ) == constant . longValue ( ) ; case T_int : return constant . intValue ( ) == constant . longValue ( ) ; case T_short : return constant . shortValue ( ) == constant . longValue ( ) ; case T_byte : return constant . byteValue ( ) == constant . longValue ( ) ; case T_long : return true ; default : return false ; } default : return false ; } } public Expression ( ) { super ( ) ; } public FlowInfo analyseCode ( BlockScope currentScope , FlowContext flowContext , FlowInfo flowInfo ) { return flowInfo ; } public FlowInfo analyseCode ( BlockScope currentScope , FlowContext flowContext , FlowInfo flowInfo , boolean valueRequired ) { return analyseCode ( currentScope , flowContext , flowInfo ) ; } public final boolean checkCastTypesCompatibility ( Scope scope , TypeBinding castType , TypeBinding expressionType , Expression expression ) { if ( castType == null || expressionType == null ) return true ; boolean use15specifics = scope . compilerOptions ( ) . sourceLevel >= ClassFileConstants . JDK1_5 ; boolean use17specifics = scope . compilerOptions ( ) . sourceLevel >= ClassFileConstants . JDK1_7 ; if ( castType . isBaseType ( ) ) { if ( expressionType . isBaseType ( ) ) { if ( expressionType == castType ) { if ( expression != null ) { this . constant = expression . constant ; } tagAsUnnecessaryCast ( scope , castType ) ; return true ; } boolean necessary = false ; if ( expressionType . isCompatibleWith ( castType ) || ( necessary = BaseTypeBinding . isNarrowing ( castType . id , expressionType . id ) ) ) { if ( expression != null ) { expression . implicitConversion = ( castType . id << 4 ) + expressionType . id ; if ( expression . constant != Constant . NotAConstant ) { this . constant = expression . constant . castTo ( expression . implicitConversion ) ; } } if ( ! necessary ) tagAsUnnecessaryCast ( scope , castType ) ; return true ; } } else if ( use17specifics && expressionType . id == TypeIds . T_JavaLangObject ) { return true ; } else if ( use15specifics && scope . environment ( ) . computeBoxingType ( expressionType ) . isCompatibleWith ( castType ) ) { tagAsUnnecessaryCast ( scope , castType ) ; return true ; } return false ; } else if ( use15specifics && expressionType . isBaseType ( ) && scope . environment ( ) . computeBoxingType ( expressionType ) . isCompatibleWith ( castType ) ) { tagAsUnnecessaryCast ( scope , castType ) ; return true ; } switch ( expressionType . kind ( ) ) { case Binding . BASE_TYPE : if ( expressionType == TypeBinding . NULL ) { tagAsUnnecessaryCast ( scope , castType ) ; return true ; } return false ; case Binding . ARRAY_TYPE : if ( castType == expressionType ) { tagAsUnnecessaryCast ( scope , castType ) ; return true ; } switch ( castType . kind ( ) ) { case Binding . ARRAY_TYPE : TypeBinding castElementType = ( ( ArrayBinding ) castType ) . elementsType ( ) ; TypeBinding exprElementType = ( ( ArrayBinding ) expressionType ) . elementsType ( ) ; if ( exprElementType . isBaseType ( ) || castElementType . isBaseType ( ) ) { if ( castElementType == exprElementType ) { tagAsNeedCheckCast ( ) ; return true ; } return false ; } return checkCastTypesCompatibility ( scope , castElementType , exprElementType , expression ) ; case Binding . TYPE_PARAMETER : TypeBinding match = expressionType . findSuperTypeOriginatingFrom ( castType ) ; if ( match == null ) { checkUnsafeCast ( scope , castType , expressionType , null , true ) ; } return checkCastTypesCompatibility ( scope , ( ( TypeVariableBinding ) castType ) . upperBound ( ) , expressionType , expression ) ; default : switch ( castType . id ) { case T_JavaLangCloneable : case T_JavaIoSerializable : tagAsNeedCheckCast ( ) ; return true ; case T_JavaLangObject : tagAsUnnecessaryCast ( scope , castType ) ; return true ; default : return false ; } } case Binding . TYPE_PARAMETER : TypeBinding match = expressionType . findSuperTypeOriginatingFrom ( castType ) ; if ( match != null ) { return checkUnsafeCast ( scope , castType , expressionType , match , false ) ; } return checkCastTypesCompatibility ( scope , castType , ( ( TypeVariableBinding ) expressionType ) . upperBound ( ) , expression ) ; case Binding . WILDCARD_TYPE : case Binding . INTERSECTION_TYPE : match = expressionType . findSuperTypeOriginatingFrom ( castType ) ; if ( match != null ) { return checkUnsafeCast ( scope , castType , expressionType , match , false ) ; } return checkCastTypesCompatibility ( scope , castType , ( ( WildcardBinding ) expressionType ) . bound , expression ) ; default : if ( expressionType . isInterface ( ) ) { switch ( castType . kind ( ) ) { case Binding . ARRAY_TYPE : switch ( expressionType . id ) { case T_JavaLangCloneable : case T_JavaIoSerializable : tagAsNeedCheckCast ( ) ; return true ; default : return false ; } case Binding . TYPE_PARAMETER : match = expressionType . findSuperTypeOriginatingFrom ( castType ) ; if ( match == null ) { checkUnsafeCast ( scope , castType , expressionType , null , true ) ; } return checkCastTypesCompatibility ( scope , ( ( TypeVariableBinding ) castType ) . upperBound ( ) , expressionType , expression ) ; default : if ( castType . isInterface ( ) ) { ReferenceBinding interfaceType = ( ReferenceBinding ) expressionType ; match = interfaceType . findSuperTypeOriginatingFrom ( castType ) ; if ( match != null ) { return checkUnsafeCast ( scope , castType , interfaceType , match , false ) ; } tagAsNeedCheckCast ( ) ; match = castType . findSuperTypeOriginatingFrom ( interfaceType ) ; if ( match != null ) { return checkUnsafeCast ( scope , castType , interfaceType , match , true ) ; } if ( use15specifics ) { checkUnsafeCast ( scope , castType , expressionType , null , true ) ; if ( scope . compilerOptions ( ) . complianceLevel < ClassFileConstants . JDK1_7 ) { if ( interfaceType . hasIncompatibleSuperType ( ( ReferenceBinding ) castType ) ) { return false ; } } else if ( ! castType . isRawType ( ) && interfaceType . hasIncompatibleSuperType ( ( ReferenceBinding ) castType ) ) { return false ; } } else { MethodBinding [ ] castTypeMethods = getAllOriginalInheritedMethods ( ( ReferenceBinding ) castType ) ; MethodBinding [ ] expressionTypeMethods = getAllOriginalInheritedMethods ( ( ReferenceBinding ) expressionType ) ; 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 ] ) ) { return false ; } } } } return true ; } else { if ( castType . id == TypeIds . T_JavaLangObject ) { tagAsUnnecessaryCast ( scope , castType ) ; return true ; } tagAsNeedCheckCast ( ) ; match = castType . findSuperTypeOriginatingFrom ( expressionType ) ; if ( match != null ) { return checkUnsafeCast ( scope , castType , expressionType , match , true ) ; } if ( ( ( ReferenceBinding ) castType ) . isFinal ( ) ) { return false ; } if ( use15specifics ) { checkUnsafeCast ( scope , castType , expressionType , null , true ) ; if ( scope . compilerOptions ( ) . complianceLevel < ClassFileConstants . JDK1_7 ) { if ( ( ( ReferenceBinding ) castType ) . hasIncompatibleSuperType ( ( ReferenceBinding ) expressionType ) ) { return false ; } } else if ( ! castType . isRawType ( ) && ( ( ReferenceBinding ) castType ) . hasIncompatibleSuperType ( ( ReferenceBinding ) expressionType ) ) { return false ; } } return true ; } } } else { switch ( castType . kind ( ) ) { case Binding . ARRAY_TYPE : if ( expressionType . id == TypeIds . T_JavaLangObject ) { if ( use15specifics ) checkUnsafeCast ( scope , castType , expressionType , expressionType , true ) ; tagAsNeedCheckCast ( ) ; return true ; } return false ; case Binding . TYPE_PARAMETER : match = expressionType . findSuperTypeOriginatingFrom ( castType ) ; if ( match == null ) { checkUnsafeCast ( scope , castType , expressionType , null , true ) ; } return checkCastTypesCompatibility ( scope , ( ( TypeVariableBinding ) castType ) . upperBound ( ) , expressionType , expression ) ; default : if ( castType . isInterface ( ) ) { ReferenceBinding refExprType = ( ReferenceBinding ) expressionType ; match = refExprType . findSuperTypeOriginatingFrom ( castType ) ; if ( match != null ) { return checkUnsafeCast ( scope , castType , expressionType , match , false ) ; } if ( refExprType . isFinal ( ) ) { return false ; } tagAsNeedCheckCast ( ) ; match = castType . findSuperTypeOriginatingFrom ( expressionType ) ; if ( match != null ) { return checkUnsafeCast ( scope , castType , expressionType , match , true ) ; } if ( use15specifics ) { checkUnsafeCast ( scope , castType , expressionType , null , true ) ; if ( scope . compilerOptions ( ) . complianceLevel < ClassFileConstants . JDK1_7 ) { if ( refExprType . hasIncompatibleSuperType ( ( ReferenceBinding ) castType ) ) { return false ; } } else if ( ! castType . isRawType ( ) && refExprType . hasIncompatibleSuperType ( ( ReferenceBinding ) castType ) ) { return false ; } } return true ; } else { match = expressionType . findSuperTypeOriginatingFrom ( castType ) ; if ( match != null ) { if ( expression != null && castType . id == TypeIds . T_JavaLangString ) this . constant = expression . constant ; return checkUnsafeCast ( scope , castType , expressionType , match , false ) ; } match = castType . findSuperTypeOriginatingFrom ( expressionType ) ; if ( match != null ) { tagAsNeedCheckCast ( ) ; return checkUnsafeCast ( scope , castType , expressionType , match , true ) ; } return false ; } } } } } public void checkNPE ( BlockScope scope , FlowContext flowContext , FlowInfo flowInfo ) { LocalVariableBinding local = localVariableBinding ( ) ; if ( local != null && ( local . type . tagBits & TagBits . IsBaseType ) == 0 ) { if ( ( this . bits & ASTNode . IsNonNull ) == 0 ) { flowContext . recordUsingNullReference ( scope , local , this , FlowContext . MAY_NULL , flowInfo ) ; } flowInfo . markAsComparedEqualToNonNull ( local ) ; if ( flowContext . initsOnFinally != null ) { flowContext . initsOnFinally . markAsComparedEqualToNonNull ( local ) ; } } } public boolean checkUnsafeCast ( Scope scope , TypeBinding castType , TypeBinding expressionType , TypeBinding match , boolean isNarrowing ) { if ( match == castType ) { if ( ! isNarrowing ) tagAsUnnecessaryCast ( scope , castType ) ; return true ; } if ( match != null && ( ! castType . isReifiable ( ) || ! expressionType . isReifiable ( ) ) ) { if ( isNarrowing ? match . isProvablyDistinct ( expressionType ) : castType . isProvablyDistinct ( match ) ) { return false ; } } if ( ! isNarrowing ) tagAsUnnecessaryCast ( scope , castType ) ; return true ; } public void computeConversion ( Scope scope , TypeBinding runtimeType , TypeBinding compileTimeType ) { if ( runtimeType == null || compileTimeType == null ) return ; if ( this . implicitConversion != 0 ) return ; if ( runtimeType != TypeBinding . NULL && runtimeType . isBaseType ( ) ) { if ( ! compileTimeType . isBaseType ( ) ) { TypeBinding unboxedType = scope . environment ( ) . computeBoxingType ( compileTimeType ) ; this . implicitConversion = TypeIds . UNBOXING ; scope . problemReporter ( ) . autoboxing ( this , compileTimeType , runtimeType ) ; compileTimeType = unboxedType ; } } else if ( compileTimeType != TypeBinding . NULL && compileTimeType . isBaseType ( ) ) { TypeBinding boxedType = scope . environment ( ) . computeBoxingType ( runtimeType ) ; if ( boxedType == runtimeType ) boxedType = compileTimeType ; this . implicitConversion = TypeIds . BOXING | ( boxedType . id << 4 ) + compileTimeType . id ; scope . problemReporter ( ) . autoboxing ( this , compileTimeType , scope . environment ( ) . computeBoxingType ( boxedType ) ) ; return ; } else if ( this . constant != Constant . NotAConstant && this . constant . typeID ( ) != TypeIds . T_JavaLangString ) { this . implicitConversion = TypeIds . BOXING ; return ; } int compileTimeTypeID , runtimeTypeID ; if ( ( compileTimeTypeID = compileTimeType . id ) == TypeIds . NoId ) { compileTimeTypeID = compileTimeType . erasure ( ) . id == TypeIds . T_JavaLangString ? TypeIds . T_JavaLangString : TypeIds . T_JavaLangObject ; } switch ( runtimeTypeID = runtimeType . id ) { case T_byte : case T_short : case T_char : if ( compileTimeTypeID == TypeIds . T_JavaLangObject ) { this . implicitConversion |= ( runtimeTypeID << 4 ) + compileTimeTypeID ; } else { this . implicitConversion |= ( TypeIds . T_int << 4 ) + compileTimeTypeID ; } break ; case T_JavaLangString : case T_float : case T_boolean : case T_double : case T_int : case T_long : this . implicitConversion |= ( runtimeTypeID << 4 ) + compileTimeTypeID ; break ; default : } } public void generateCode ( BlockScope currentScope , CodeStream codeStream ) { if ( ( this . bits & ASTNode . IsReachable ) == 0 ) { return ; } generateCode ( currentScope , codeStream , false ) ; } public void generateCode ( BlockScope currentScope , CodeStream codeStream , boolean valueRequired ) { if ( this . constant != Constant . NotAConstant ) { int pc = codeStream . position ; codeStream . generateConstant ( this . constant , this . implicitConversion ) ; codeStream . recordPositionsFrom ( pc , this . sourceStart ) ; } else { throw new ShouldNotImplement ( Messages . ast_missingCode ) ; } } public void generateOptimizedBoolean ( BlockScope currentScope , CodeStream codeStream , BranchLabel trueLabel , BranchLabel falseLabel , boolean valueRequired ) { Constant cst = optimizedBooleanConstant ( ) ; generateCode ( currentScope , codeStream , valueRequired && cst == Constant . NotAConstant ) ; if ( ( cst != Constant . NotAConstant ) && ( cst . typeID ( ) == TypeIds . T_boolean ) ) { int pc = codeStream . position ; if ( cst . booleanValue ( ) == true ) { if ( valueRequired ) { if ( falseLabel == null ) { if ( trueLabel != null ) { codeStream . goto_ ( trueLabel ) ; } } } } else { if ( valueRequired ) { if ( falseLabel != null ) { if ( trueLabel == null ) { codeStream . goto_ ( falseLabel ) ; } } } } codeStream . recordPositionsFrom ( pc , this . sourceStart ) ; return ; } int position = codeStream . position ; if ( valueRequired ) { if ( falseLabel == null ) { if ( trueLabel != null ) { codeStream . ifne ( trueLabel ) ; } } else { if ( trueLabel == null ) { codeStream . ifeq ( falseLabel ) ; } else { } } } codeStream . recordPositionsFrom ( position , this . sourceEnd ) ; } public void generateOptimizedStringConcatenation ( BlockScope blockScope , CodeStream codeStream , int typeID ) { if ( typeID == TypeIds . T_JavaLangString && this . constant != Constant . NotAConstant && this . constant . stringValue ( ) . length ( ) == 0 ) { return ; } generateCode ( blockScope , codeStream , true ) ; codeStream . invokeStringConcatenationAppendForType ( typeID ) ; } public void generateOptimizedStringConcatenationCreation ( BlockScope blockScope , CodeStream codeStream , int typeID ) { codeStream . newStringContatenation ( ) ; codeStream . dup ( ) ; switch ( typeID ) { case T_JavaLangObject : case T_undefined : codeStream . invokeStringConcatenationDefaultConstructor ( ) ; generateCode ( blockScope , codeStream , true ) ; codeStream . invokeStringConcatenationAppendForType ( TypeIds . T_JavaLangObject ) ; return ; case T_JavaLangString : case T_null : if ( this . constant != Constant . NotAConstant ) { String stringValue = this . constant . stringValue ( ) ; if ( stringValue . length ( ) == 0 ) { codeStream . invokeStringConcatenationDefaultConstructor ( ) ; return ; } codeStream . ldc ( stringValue ) ; } else { generateCode ( blockScope , codeStream , true ) ; codeStream . invokeStringValueOf ( TypeIds . T_JavaLangObject ) ; } break ; default : generateCode ( blockScope , codeStream , true ) ; codeStream . invokeStringValueOf ( typeID ) ; } codeStream . invokeStringConcatenationStringConstructor ( ) ; } private MethodBinding [ ] getAllOriginalInheritedMethods ( ReferenceBinding binding ) { ArrayList collector = new ArrayList ( ) ; getAllInheritedMethods0 ( binding , collector ) ; for ( int i = 0 , len = collector . size ( ) ; i < len ; i ++ ) { collector . set ( i , ( ( MethodBinding ) collector . get ( i ) ) . original ( ) ) ; } return ( MethodBinding [ ] ) collector . toArray ( new MethodBinding [ collector . size ( ) ] ) ; } private void getAllInheritedMethods0 ( ReferenceBinding binding , ArrayList collector ) { if ( ! binding . isInterface ( ) ) return ; MethodBinding [ ] methodBindings = binding . methods ( ) ; for ( int i = 0 , max = methodBindings . length ; i < max ; i ++ ) { collector . add ( methodBindings [ i ] ) ; } ReferenceBinding [ ] superInterfaces = binding . superInterfaces ( ) ; for ( int i = 0 , max = superInterfaces . length ; i < max ; i ++ ) { getAllInheritedMethods0 ( superInterfaces [ i ] , collector ) ; } } public static Binding getDirectBinding ( Expression someExpression ) { if ( ( someExpression . bits & ASTNode . IgnoreNoEffectAssignCheck ) != 0 ) { return null ; } if ( someExpression instanceof SingleNameReference ) { return ( ( SingleNameReference ) someExpression ) . binding ; } else if ( someExpression instanceof FieldReference ) { FieldReference fieldRef = ( FieldReference ) someExpression ; if ( fieldRef . receiver . isThis ( ) && ! ( fieldRef . receiver instanceof QualifiedThisReference ) ) { return fieldRef . binding ; } } else if ( someExpression instanceof Assignment ) { Expression lhs = ( ( Assignment ) someExpression ) . lhs ; if ( ( lhs . bits & ASTNode . IsStrictlyAssigned ) != 0 ) { return getDirectBinding ( ( ( Assignment ) someExpression ) . lhs ) ; } else if ( someExpression instanceof PrefixExpression ) { return getDirectBinding ( ( ( Assignment ) someExpression ) . lhs ) ; } } else if ( someExpression instanceof QualifiedNameReference ) { QualifiedNameReference qualifiedNameReference = ( QualifiedNameReference ) someExpression ; if ( qualifiedNameReference . indexOfFirstFieldBinding != 1 && qualifiedNameReference . otherBindings == null ) { return qualifiedNameReference . binding ; } } else if ( someExpression . isThis ( ) ) { return someExpression . resolvedType ; } return null ; } public boolean isCompactableOperation ( ) { return false ; } public boolean isConstantValueOfTypeAssignableToType ( TypeBinding constantType , TypeBinding targetType ) { if ( this . constant == Constant . NotAConstant ) return false ; if ( constantType == targetType ) return true ; if ( BaseTypeBinding . isWidening ( TypeIds . T_int , constantType . id ) && ( BaseTypeBinding . isNarrowing ( targetType . id , TypeIds . T_int ) ) ) { return isConstantValueRepresentable ( this . constant , constantType . id , targetType . id ) ; } return false ; } public boolean isTypeReference ( ) { return false ; } public LocalVariableBinding localVariableBinding ( ) { return null ; } public void markAsNonNull ( ) { this . bits |= ASTNode . IsNonNull ; } public int nullStatus ( FlowInfo flowInfo ) { if ( this . constant != null && this . constant != Constant . NotAConstant ) return FlowInfo . NON_NULL ; LocalVariableBinding local = localVariableBinding ( ) ; if ( local != null ) return flowInfo . nullStatus ( local ) ; return FlowInfo . NON_NULL ; } public Constant optimizedBooleanConstant ( ) { return this . constant ; } public TypeBinding postConversionType ( Scope scope ) { TypeBinding convertedType = this . resolvedType ; int runtimeType = ( this . implicitConversion & TypeIds . IMPLICIT_CONVERSION_MASK ) >> 4 ; switch ( runtimeType ) { case T_boolean : convertedType = TypeBinding . BOOLEAN ; break ; case T_byte : convertedType = TypeBinding . BYTE ; break ; case T_short : convertedType = TypeBinding . SHORT ; break ; case T_char : convertedType = TypeBinding . CHAR ; break ; case T_int : convertedType = TypeBinding . INT ; break ; case T_float : convertedType = TypeBinding . FLOAT ; break ; case T_long : convertedType = TypeBinding . LONG ; break ; case T_double : convertedType = TypeBinding . DOUBLE ; break ; default : } if ( ( this . implicitConversion & TypeIds . BOXING ) != 0 ) { convertedType = scope . environment ( ) . computeBoxingType ( convertedType ) ; } return convertedType ; } public StringBuffer print ( int indent , StringBuffer output ) { printIndent ( indent , output ) ; return printExpression ( indent , output ) ; } public abstract StringBuffer printExpression ( int indent , StringBuffer output ) ; public StringBuffer printStatement ( int indent , StringBuffer output ) { return print ( indent , output ) . append ( ";" ) ; } public void resolve ( BlockScope scope ) { this . resolveType ( scope ) ; return ; } public TypeBinding resolveType ( BlockScope scope ) { return null ; } public TypeBinding resolveType ( ClassScope scope ) { return null ; } public TypeBinding resolveTypeExpecting ( BlockScope scope , TypeBinding expectedType ) { setExpectedType ( expectedType ) ; TypeBinding expressionType = this . resolveType ( scope ) ; if ( expressionType == null ) return null ; if ( expressionType == expectedType ) return expressionType ; if ( ! expressionType . isCompatibleWith ( expectedType ) ) { if ( scope . isBoxingCompatibleWith ( expressionType , expectedType ) ) { computeConversion ( scope , expectedType , expressionType ) ; } else { scope . problemReporter ( ) . typeMismatchError ( expressionType , expectedType , this , null ) ; return null ; } } return expressionType ; } public boolean forcedToBeRaw ( ReferenceContext referenceContext ) { if ( this instanceof NameReference ) { final Binding receiverBinding = ( ( NameReference ) this ) . binding ; if ( receiverBinding . isParameter ( ) && ( ( ( LocalVariableBinding ) receiverBinding ) . tagBits & TagBits . ForcedToBeRawType ) != 0 ) { return true ; } else if ( receiverBinding instanceof FieldBinding ) { FieldBinding field = ( FieldBinding ) receiverBinding ; if ( field . type . isRawType ( ) ) { if ( referenceContext instanceof AbstractMethodDeclaration ) { AbstractMethodDeclaration methodDecl = ( AbstractMethodDeclaration ) referenceContext ; if ( field . declaringClass != methodDecl . binding . declaringClass ) { return true ; } } else if ( referenceContext instanceof TypeDeclaration ) { TypeDeclaration type = ( TypeDeclaration ) referenceContext ; if ( field . declaringClass != type . binding ) { return true ; } } } } } else if ( this instanceof MessageSend ) { if ( ! CharOperation . equals ( ( ( MessageSend ) this ) . binding . declaringClass . getFileName ( ) , referenceContext . compilationResult ( ) . getFileName ( ) ) ) { return true ; } } else if ( this instanceof FieldReference ) { FieldBinding field = ( ( FieldReference ) this ) . binding ; if ( ! CharOperation . equals ( field . declaringClass . getFileName ( ) , referenceContext . compilationResult ( ) . getFileName ( ) ) ) { return true ; } if ( field . type . isRawType ( ) ) { if ( referenceContext instanceof AbstractMethodDeclaration ) { AbstractMethodDeclaration methodDecl = ( AbstractMethodDeclaration ) referenceContext ; if ( field . declaringClass != methodDecl . binding . declaringClass ) { return true ; } } else if ( referenceContext instanceof TypeDeclaration ) { TypeDeclaration type = ( TypeDeclaration ) referenceContext ; if ( field . declaringClass != type . binding ) { return true ; } } } } else if ( this instanceof ConditionalExpression ) { ConditionalExpression ternary = ( ConditionalExpression ) this ; if ( ternary . valueIfTrue . forcedToBeRaw ( referenceContext ) || ternary . valueIfFalse . forcedToBeRaw ( referenceContext ) ) { return true ; } } return false ; } public Object reusableJSRTarget ( ) { if ( this . constant != Constant . NotAConstant ) return this . constant ; return null ; } public void setExpectedType ( TypeBinding expectedType ) { } public void tagAsNeedCheckCast ( ) { } public void tagAsUnnecessaryCast ( Scope scope , TypeBinding castType ) { } public Expression toTypeReference ( ) { return this ; } public void traverse ( ASTVisitor visitor , BlockScope scope ) { } public void traverse ( ASTVisitor visitor , ClassScope scope ) { } } </s>