<s> package org . eclipse . jdt . internal . compiler . ast ; import org . eclipse . jdt . internal . compiler . ASTVisitor ; import org . eclipse . jdt . internal . compiler . classfmt . ClassFileConstants ; 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 . lookup . Binding ; import org . eclipse . jdt . internal . compiler . lookup . BlockScope ; import org . eclipse . jdt . internal . compiler . lookup . ExtraCompilerModifiers ; import org . eclipse . jdt . internal . compiler . lookup . InvocationSite ; import org . eclipse . jdt . internal . compiler . lookup . LocalTypeBinding ; import org . eclipse . jdt . internal . compiler . lookup . MethodBinding ; import org . eclipse . jdt . internal . compiler . lookup . MethodScope ; import org . eclipse . jdt . internal . compiler . lookup . ProblemMethodBinding ; import org . eclipse . jdt . internal . compiler . lookup . RawTypeBinding ; import org . eclipse . jdt . internal . compiler . lookup . ReferenceBinding ; import org . eclipse . jdt . internal . compiler . lookup . SourceTypeBinding ; import org . eclipse . jdt . internal . compiler . lookup . TagBits ; import org . eclipse . jdt . internal . compiler . lookup . TypeBinding ; import org . eclipse . jdt . internal . compiler . lookup . TypeConstants ; import org . eclipse . jdt . internal . compiler . lookup . TypeIds ; import org . eclipse . jdt . internal . compiler . lookup . VariableBinding ; public class ExplicitConstructorCall extends Statement implements InvocationSite { public Expression [ ] arguments ; public Expression qualification ; public MethodBinding binding ; MethodBinding syntheticAccessor ; public int accessMode ; public TypeReference [ ] typeArguments ; public TypeBinding [ ] genericTypeArguments ; public final static int ImplicitSuper = 1 ; public final static int Super = 2 ; public final static int This = 3 ; public VariableBinding [ ] [ ] implicitArguments ; public int typeArgumentsSourceStart ; public ExplicitConstructorCall ( int accessMode ) { this . accessMode = accessMode ; } public FlowInfo analyseCode ( BlockScope currentScope , FlowContext flowContext , FlowInfo flowInfo ) { try { ( ( MethodScope ) currentScope ) . isConstructorCall = true ; if ( this . qualification != null ) { flowInfo = this . qualification . analyseCode ( currentScope , flowContext , flowInfo ) . unconditionalInits ( ) ; } if ( this . arguments != null ) { boolean analyseResources = currentScope . compilerOptions ( ) . analyseResourceLeaks ; for ( int i = 0 , max = this . arguments . length ; i < max ; i ++ ) { flowInfo = this . arguments [ i ] . analyseCode ( currentScope , flowContext , flowInfo ) . unconditionalInits ( ) ; if ( analyseResources ) { flowInfo = FakedTrackingVariable . markPassedToOutside ( currentScope , this . arguments [ i ] , flowInfo , false ) ; } if ( ( this . arguments [ i ] . implicitConversion & TypeIds . UNBOXING ) != 0 ) { this . arguments [ i ] . checkNPE ( currentScope , flowContext , flowInfo ) ; } } analyseArguments ( currentScope , flowContext , flowInfo , this . binding , this . arguments ) ; } ReferenceBinding [ ] thrownExceptions ; if ( ( thrownExceptions = this . binding . thrownExceptions ) != Binding . NO_EXCEPTIONS ) { if ( ( this . bits & ASTNode . Unchecked ) != 0 && this . genericTypeArguments == null ) { thrownExceptions = currentScope . environment ( ) . convertToRawTypes ( this . binding . thrownExceptions , true , true ) ; } flowContext . checkExceptionHandlers ( thrownExceptions , ( this . accessMode == ExplicitConstructorCall . ImplicitSuper ) ? ( ASTNode ) currentScope . methodScope ( ) . referenceContext : ( ASTNode ) this , flowInfo , currentScope ) ; } manageEnclosingInstanceAccessIfNecessary ( currentScope , flowInfo ) ; manageSyntheticAccessIfNecessary ( currentScope , flowInfo ) ; return flowInfo ; } finally { ( ( MethodScope ) currentScope ) . isConstructorCall = false ; } } public void generateCode ( BlockScope currentScope , CodeStream codeStream ) { if ( ( this . bits & ASTNode . IsReachable ) == 0 ) { return ; } try { ( ( MethodScope ) currentScope ) . isConstructorCall = true ; int pc = codeStream . position ; codeStream . aload_0 ( ) ; MethodBinding codegenBinding = this . binding . original ( ) ; ReferenceBinding targetType = codegenBinding . declaringClass ; if ( targetType . erasure ( ) . id == TypeIds . T_JavaLangEnum || targetType . isEnum ( ) ) { codeStream . aload_1 ( ) ; codeStream . iload_2 ( ) ; } if ( targetType . isNestedType ( ) ) { codeStream . generateSyntheticEnclosingInstanceValues ( currentScope , targetType , ( this . bits & ASTNode . DiscardEnclosingInstance ) != 0 ? null : this . qualification , this ) ; } generateArguments ( this . binding , this . arguments , currentScope , codeStream ) ; if ( targetType . isNestedType ( ) ) { codeStream . generateSyntheticOuterArgumentValues ( currentScope , targetType , this ) ; } if ( this . syntheticAccessor != null ) { for ( int i = 0 , max = this . syntheticAccessor . parameters . length - codegenBinding . parameters . length ; i < max ; i ++ ) { codeStream . aconst_null ( ) ; } codeStream . invoke ( Opcodes . OPC_invokespecial , this . syntheticAccessor , null ) ; } else { codeStream . invoke ( Opcodes . OPC_invokespecial , codegenBinding , null ) ; } codeStream . recordPositionsFrom ( pc , this . sourceStart ) ; } finally { ( ( MethodScope ) currentScope ) . isConstructorCall = false ; } } public TypeBinding [ ] genericTypeArguments ( ) { return this . genericTypeArguments ; } public boolean isImplicitSuper ( ) { return ( this . accessMode == ExplicitConstructorCall . ImplicitSuper ) ; } public boolean isSuperAccess ( ) { return this . accessMode != ExplicitConstructorCall . This ; } public boolean isTypeAccess ( ) { return true ; } void manageEnclosingInstanceAccessIfNecessary ( BlockScope currentScope , FlowInfo flowInfo ) { ReferenceBinding superTypeErasure = ( ReferenceBinding ) this . binding . declaringClass . erasure ( ) ; if ( ( flowInfo . tagBits & FlowInfo . UNREACHABLE_OR_DEAD ) == 0 ) { if ( superTypeErasure . isNestedType ( ) && currentScope . enclosingSourceType ( ) . isLocalType ( ) ) { if ( superTypeErasure . isLocalType ( ) ) { ( ( LocalTypeBinding ) superTypeErasure ) . addInnerEmulationDependent ( currentScope , this . qualification != null ) ; } else { currentScope . propagateInnerEmulation ( superTypeErasure , this . qualification != null ) ; } } } } public void manageSyntheticAccessIfNecessary ( BlockScope currentScope , FlowInfo flowInfo ) { if ( ( flowInfo . tagBits & FlowInfo . UNREACHABLE_OR_DEAD ) == 0 ) { MethodBinding codegenBinding = this . binding . original ( ) ; if ( this . binding . isPrivate ( ) && this . accessMode != ExplicitConstructorCall . This ) { ReferenceBinding declaringClass = codegenBinding . declaringClass ; if ( ( declaringClass . tagBits & TagBits . IsLocalType ) != 0 && currentScope . compilerOptions ( ) . complianceLevel >= ClassFileConstants . JDK1_4 ) { codegenBinding . tagBits |= TagBits . ClearPrivateModifier ; } else { this . syntheticAccessor = ( ( SourceTypeBinding ) declaringClass ) . addSyntheticMethod ( codegenBinding , isSuperAccess ( ) ) ; currentScope . problemReporter ( ) . needToEmulateMethodAccess ( codegenBinding , this ) ; } } } } public StringBuffer printStatement ( int indent , StringBuffer output ) { printIndent ( indent , output ) ; if ( this . qualification != null ) this . qualification . printExpression ( 0 , output ) . append ( '.' ) ; if ( this . typeArguments != null ) { output . append ( '<' ) ; int max = this . typeArguments . length - 1 ; for ( int j = 0 ; j < max ; j ++ ) { this . typeArguments [ j ] . print ( 0 , output ) ; output . append ( ", " ) ; } this . typeArguments [ max ] . print ( 0 , output ) ; output . append ( '>' ) ; } if ( this . accessMode == ExplicitConstructorCall . This ) { output . append ( "this(" ) ; } else { output . append ( "super(" ) ; } if ( this . arguments != null ) { for ( int i = 0 ; i < this . arguments . length ; i ++ ) { if ( i > 0 ) output . append ( ", " ) ; this . arguments [ i ] . printExpression ( 0 , output ) ; } } return output . append ( ");" ) ; } public void resolve ( BlockScope scope ) { MethodScope methodScope = scope . methodScope ( ) ; try { AbstractMethodDeclaration methodDeclaration = methodScope . referenceMethod ( ) ; if ( methodDeclaration == null || ! methodDeclaration . isConstructor ( ) || ( ( ConstructorDeclaration ) methodDeclaration ) . constructorCall != this ) { scope . problemReporter ( ) . invalidExplicitConstructorCall ( this ) ; if ( this . qualification != null ) { this . qualification . resolveType ( scope ) ; } if ( this . typeArguments != null ) { for ( int i = 0 , max = this . typeArguments . length ; i < max ; i ++ ) { this . typeArguments [ i ] . resolveType ( scope , true ) ; } } if ( this . arguments != null ) { for ( int i = 0 , max = this . arguments . length ; i < max ; i ++ ) { this . arguments [ i ] . resolveType ( scope ) ; } } return ; } methodScope . isConstructorCall = true ; ReferenceBinding receiverType = scope . enclosingReceiverType ( ) ; boolean rcvHasError = false ; if ( this . accessMode != ExplicitConstructorCall . This ) { receiverType = receiverType . superclass ( ) ; TypeReference superclassRef = scope . referenceType ( ) . superclass ; if ( superclassRef != null && superclassRef . resolvedType != null && ! superclassRef . resolvedType . isValidBinding ( ) ) { rcvHasError = true ; } } if ( receiverType != null ) { if ( this . accessMode == ExplicitConstructorCall . Super && receiverType . erasure ( ) . id == TypeIds . T_JavaLangEnum ) { scope . problemReporter ( ) . cannotInvokeSuperConstructorInEnum ( this , methodScope . referenceMethod ( ) . binding ) ; } if ( this . qualification != null ) { if ( this . accessMode != ExplicitConstructorCall . Super ) { scope . problemReporter ( ) . unnecessaryEnclosingInstanceSpecification ( this . qualification , receiverType ) ; } if ( ! rcvHasError ) { ReferenceBinding enclosingType = receiverType . enclosingType ( ) ; if ( enclosingType == null ) { scope . problemReporter ( ) . unnecessaryEnclosingInstanceSpecification ( this . qualification , receiverType ) ; this . bits |= ASTNode . DiscardEnclosingInstance ; } else { TypeBinding qTb = this . qualification . resolveTypeExpecting ( scope , enclosingType ) ; this . qualification . computeConversion ( scope , qTb , qTb ) ; } } } } if ( this . typeArguments != null ) { boolean argHasError = scope . compilerOptions ( ) . sourceLevel < ClassFileConstants . JDK1_5 ; int length = this . typeArguments . length ; this . genericTypeArguments = new TypeBinding [ length ] ; for ( int i = 0 ; i < length ; i ++ ) { TypeReference typeReference = this . typeArguments [ i ] ; if ( ( this . genericTypeArguments [ i ] = typeReference . resolveType ( scope , true ) ) == null ) { argHasError = true ; } if ( argHasError && typeReference instanceof Wildcard ) { scope . problemReporter ( ) . illegalUsageOfWildcard ( typeReference ) ; } } if ( argHasError ) { if ( this . arguments != null ) { for ( int i = 0 , max = this . arguments . length ; i < max ; i ++ ) { this . arguments [ i ] . resolveType ( scope ) ; } } return ; } } TypeBinding [ ] argumentTypes = Binding . NO_PARAMETERS ; boolean argsContainCast = false ; if ( this . arguments != null ) { boolean argHasError = false ; int length = this . arguments . length ; argumentTypes = new TypeBinding [ length ] ; for ( int i = 0 ; i < length ; i ++ ) { Expression argument = this . arguments [ i ] ; if ( argument instanceof CastExpression ) { argument . bits |= ASTNode . DisableUnnecessaryCastCheck ; argsContainCast = true ; } if ( ( argumentTypes [ i ] = argument . resolveType ( scope ) ) == null ) { argHasError = true ; } } if ( argHasError ) { if ( receiverType == null ) { return ; } TypeBinding [ ] pseudoArgs = new TypeBinding [ length ] ; for ( int i = length ; -- i >= 0 ; ) { pseudoArgs [ i ] = argumentTypes [ i ] == null ? TypeBinding . NULL : argumentTypes [ i ] ; } this . binding = scope . findMethod ( receiverType , TypeConstants . INIT , pseudoArgs , this ) ; if ( this . binding != null && ! this . binding . isValidBinding ( ) ) { MethodBinding closestMatch = ( ( ProblemMethodBinding ) this . binding ) . closestMatch ; if ( closestMatch != null ) { if ( closestMatch . original ( ) . typeVariables != Binding . NO_TYPE_VARIABLES ) { closestMatch = scope . environment ( ) . createParameterizedGenericMethod ( closestMatch . original ( ) , ( RawTypeBinding ) null ) ; } this . binding = closestMatch ; MethodBinding closestMatchOriginal = closestMatch . original ( ) ; if ( closestMatchOriginal . isOrEnclosedByPrivateType ( ) && ! scope . isDefinedInMethod ( closestMatchOriginal ) ) { closestMatchOriginal . modifiers |= ExtraCompilerModifiers . AccLocallyUsed ; } } } return ; } } else if ( receiverType . erasure ( ) . id == TypeIds . T_JavaLangEnum ) { argumentTypes = new TypeBinding [ ] { scope . getJavaLangString ( ) , TypeBinding . INT } ; } if ( receiverType == null ) { return ; } if ( ( this . binding = scope . getConstructor ( receiverType , argumentTypes , this ) ) . isValidBinding ( ) ) { if ( ( this . binding . tagBits & TagBits . HasMissingType ) != 0 ) { if ( ! methodScope . enclosingSourceType ( ) . isAnonymousType ( ) ) { scope . problemReporter ( ) . missingTypeInConstructor ( this , this . binding ) ; } } if ( isMethodUseDeprecated ( this . binding , scope , this . accessMode != ExplicitConstructorCall . ImplicitSuper ) ) { scope . problemReporter ( ) . deprecatedMethod ( this . binding , this ) ; } if ( checkInvocationArguments ( scope , null , receiverType , this . binding , this . arguments , argumentTypes , argsContainCast , this ) ) { this . bits |= ASTNode . Unchecked ; } if ( this . binding . isOrEnclosedByPrivateType ( ) ) { this . binding . original ( ) . modifiers |= ExtraCompilerModifiers . AccLocallyUsed ; } if ( this . typeArguments != null && this . binding . original ( ) . typeVariables == Binding . NO_TYPE_VARIABLES ) { scope . problemReporter ( ) . unnecessaryTypeArgumentsForMethodInvocation ( this . binding , this . genericTypeArguments , this . typeArguments ) ; } } else { if ( this . binding . declaringClass == null ) { this . binding . declaringClass = receiverType ; } if ( rcvHasError ) return ; scope . problemReporter ( ) . invalidConstructor ( this , this . binding ) ; } } finally { methodScope . isConstructorCall = false ; } } public void setActualReceiverType ( ReferenceBinding receiverType ) { } public void setDepth ( int depth ) { } public void setFieldIndex ( int depth ) { } public void traverse ( ASTVisitor visitor , BlockScope scope ) { if ( visitor . visit ( this , scope ) ) { if ( this . qualification != null ) { this . qualification . traverse ( visitor , scope ) ; } if ( this . typeArguments != null ) { for ( int i = 0 , typeArgumentsLength = this . typeArguments . length ; i < typeArgumentsLength ; i ++ ) { this . typeArguments [ i ] . traverse ( visitor , scope ) ; } } if ( this . arguments != null ) { for ( int i = 0 , argumentLength = this . arguments . length ; i < argumentLength ; i ++ ) this . arguments [ i ] . traverse ( visitor , scope ) ; } } visitor . endVisit ( this , scope ) ; } } </s>