<s> package org . eclipse . jdt . internal . eval ; import org . eclipse . jdt . internal . compiler . ast . Assignment ; import org . eclipse . jdt . internal . compiler . ast . BinaryExpression ; import org . eclipse . jdt . internal . compiler . ast . CompoundAssignment ; import org . eclipse . jdt . internal . compiler . ast . Expression ; import org . eclipse . jdt . internal . compiler . ast . IntLiteral ; import org . eclipse . jdt . internal . compiler . ast . SingleNameReference ; import org . eclipse . jdt . internal . compiler . codegen . CodeStream ; import org . eclipse . jdt . internal . compiler . codegen . Opcodes ; 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 . 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 . ParameterizedFieldBinding ; import org . eclipse . jdt . internal . compiler . lookup . ProblemBinding ; import org . eclipse . jdt . internal . compiler . lookup . ProblemFieldBinding ; import org . eclipse . jdt . internal . compiler . lookup . ProblemReasons ; 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 . VariableBinding ; public class CodeSnippetSingleNameReference extends SingleNameReference implements EvaluationConstants , ProblemReasons { EvaluationContext evaluationContext ; FieldBinding delegateThis ; public CodeSnippetSingleNameReference ( char [ ] source , long pos , EvaluationContext evaluationContext ) { super ( source , pos ) ; this . evaluationContext = evaluationContext ; } public FlowInfo analyseCode ( BlockScope currentScope , FlowContext flowContext , FlowInfo flowInfo , boolean valueRequired ) { switch ( this . bits & RestrictiveFlagMASK ) { case Binding . FIELD : FieldBinding fieldBinding ; if ( ( fieldBinding = ( FieldBinding ) this . binding ) . isBlankFinal ( ) && currentScope . needBlankFinalFieldInitializationCheck ( fieldBinding ) ) { FlowInfo fieldInits = flowContext . getInitsForFinalBlankInitializationCheck ( fieldBinding . declaringClass . original ( ) , flowInfo ) ; if ( ! fieldInits . isDefinitelyAssigned ( fieldBinding ) ) { currentScope . problemReporter ( ) . uninitializedBlankFinalField ( fieldBinding , this ) ; } } break ; case Binding . LOCAL : LocalVariableBinding localBinding ; if ( ! flowInfo . isDefinitelyAssigned ( localBinding = ( LocalVariableBinding ) this . binding ) ) { currentScope . problemReporter ( ) . uninitializedLocalVariable ( localBinding , this ) ; } if ( ( flowInfo . tagBits & FlowInfo . UNREACHABLE ) == 0 ) { localBinding . useFlag = LocalVariableBinding . USED ; } else if ( localBinding . useFlag == LocalVariableBinding . UNUSED ) { localBinding . useFlag = LocalVariableBinding . FAKE_USED ; } } return flowInfo ; } public TypeBinding checkFieldAccess ( BlockScope scope ) { if ( this . delegateThis == null ) { return super . checkFieldAccess ( scope ) ; } FieldBinding fieldBinding = ( FieldBinding ) this . binding ; this . bits &= ~ RestrictiveFlagMASK ; this . bits |= Binding . FIELD ; if ( ! fieldBinding . isStatic ( ) ) { if ( this . evaluationContext . isStatic ) { scope . problemReporter ( ) . staticFieldAccessToNonStaticVariable ( this , fieldBinding ) ; this . constant = Constant . NotAConstant ; return null ; } } this . constant = fieldBinding . constant ( ) ; if ( isFieldUseDeprecated ( fieldBinding , scope , ( this . bits & IsStrictlyAssigned ) != 0 ) ) { scope . problemReporter ( ) . deprecatedField ( fieldBinding , this ) ; } return fieldBinding . type ; } public void generateAssignment ( BlockScope currentScope , CodeStream codeStream , Assignment assignment , boolean valueRequired ) { if ( assignment . expression . isCompactableOperation ( ) ) { BinaryExpression operation = ( BinaryExpression ) assignment . expression ; int operator = ( operation . bits & OperatorMASK ) >> OperatorSHIFT ; SingleNameReference variableReference ; if ( ( operation . left instanceof SingleNameReference ) && ( ( variableReference = ( SingleNameReference ) operation . left ) . binding == this . binding ) ) { variableReference . generateCompoundAssignment ( currentScope , codeStream , this . syntheticAccessors == null ? null : this . syntheticAccessors [ WRITE ] , operation . right , operator , operation . implicitConversion , valueRequired ) ; if ( valueRequired ) { codeStream . generateImplicitConversion ( assignment . implicitConversion ) ; } return ; } if ( ( operation . right instanceof SingleNameReference ) && ( ( operator == PLUS ) || ( operator == MULTIPLY ) ) && ( ( variableReference = ( SingleNameReference ) operation . right ) . binding == this . binding ) && ( operation . left . constant != Constant . NotAConstant ) && ( ( ( operation . left . implicitConversion & IMPLICIT_CONVERSION_MASK ) >> 4 ) != T_JavaLangString ) && ( ( ( operation . right . implicitConversion & IMPLICIT_CONVERSION_MASK ) >> 4 ) != T_JavaLangString ) ) { variableReference . generateCompoundAssignment ( currentScope , codeStream , this . syntheticAccessors == null ? null : this . syntheticAccessors [ WRITE ] , operation . left , operator , operation . implicitConversion , valueRequired ) ; if ( valueRequired ) { codeStream . generateImplicitConversion ( assignment . implicitConversion ) ; } return ; } } switch ( this . bits & RestrictiveFlagMASK ) { case Binding . FIELD : FieldBinding codegenField = ( ( FieldBinding ) this . binding ) . original ( ) ; if ( codegenField . canBeSeenBy ( getReceiverType ( currentScope ) , this , currentScope ) ) { if ( ! codegenField . isStatic ( ) ) { if ( ( this . bits & DepthMASK ) != 0 ) { ReferenceBinding targetType = currentScope . enclosingSourceType ( ) . enclosingTypeAt ( ( this . bits & DepthMASK ) >> DepthSHIFT ) ; Object [ ] emulationPath = currentScope . getEmulationPath ( targetType , true , false ) ; codeStream . generateOuterAccess ( emulationPath , this , targetType , currentScope ) ; } else { generateReceiver ( codeStream ) ; } } assignment . expression . generateCode ( currentScope , codeStream , true ) ; fieldStore ( currentScope , codeStream , codegenField , null , this . actualReceiverType , this . delegateThis == null , valueRequired ) ; if ( valueRequired ) { codeStream . generateImplicitConversion ( assignment . implicitConversion ) ; } } else { codeStream . generateEmulationForField ( codegenField ) ; if ( ! codegenField . isStatic ( ) ) { if ( ( this . bits & DepthMASK ) != 0 ) { currentScope . problemReporter ( ) . needImplementation ( this ) ; } else { generateReceiver ( codeStream ) ; } } else { codeStream . aconst_null ( ) ; } assignment . expression . generateCode ( currentScope , codeStream , true ) ; if ( valueRequired ) { if ( ( codegenField . type == TypeBinding . LONG ) || ( codegenField . type == TypeBinding . DOUBLE ) ) { codeStream . dup2_x2 ( ) ; } else { codeStream . dup_x2 ( ) ; } } codeStream . generateEmulatedWriteAccessForField ( codegenField ) ; if ( valueRequired ) { codeStream . generateImplicitConversion ( assignment . implicitConversion ) ; } } return ; case Binding . LOCAL : LocalVariableBinding localBinding = ( LocalVariableBinding ) this . binding ; if ( localBinding . resolvedPosition != - 1 ) { assignment . expression . generateCode ( currentScope , codeStream , true ) ; } else { if ( assignment . expression . constant != Constant . NotAConstant ) { if ( valueRequired ) { codeStream . generateConstant ( assignment . expression . constant , assignment . implicitConversion ) ; } } else { assignment . expression . generateCode ( currentScope , codeStream , true ) ; if ( valueRequired ) { codeStream . generateImplicitConversion ( assignment . implicitConversion ) ; } else { if ( ( localBinding . type == TypeBinding . LONG ) || ( localBinding . type == TypeBinding . DOUBLE ) ) { codeStream . pop2 ( ) ; } else { codeStream . pop ( ) ; } } } return ; } codeStream . store ( localBinding , valueRequired ) ; if ( ( this . bits & FirstAssignmentToLocal ) != 0 ) { localBinding . recordInitializationStartPC ( codeStream . position ) ; } if ( valueRequired ) { codeStream . generateImplicitConversion ( assignment . implicitConversion ) ; } } } public void generateCode ( BlockScope currentScope , CodeStream codeStream , boolean valueRequired ) { int pc = codeStream . position ; if ( this . constant != Constant . NotAConstant ) { if ( valueRequired ) { codeStream . generateConstant ( this . constant , this . implicitConversion ) ; } } else { switch ( this . bits & RestrictiveFlagMASK ) { case Binding . FIELD : if ( ! valueRequired ) break ; FieldBinding codegenField = ( ( FieldBinding ) this . binding ) . original ( ) ; Constant fieldConstant = codegenField . constant ( ) ; if ( fieldConstant == Constant . NotAConstant ) { if ( codegenField . canBeSeenBy ( getReceiverType ( currentScope ) , this , currentScope ) ) { TypeBinding someReceiverType = this . delegateThis != null ? this . delegateThis . type : this . actualReceiverType ; TypeBinding constantPoolDeclaringClass = CodeStream . getConstantPoolDeclaringClass ( currentScope , codegenField , someReceiverType , true ) ; if ( codegenField . isStatic ( ) ) { codeStream . fieldAccess ( Opcodes . OPC_getstatic , codegenField , constantPoolDeclaringClass ) ; } else { if ( ( this . bits & DepthMASK ) != 0 ) { ReferenceBinding targetType = currentScope . enclosingSourceType ( ) . enclosingTypeAt ( ( this . bits & DepthMASK ) >> DepthSHIFT ) ; Object [ ] emulationPath = currentScope . getEmulationPath ( targetType , true , false ) ; codeStream . generateOuterAccess ( emulationPath , this , targetType , currentScope ) ; } else { generateReceiver ( codeStream ) ; } codeStream . fieldAccess ( Opcodes . OPC_getfield , codegenField , constantPoolDeclaringClass ) ; } } else { if ( ! codegenField . isStatic ( ) ) { if ( ( this . bits & DepthMASK ) != 0 ) { currentScope . problemReporter ( ) . needImplementation ( this ) ; } else { generateReceiver ( codeStream ) ; } } else { codeStream . aconst_null ( ) ; } codeStream . generateEmulatedReadAccessForField ( codegenField ) ; } if ( this . genericCast != null ) codeStream . checkcast ( this . genericCast ) ; codeStream . generateImplicitConversion ( this . implicitConversion ) ; } else { codeStream . generateConstant ( fieldConstant , this . implicitConversion ) ; } break ; case Binding . LOCAL : LocalVariableBinding localBinding = ( LocalVariableBinding ) this . binding ; if ( ! valueRequired ) break ; if ( ( this . bits & DepthMASK ) != 0 ) { VariableBinding [ ] path = currentScope . getEmulationPath ( localBinding ) ; codeStream . generateOuterAccess ( path , this , localBinding , currentScope ) ; } else { codeStream . load ( localBinding ) ; } codeStream . generateImplicitConversion ( this . implicitConversion ) ; break ; } } codeStream . recordPositionsFrom ( pc , this . sourceStart ) ; } public void generateCompoundAssignment ( BlockScope currentScope , CodeStream codeStream , MethodBinding writeAccessor , Expression expression , int operator , int assignmentImplicitConversion , boolean valueRequired ) { switch ( this . bits & RestrictiveFlagMASK ) { case Binding . FIELD : FieldBinding codegenField = ( ( FieldBinding ) this . binding ) . original ( ) ; if ( codegenField . isStatic ( ) ) { if ( codegenField . canBeSeenBy ( getReceiverType ( currentScope ) , this , currentScope ) ) { TypeBinding someReceiverType = this . delegateThis != null ? this . delegateThis . type : this . actualReceiverType ; TypeBinding constantPoolDeclaringClass = CodeStream . getConstantPoolDeclaringClass ( currentScope , codegenField , someReceiverType , true ) ; codeStream . fieldAccess ( Opcodes . OPC_getstatic , codegenField , constantPoolDeclaringClass ) ; } else { codeStream . generateEmulationForField ( codegenField ) ; codeStream . aconst_null ( ) ; codeStream . aconst_null ( ) ; codeStream . generateEmulatedReadAccessForField ( codegenField ) ; } } else { if ( codegenField . canBeSeenBy ( getReceiverType ( currentScope ) , this , currentScope ) ) { if ( ( this . bits & DepthMASK ) != 0 ) { ReferenceBinding targetType = currentScope . enclosingSourceType ( ) . enclosingTypeAt ( ( this . bits & DepthMASK ) >> DepthSHIFT ) ; Object [ ] emulationPath = currentScope . getEmulationPath ( targetType , true , false ) ; codeStream . generateOuterAccess ( emulationPath , this , targetType , currentScope ) ; } else { generateReceiver ( codeStream ) ; } codeStream . dup ( ) ; TypeBinding someReceiverType = this . delegateThis != null ? this . delegateThis . type : this . actualReceiverType ; TypeBinding constantPoolDeclaringClass = CodeStream . getConstantPoolDeclaringClass ( currentScope , codegenField , someReceiverType , true ) ; codeStream . fieldAccess ( Opcodes . OPC_getfield , codegenField , constantPoolDeclaringClass ) ; } else { if ( ( this . bits & DepthMASK ) != 0 ) { currentScope . problemReporter ( ) . needImplementation ( this ) ; } codeStream . generateEmulationForField ( codegenField ) ; generateReceiver ( codeStream ) ; codeStream . dup ( ) ; codeStream . generateEmulatedReadAccessForField ( codegenField ) ; } } break ; case Binding . LOCAL : LocalVariableBinding localBinding = ( LocalVariableBinding ) this . binding ; switch ( localBinding . type . id ) { case T_JavaLangString : codeStream . generateStringConcatenationAppend ( currentScope , this , expression ) ; if ( valueRequired ) { codeStream . dup ( ) ; } codeStream . store ( localBinding , false ) ; return ; case T_int : Constant assignConstant ; if ( ( ( assignConstant = expression . constant ) != Constant . NotAConstant ) && ( assignConstant . typeID ( ) != TypeIds . T_float ) && ( assignConstant . typeID ( ) != TypeIds . T_double ) ) { switch ( operator ) { case PLUS : int increment = assignConstant . intValue ( ) ; if ( increment != ( short ) increment ) break ; codeStream . iinc ( localBinding . resolvedPosition , increment ) ; if ( valueRequired ) { codeStream . load ( localBinding ) ; } return ; case MINUS : increment = - assignConstant . intValue ( ) ; if ( increment != ( short ) increment ) break ; codeStream . iinc ( localBinding . resolvedPosition , increment ) ; if ( valueRequired ) { codeStream . load ( localBinding ) ; } return ; } } default : codeStream . load ( localBinding ) ; } } int operationTypeID ; switch ( operationTypeID = ( this . implicitConversion & IMPLICIT_CONVERSION_MASK ) >> 4 ) { case T_JavaLangString : case T_JavaLangObject : case T_undefined : codeStream . generateStringConcatenationAppend ( currentScope , null , expression ) ; break ; default : codeStream . generateImplicitConversion ( this . implicitConversion ) ; if ( expression == IntLiteral . One ) { codeStream . generateConstant ( expression . constant , this . implicitConversion ) ; } else { expression . generateCode ( currentScope , codeStream , true ) ; } codeStream . sendOperator ( operator , operationTypeID ) ; codeStream . generateImplicitConversion ( assignmentImplicitConversion ) ; } switch ( this . bits & RestrictiveFlagMASK ) { case Binding . FIELD : FieldBinding codegenField = ( ( FieldBinding ) this . binding ) . original ( ) ; if ( codegenField . canBeSeenBy ( getReceiverType ( currentScope ) , this , currentScope ) ) { fieldStore ( currentScope , codeStream , codegenField , writeAccessor , this . actualReceiverType , this . delegateThis == null , valueRequired ) ; } else { if ( valueRequired ) { switch ( codegenField . type . id ) { case TypeIds . T_long : case TypeIds . T_double : codeStream . dup2_x2 ( ) ; break ; default : codeStream . dup_x2 ( ) ; break ; } } codeStream . generateEmulatedWriteAccessForField ( codegenField ) ; } return ; case Binding . LOCAL : LocalVariableBinding localBinding = ( LocalVariableBinding ) this . binding ; if ( valueRequired ) { switch ( localBinding . type . id ) { case TypeIds . T_long : case TypeIds . T_double : codeStream . dup2 ( ) ; break ; default : codeStream . dup ( ) ; break ; } } codeStream . store ( localBinding , false ) ; } } public void generatePostIncrement ( BlockScope currentScope , CodeStream codeStream , CompoundAssignment postIncrement , boolean valueRequired ) { switch ( this . bits & RestrictiveFlagMASK ) { case Binding . FIELD : FieldBinding codegenField = ( ( FieldBinding ) this . binding ) . original ( ) ; if ( codegenField . canBeSeenBy ( getReceiverType ( currentScope ) , this , currentScope ) ) { super . generatePostIncrement ( currentScope , codeStream , postIncrement , valueRequired ) ; } else { if ( codegenField . isStatic ( ) ) { codeStream . aconst_null ( ) ; } else { if ( ( this . bits & DepthMASK ) != 0 ) { currentScope . problemReporter ( ) . needImplementation ( this ) ; } else { generateReceiver ( codeStream ) ; } } codeStream . generateEmulatedReadAccessForField ( codegenField ) ; if ( valueRequired ) { switch ( codegenField . type . id ) { case TypeIds . T_long : case TypeIds . T_double : codeStream . dup2 ( ) ; break ; default : codeStream . dup ( ) ; break ; } } codeStream . generateEmulationForField ( codegenField ) ; switch ( codegenField . type . id ) { case TypeIds . T_long : case TypeIds . T_double : codeStream . dup_x2 ( ) ; codeStream . pop ( ) ; if ( codegenField . isStatic ( ) ) { codeStream . aconst_null ( ) ; } else { generateReceiver ( codeStream ) ; } codeStream . dup_x2 ( ) ; codeStream . pop ( ) ; break ; default : codeStream . dup_x1 ( ) ; codeStream . pop ( ) ; if ( codegenField . isStatic ( ) ) { codeStream . aconst_null ( ) ; } else { generateReceiver ( codeStream ) ; } codeStream . dup_x1 ( ) ; codeStream . pop ( ) ; break ; } codeStream . generateConstant ( postIncrement . expression . constant , this . implicitConversion ) ; codeStream . sendOperator ( postIncrement . operator , codegenField . type . id ) ; codeStream . generateImplicitConversion ( postIncrement . preAssignImplicitConversion ) ; codeStream . generateEmulatedWriteAccessForField ( codegenField ) ; } return ; case Binding . LOCAL : super . generatePostIncrement ( currentScope , codeStream , postIncrement , valueRequired ) ; } } public void generateReceiver ( CodeStream codeStream ) { codeStream . aload_0 ( ) ; if ( this . delegateThis != null ) { codeStream . fieldAccess ( Opcodes . OPC_getfield , this . delegateThis , null ) ; } } public TypeBinding getReceiverType ( BlockScope currentScope ) { Scope scope = currentScope . parent ; while ( true ) { switch ( scope . kind ) { case Scope . CLASS_SCOPE : return ( ( ClassScope ) scope ) . referenceContext . binding ; default : scope = scope . parent ; } } } public void manageSyntheticAccessIfNecessary ( BlockScope currentScope , FlowInfo flowInfo , boolean isReadAccess ) { if ( this . delegateThis == null ) { super . manageSyntheticAccessIfNecessary ( currentScope , flowInfo , isReadAccess ) ; return ; } if ( ( flowInfo . tagBits & FlowInfo . UNREACHABLE ) != 0 ) return ; if ( this . constant != Constant . NotAConstant ) return ; if ( this . binding instanceof ParameterizedFieldBinding ) { ParameterizedFieldBinding parameterizedField = ( ParameterizedFieldBinding ) this . binding ; FieldBinding codegenField = parameterizedField . originalField ; if ( ( codegenField . type . tagBits & TagBits . HasTypeVariable ) != 0 ) { this . genericCast = codegenField . type . genericCast ( currentScope . boxing ( parameterizedField . type ) ) ; } } } public TypeBinding reportError ( BlockScope scope ) { this . constant = Constant . NotAConstant ; if ( this . binding instanceof ProblemFieldBinding && ( ( ProblemFieldBinding ) this . binding ) . problemId ( ) == NotFound ) { if ( this . evaluationContext . declaringTypeName != null ) { this . delegateThis = scope . getField ( scope . enclosingSourceType ( ) , DELEGATE_THIS , this ) ; if ( this . delegateThis != null ) { this . actualReceiverType = this . delegateThis . type ; this . binding = scope . getField ( this . delegateThis . type , this . token , this ) ; if ( ! this . binding . isValidBinding ( ) ) { return super . reportError ( scope ) ; } return checkFieldAccess ( scope ) ; } } } if ( this . binding instanceof ProblemBinding && ( ( ProblemBinding ) this . binding ) . problemId ( ) == NotFound ) { if ( this . evaluationContext . declaringTypeName != null ) { this . delegateThis = scope . getField ( scope . enclosingSourceType ( ) , DELEGATE_THIS , this ) ; if ( this . delegateThis != null ) { this . actualReceiverType = this . delegateThis . type ; FieldBinding fieldBinding = scope . getField ( this . delegateThis . type , this . token , this ) ; if ( ! fieldBinding . isValidBinding ( ) ) { if ( ( ( ProblemFieldBinding ) fieldBinding ) . problemId ( ) == NotVisible ) { CodeSnippetScope localScope = new CodeSnippetScope ( scope ) ; this . binding = localScope . getFieldForCodeSnippet ( this . delegateThis . type , this . token , this ) ; return checkFieldAccess ( scope ) ; } else { return super . reportError ( scope ) ; } } this . binding = fieldBinding ; return checkFieldAccess ( scope ) ; } } } return super . reportError ( scope ) ; } } </s>