<s> package org . eclipse . jdt . internal . compiler . lookup ; import java . util . * ; import org . eclipse . jdt . core . compiler . CharOperation ; import org . eclipse . jdt . internal . compiler . ast . * ; import org . eclipse . jdt . internal . compiler . classfmt . ClassFileConstants ; import org . eclipse . jdt . internal . compiler . impl . CompilerOptions ; import org . eclipse . jdt . internal . compiler . impl . ReferenceContext ; import org . eclipse . jdt . internal . compiler . problem . AbortCompilation ; import org . eclipse . jdt . internal . compiler . problem . ProblemReporter ; import org . eclipse . jdt . internal . compiler . util . HashtableOfObject ; import org . eclipse . jdt . internal . compiler . util . ObjectVector ; import org . eclipse . jdt . internal . compiler . util . SimpleLookupTable ; import org . eclipse . jdt . internal . compiler . util . SimpleSet ; public abstract class Scope { public final static int BLOCK_SCOPE = 1 ; public final static int CLASS_SCOPE = 3 ; public final static int COMPILATION_UNIT_SCOPE = 4 ; public final static int METHOD_SCOPE = 2 ; public final static int NOT_COMPATIBLE = - 1 ; public final static int COMPATIBLE = 0 ; public final static int AUTOBOX_COMPATIBLE = 1 ; public final static int VARARGS_COMPATIBLE = 2 ; public static final int EQUAL_OR_MORE_SPECIFIC = - 1 ; public static final int NOT_RELATED = 0 ; public static final int MORE_GENERIC = 1 ; public int kind ; public Scope parent ; protected Scope ( int kind , Scope parent ) { this . kind = kind ; this . parent = parent ; } public static int compareTypes ( TypeBinding left , TypeBinding right ) { if ( left . isCompatibleWith ( right ) ) return Scope . EQUAL_OR_MORE_SPECIFIC ; if ( right . isCompatibleWith ( left ) ) return Scope . MORE_GENERIC ; return Scope . NOT_RELATED ; } public static TypeBinding convertEliminatingTypeVariables ( TypeBinding originalType , ReferenceBinding genericType , int rank , Set eliminatedVariables ) { if ( ( originalType . tagBits & TagBits . HasTypeVariable ) != 0 ) { switch ( originalType . kind ( ) ) { case Binding . ARRAY_TYPE : ArrayBinding originalArrayType = ( ArrayBinding ) originalType ; TypeBinding originalLeafComponentType = originalArrayType . leafComponentType ; TypeBinding substitute = convertEliminatingTypeVariables ( originalLeafComponentType , genericType , rank , eliminatedVariables ) ; if ( substitute != originalLeafComponentType ) { return originalArrayType . environment . createArrayType ( substitute . leafComponentType ( ) , substitute . dimensions ( ) + originalArrayType . dimensions ( ) ) ; } break ; case Binding . PARAMETERIZED_TYPE : ParameterizedTypeBinding paramType = ( ParameterizedTypeBinding ) originalType ; ReferenceBinding originalEnclosing = paramType . enclosingType ( ) ; ReferenceBinding substitutedEnclosing = originalEnclosing ; if ( originalEnclosing != null ) { substitutedEnclosing = ( ReferenceBinding ) convertEliminatingTypeVariables ( originalEnclosing , genericType , rank , eliminatedVariables ) ; } TypeBinding [ ] originalArguments = paramType . arguments ; TypeBinding [ ] substitutedArguments = originalArguments ; for ( int i = 0 , length = originalArguments == null ? 0 : originalArguments . length ; i < length ; i ++ ) { TypeBinding originalArgument = originalArguments [ i ] ; TypeBinding substitutedArgument = convertEliminatingTypeVariables ( originalArgument , paramType . genericType ( ) , i , eliminatedVariables ) ; if ( substitutedArgument != originalArgument ) { if ( substitutedArguments == originalArguments ) { System . arraycopy ( originalArguments , 0 , substitutedArguments = new TypeBinding [ length ] , 0 , i ) ; } substitutedArguments [ i ] = substitutedArgument ; } else if ( substitutedArguments != originalArguments ) { substitutedArguments [ i ] = originalArgument ; } } if ( originalEnclosing != substitutedEnclosing || originalArguments != substitutedArguments ) { return paramType . environment . createParameterizedType ( paramType . genericType ( ) , substitutedArguments , substitutedEnclosing ) ; } break ; case Binding . TYPE_PARAMETER : if ( genericType == null ) { break ; } TypeVariableBinding originalVariable = ( TypeVariableBinding ) originalType ; if ( eliminatedVariables != null && eliminatedVariables . contains ( originalType ) ) { return originalVariable . environment . createWildcard ( genericType , rank , null , null , Wildcard . UNBOUND ) ; } TypeBinding originalUpperBound = originalVariable . upperBound ( ) ; if ( eliminatedVariables == null ) { eliminatedVariables = new HashSet ( 2 ) ; } eliminatedVariables . add ( originalVariable ) ; TypeBinding substitutedUpperBound = convertEliminatingTypeVariables ( originalUpperBound , genericType , rank , eliminatedVariables ) ; eliminatedVariables . remove ( originalVariable ) ; return originalVariable . environment . createWildcard ( genericType , rank , substitutedUpperBound , null , Wildcard . EXTENDS ) ; case Binding . RAW_TYPE : break ; case Binding . GENERIC_TYPE : ReferenceBinding currentType = ( ReferenceBinding ) originalType ; originalEnclosing = currentType . enclosingType ( ) ; substitutedEnclosing = originalEnclosing ; if ( originalEnclosing != null ) { substitutedEnclosing = ( ReferenceBinding ) convertEliminatingTypeVariables ( originalEnclosing , genericType , rank , eliminatedVariables ) ; } originalArguments = currentType . typeVariables ( ) ; substitutedArguments = originalArguments ; for ( int i = 0 , length = originalArguments == null ? 0 : originalArguments . length ; i < length ; i ++ ) { TypeBinding originalArgument = originalArguments [ i ] ; TypeBinding substitutedArgument = convertEliminatingTypeVariables ( originalArgument , currentType , i , eliminatedVariables ) ; if ( substitutedArgument != originalArgument ) { if ( substitutedArguments == originalArguments ) { System . arraycopy ( originalArguments , 0 , substitutedArguments = new TypeBinding [ length ] , 0 , i ) ; } substitutedArguments [ i ] = substitutedArgument ; } else if ( substitutedArguments != originalArguments ) { substitutedArguments [ i ] = originalArgument ; } } if ( originalEnclosing != substitutedEnclosing || originalArguments != substitutedArguments ) { return ( ( TypeVariableBinding ) originalArguments [ 0 ] ) . environment . createParameterizedType ( genericType , substitutedArguments , substitutedEnclosing ) ; } break ; case Binding . WILDCARD_TYPE : WildcardBinding wildcard = ( WildcardBinding ) originalType ; TypeBinding originalBound = wildcard . bound ; TypeBinding substitutedBound = originalBound ; if ( originalBound != null ) { substitutedBound = convertEliminatingTypeVariables ( originalBound , genericType , rank , eliminatedVariables ) ; if ( substitutedBound != originalBound ) { return wildcard . environment . createWildcard ( wildcard . genericType , wildcard . rank , substitutedBound , null , wildcard . boundKind ) ; } } break ; case Binding . INTERSECTION_TYPE : WildcardBinding intersection = ( WildcardBinding ) originalType ; originalBound = intersection . bound ; substitutedBound = originalBound ; if ( originalBound != null ) { substitutedBound = convertEliminatingTypeVariables ( originalBound , genericType , rank , eliminatedVariables ) ; } TypeBinding [ ] originalOtherBounds = intersection . otherBounds ; TypeBinding [ ] substitutedOtherBounds = originalOtherBounds ; for ( int i = 0 , length = originalOtherBounds == null ? 0 : originalOtherBounds . length ; i < length ; i ++ ) { TypeBinding originalOtherBound = originalOtherBounds [ i ] ; TypeBinding substitutedOtherBound = convertEliminatingTypeVariables ( originalOtherBound , genericType , rank , eliminatedVariables ) ; if ( substitutedOtherBound != originalOtherBound ) { if ( substitutedOtherBounds == originalOtherBounds ) { System . arraycopy ( originalOtherBounds , 0 , substitutedOtherBounds = new TypeBinding [ length ] , 0 , i ) ; } substitutedOtherBounds [ i ] = substitutedOtherBound ; } else if ( substitutedOtherBounds != originalOtherBounds ) { substitutedOtherBounds [ i ] = originalOtherBound ; } } if ( substitutedBound != originalBound || substitutedOtherBounds != originalOtherBounds ) { return intersection . environment . createWildcard ( intersection . genericType , intersection . rank , substitutedBound , substitutedOtherBounds , intersection . boundKind ) ; } break ; } } return originalType ; } public static TypeBinding getBaseType ( char [ ] name ) { int length = name . length ; if ( length > 2 && length < 8 ) { switch ( name [ 0 ] ) { case 'i' : if ( length == 3 && name [ 1 ] == 'n' && name [ 2 ] == 't' ) return TypeBinding . INT ; break ; case 'v' : if ( length == 4 && name [ 1 ] == 'o' && name [ 2 ] == 'i' && name [ 3 ] == 'd' ) return TypeBinding . VOID ; break ; case 'b' : if ( length == 7 && name [ 1 ] == 'o' && name [ 2 ] == 'o' && name [ 3 ] == 'l' && name [ 4 ] == 'e' && name [ 5 ] == 'a' && name [ 6 ] == 'n' ) return TypeBinding . BOOLEAN ; if ( length == 4 && name [ 1 ] == 'y' && name [ 2 ] == 't' && name [ 3 ] == 'e' ) return TypeBinding . BYTE ; break ; case 'c' : if ( length == 4 && name [ 1 ] == 'h' && name [ 2 ] == 'a' && name [ 3 ] == 'r' ) return TypeBinding . CHAR ; break ; case 'd' : if ( length == 6 && name [ 1 ] == 'o' && name [ 2 ] == 'u' && name [ 3 ] == 'b' && name [ 4 ] == 'l' && name [ 5 ] == 'e' ) return TypeBinding . DOUBLE ; break ; case 'f' : if ( length == 5 && name [ 1 ] == 'l' && name [ 2 ] == 'o' && name [ 3 ] == 'a' && name [ 4 ] == 't' ) return TypeBinding . FLOAT ; break ; case 'l' : if ( length == 4 && name [ 1 ] == 'o' && name [ 2 ] == 'n' && name [ 3 ] == 'g' ) return TypeBinding . LONG ; break ; case 's' : if ( length == 5 && name [ 1 ] == 'h' && name [ 2 ] == 'o' && name [ 3 ] == 'r' && name [ 4 ] == 't' ) return TypeBinding . SHORT ; } } return null ; } public static ReferenceBinding [ ] greaterLowerBound ( ReferenceBinding [ ] types ) { if ( types == null ) return null ; int length = types . length ; if ( length == 0 ) return null ; ReferenceBinding [ ] result = types ; int removed = 0 ; for ( int i = 0 ; i < length ; i ++ ) { ReferenceBinding iType = result [ i ] ; if ( iType == null ) continue ; for ( int j = 0 ; j < length ; j ++ ) { if ( i == j ) continue ; ReferenceBinding jType = result [ j ] ; if ( jType == null ) continue ; if ( iType . isCompatibleWith ( jType ) ) { if ( result == types ) { System . arraycopy ( result , 0 , result = new ReferenceBinding [ length ] , 0 , length ) ; } result [ j ] = null ; removed ++ ; } } } if ( removed == 0 ) return result ; if ( length == removed ) return null ; ReferenceBinding [ ] trimmedResult = new ReferenceBinding [ length - removed ] ; for ( int i = 0 , index = 0 ; i < length ; i ++ ) { ReferenceBinding iType = result [ i ] ; if ( iType != null ) { trimmedResult [ index ++ ] = iType ; } } return trimmedResult ; } public static TypeBinding [ ] greaterLowerBound ( TypeBinding [ ] types ) { if ( types == null ) return null ; int length = types . length ; if ( length == 0 ) return null ; TypeBinding [ ] result = types ; int removed = 0 ; for ( int i = 0 ; i < length ; i ++ ) { TypeBinding iType = result [ i ] ; if ( iType == null ) continue ; for ( int j = 0 ; j < length ; j ++ ) { if ( i == j ) continue ; TypeBinding jType = result [ j ] ; if ( jType == null ) continue ; if ( iType . isCompatibleWith ( jType ) ) { if ( result == types ) { System . arraycopy ( result , 0 , result = new TypeBinding [ length ] , 0 , length ) ; } result [ j ] = null ; removed ++ ; } } } if ( removed == 0 ) return result ; if ( length == removed ) return null ; TypeBinding [ ] trimmedResult = new TypeBinding [ length - removed ] ; for ( int i = 0 , index = 0 ; i < length ; i ++ ) { TypeBinding iType = result [ i ] ; if ( iType != null ) { trimmedResult [ index ++ ] = iType ; } } return trimmedResult ; } public static ReferenceBinding [ ] substitute ( Substitution substitution , ReferenceBinding [ ] originalTypes ) { if ( originalTypes == null ) return null ; ReferenceBinding [ ] substitutedTypes = originalTypes ; for ( int i = 0 , length = originalTypes . length ; i < length ; i ++ ) { ReferenceBinding originalType = originalTypes [ i ] ; TypeBinding substitutedType = substitute ( substitution , originalType ) ; if ( ! ( substitutedType instanceof ReferenceBinding ) ) { return null ; } if ( substitutedType != originalType ) { if ( substitutedTypes == originalTypes ) { System . arraycopy ( originalTypes , 0 , substitutedTypes = new ReferenceBinding [ length ] , 0 , i ) ; } substitutedTypes [ i ] = ( ReferenceBinding ) substitutedType ; } else if ( substitutedTypes != originalTypes ) { substitutedTypes [ i ] = originalType ; } } return substitutedTypes ; } public static TypeBinding substitute ( Substitution substitution , TypeBinding originalType ) { if ( originalType == null ) return null ; switch ( originalType . kind ( ) ) { case Binding . TYPE_PARAMETER : return substitution . substitute ( ( TypeVariableBinding ) originalType ) ; case Binding . PARAMETERIZED_TYPE : ParameterizedTypeBinding originalParameterizedType = ( ParameterizedTypeBinding ) originalType ; ReferenceBinding originalEnclosing = originalType . enclosingType ( ) ; ReferenceBinding substitutedEnclosing = originalEnclosing ; if ( originalEnclosing != null ) { substitutedEnclosing = ( ReferenceBinding ) substitute ( substitution , originalEnclosing ) ; } TypeBinding [ ] originalArguments = originalParameterizedType . arguments ; TypeBinding [ ] substitutedArguments = originalArguments ; if ( originalArguments != null ) { if ( substitution . isRawSubstitution ( ) ) { return originalParameterizedType . environment . createRawType ( originalParameterizedType . genericType ( ) , substitutedEnclosing ) ; } substitutedArguments = substitute ( substitution , originalArguments ) ; } if ( substitutedArguments != originalArguments || substitutedEnclosing != originalEnclosing ) { return originalParameterizedType . environment . createParameterizedType ( originalParameterizedType . genericType ( ) , substitutedArguments , substitutedEnclosing ) ; } break ; case Binding . ARRAY_TYPE : ArrayBinding originalArrayType = ( ArrayBinding ) originalType ; TypeBinding originalLeafComponentType = originalArrayType . leafComponentType ; TypeBinding substitute = substitute ( substitution , originalLeafComponentType ) ; if ( substitute != originalLeafComponentType ) { return originalArrayType . environment . createArrayType ( substitute . leafComponentType ( ) , substitute . dimensions ( ) + originalType . dimensions ( ) ) ; } break ; case Binding . WILDCARD_TYPE : case Binding . INTERSECTION_TYPE : WildcardBinding wildcard = ( WildcardBinding ) originalType ; if ( wildcard . boundKind != Wildcard . UNBOUND ) { TypeBinding originalBound = wildcard . bound ; TypeBinding substitutedBound = substitute ( substitution , originalBound ) ; TypeBinding [ ] originalOtherBounds = wildcard . otherBounds ; TypeBinding [ ] substitutedOtherBounds = substitute ( substitution , originalOtherBounds ) ; if ( substitutedBound != originalBound || originalOtherBounds != substitutedOtherBounds ) { if ( originalOtherBounds != null ) { TypeBinding [ ] bounds = new TypeBinding [ 1 + substitutedOtherBounds . length ] ; bounds [ 0 ] = substitutedBound ; System . arraycopy ( substitutedOtherBounds , 0 , bounds , 1 , substitutedOtherBounds . length ) ; TypeBinding [ ] glb = Scope . greaterLowerBound ( bounds ) ; if ( glb != null && glb != bounds ) { substitutedBound = glb [ 0 ] ; if ( glb . length == 1 ) { substitutedOtherBounds = null ; } else { System . arraycopy ( glb , 1 , substitutedOtherBounds = new TypeBinding [ glb . length - 1 ] , 0 , glb . length - 1 ) ; } } } return wildcard . environment . createWildcard ( wildcard . genericType , wildcard . rank , substitutedBound , substitutedOtherBounds , wildcard . boundKind ) ; } } break ; case Binding . TYPE : if ( ! originalType . isMemberType ( ) ) break ; ReferenceBinding originalReferenceType = ( ReferenceBinding ) originalType ; originalEnclosing = originalType . enclosingType ( ) ; substitutedEnclosing = originalEnclosing ; if ( originalEnclosing != null ) { substitutedEnclosing = ( ReferenceBinding ) substitute ( substitution , originalEnclosing ) ; } if ( substitutedEnclosing != originalEnclosing ) { return substitution . isRawSubstitution ( ) ? substitution . environment ( ) . createRawType ( originalReferenceType , substitutedEnclosing ) : substitution . environment ( ) . createParameterizedType ( originalReferenceType , null , substitutedEnclosing ) ; } break ; case Binding . GENERIC_TYPE : originalReferenceType = ( ReferenceBinding ) originalType ; originalEnclosing = originalType . enclosingType ( ) ; substitutedEnclosing = originalEnclosing ; if ( originalEnclosing != null ) { substitutedEnclosing = ( ReferenceBinding ) substitute ( substitution , originalEnclosing ) ; } if ( substitution . isRawSubstitution ( ) ) { return substitution . environment ( ) . createRawType ( originalReferenceType , substitutedEnclosing ) ; } originalArguments = originalReferenceType . typeVariables ( ) ; substitutedArguments = substitute ( substitution , originalArguments ) ; return substitution . environment ( ) . createParameterizedType ( originalReferenceType , substitutedArguments , substitutedEnclosing ) ; } return originalType ; } public static TypeBinding [ ] substitute ( Substitution substitution , TypeBinding [ ] originalTypes ) { if ( originalTypes == null ) return null ; TypeBinding [ ] substitutedTypes = originalTypes ; for ( int i = 0 , length = originalTypes . length ; i < length ; i ++ ) { TypeBinding originalType = originalTypes [ i ] ; TypeBinding substitutedParameter = substitute ( substitution , originalType ) ; if ( substitutedParameter != originalType ) { if ( substitutedTypes == originalTypes ) { System . arraycopy ( originalTypes , 0 , substitutedTypes = new TypeBinding [ length ] , 0 , i ) ; } substitutedTypes [ i ] = substitutedParameter ; } else if ( substitutedTypes != originalTypes ) { substitutedTypes [ i ] = originalType ; } } return substitutedTypes ; } public TypeBinding boxing ( TypeBinding type ) { if ( type . isBaseType ( ) ) return environment ( ) . computeBoxingType ( type ) ; return type ; } public final ClassScope classScope ( ) { Scope scope = this ; do { if ( scope instanceof ClassScope ) return ( ClassScope ) scope ; scope = scope . parent ; } while ( scope != null ) ; return null ; } public final CompilationUnitScope compilationUnitScope ( ) { Scope lastScope = null ; Scope scope = this ; do { lastScope = scope ; scope = scope . parent ; } while ( scope != null ) ; return ( CompilationUnitScope ) lastScope ; } public final CompilerOptions compilerOptions ( ) { return compilationUnitScope ( ) . environment . globalOptions ; } protected final MethodBinding computeCompatibleMethod ( MethodBinding method , TypeBinding [ ] arguments , InvocationSite invocationSite ) { TypeBinding [ ] genericTypeArguments = invocationSite . genericTypeArguments ( ) ; TypeBinding [ ] parameters = method . parameters ; TypeVariableBinding [ ] typeVariables = method . typeVariables ; if ( parameters == arguments && ( method . returnType . tagBits & TagBits . HasTypeVariable ) == 0 && genericTypeArguments == null && typeVariables == Binding . NO_TYPE_VARIABLES ) return method ; int argLength = arguments . length ; int paramLength = parameters . length ; boolean isVarArgs = method . isVarargs ( ) ; if ( argLength != paramLength ) if ( ! isVarArgs || argLength < paramLength - 1 ) return null ; if ( typeVariables != Binding . NO_TYPE_VARIABLES && compilerOptions ( ) . sourceLevel >= ClassFileConstants . JDK1_5 ) { TypeBinding [ ] newArgs = null ; for ( int i = 0 ; i < argLength ; i ++ ) { TypeBinding param = i < paramLength ? parameters [ i ] : parameters [ paramLength - 1 ] ; if ( arguments [ i ] . isBaseType ( ) != param . isBaseType ( ) ) { if ( newArgs == null ) { newArgs = new TypeBinding [ argLength ] ; System . arraycopy ( arguments , 0 , newArgs , 0 , argLength ) ; } newArgs [ i ] = environment ( ) . computeBoxingType ( arguments [ i ] ) ; } } if ( newArgs != null ) arguments = newArgs ; method = ParameterizedGenericMethodBinding . computeCompatibleMethod ( method , arguments , this , invocationSite ) ; if ( method == null ) return null ; if ( ! method . isValidBinding ( ) ) return method ; } else if ( genericTypeArguments != null && compilerOptions ( ) . complianceLevel < ClassFileConstants . JDK1_7 ) { if ( method instanceof ParameterizedGenericMethodBinding ) { if ( ! ( ( ParameterizedGenericMethodBinding ) method ) . wasInferred ) return new ProblemMethodBinding ( method , method . selector , genericTypeArguments , ProblemReasons . TypeArgumentsForRawGenericMethod ) ; } else if ( ! method . isOverriding ( ) || ! isOverriddenMethodGeneric ( method ) ) { return new ProblemMethodBinding ( method , method . selector , genericTypeArguments , ProblemReasons . TypeParameterArityMismatch ) ; } } if ( parameterCompatibilityLevel ( method , arguments ) > NOT_COMPATIBLE ) { if ( ( method . tagBits & TagBits . AnnotationPolymorphicSignature ) != 0 ) { return this . environment ( ) . createPolymorphicMethod ( method , arguments ) ; } return method ; } if ( genericTypeArguments != null && typeVariables != Binding . NO_TYPE_VARIABLES ) return new ProblemMethodBinding ( method , method . selector , arguments , ProblemReasons . ParameterizedMethodTypeMismatch ) ; return null ; } protected boolean connectTypeVariables ( TypeParameter [ ] typeParameters , boolean checkForErasedCandidateCollisions ) { if ( typeParameters == null || typeParameters . length == 0 ) return true ; Map invocations = new HashMap ( 2 ) ; boolean noProblems = true ; for ( int i = 0 , paramLength = typeParameters . length ; i < paramLength ; i ++ ) { TypeParameter typeParameter = typeParameters [ i ] ; TypeVariableBinding typeVariable = typeParameter . binding ; if ( typeVariable == null ) return false ; typeVariable . superclass = getJavaLangObject ( ) ; typeVariable . superInterfaces = Binding . NO_SUPERINTERFACES ; typeVariable . firstBound = null ; } nextVariable : for ( int i = 0 , paramLength = typeParameters . length ; i < paramLength ; i ++ ) { TypeParameter typeParameter = typeParameters [ i ] ; TypeVariableBinding typeVariable = typeParameter . binding ; TypeReference typeRef = typeParameter . type ; if ( typeRef == null ) continue nextVariable ; boolean isFirstBoundTypeVariable = false ; TypeBinding superType = this . kind == METHOD_SCOPE ? typeRef . resolveType ( ( BlockScope ) this , false ) : typeRef . resolveType ( ( ClassScope ) this ) ; if ( superType == null ) { typeVariable . tagBits |= TagBits . HierarchyHasProblems ; } else { typeRef . resolvedType = superType ; firstBound : { switch ( superType . kind ( ) ) { case Binding . ARRAY_TYPE : problemReporter ( ) . boundCannotBeArray ( typeRef , superType ) ; typeVariable . tagBits |= TagBits . HierarchyHasProblems ; break firstBound ; case Binding . TYPE_PARAMETER : isFirstBoundTypeVariable = true ; TypeVariableBinding varSuperType = ( TypeVariableBinding ) superType ; if ( varSuperType . rank >= typeVariable . rank && varSuperType . declaringElement == typeVariable . declaringElement ) { if ( compilerOptions ( ) . complianceLevel <= ClassFileConstants . JDK1_6 ) { problemReporter ( ) . forwardTypeVariableReference ( typeParameter , varSuperType ) ; typeVariable . tagBits |= TagBits . HierarchyHasProblems ; break firstBound ; } } if ( compilerOptions ( ) . complianceLevel > ClassFileConstants . JDK1_6 ) { if ( typeVariable . rank >= varSuperType . rank && varSuperType . declaringElement == typeVariable . declaringElement ) { SimpleSet set = new SimpleSet ( typeParameters . length ) ; set . add ( typeVariable ) ; ReferenceBinding superBinding = varSuperType ; while ( superBinding instanceof TypeVariableBinding ) { if ( set . includes ( superBinding ) ) { problemReporter ( ) . hierarchyCircularity ( typeVariable , varSuperType , typeRef ) ; typeVariable . tagBits |= TagBits . HierarchyHasProblems ; break firstBound ; } else { set . add ( superBinding ) ; superBinding = ( ( TypeVariableBinding ) superBinding ) . superclass ; } } } } break ; default : if ( ( ( ReferenceBinding ) superType ) . isFinal ( ) ) { problemReporter ( ) . finalVariableBound ( typeVariable , typeRef ) ; } break ; } ReferenceBinding superRefType = ( ReferenceBinding ) superType ; if ( ! superType . isInterface ( ) ) { typeVariable . superclass = superRefType ; } else { typeVariable . superInterfaces = new ReferenceBinding [ ] { superRefType } ; } typeVariable . tagBits |= superType . tagBits & TagBits . ContainsNestedTypeReferences ; typeVariable . firstBound = superRefType ; } } TypeReference [ ] boundRefs = typeParameter . bounds ; if ( boundRefs != null ) { nextBound : for ( int j = 0 , boundLength = boundRefs . length ; j < boundLength ; j ++ ) { typeRef = boundRefs [ j ] ; superType = this . kind == METHOD_SCOPE ? typeRef . resolveType ( ( BlockScope ) this , false ) : typeRef . resolveType ( ( ClassScope ) this ) ; if ( superType == null ) { typeVariable . tagBits |= TagBits . HierarchyHasProblems ; continue nextBound ; } else { typeVariable . tagBits |= superType . tagBits & TagBits . ContainsNestedTypeReferences ; boolean didAlreadyComplain = ! typeRef . resolvedType . isValidBinding ( ) ; if ( isFirstBoundTypeVariable && j == 0 ) { problemReporter ( ) . noAdditionalBoundAfterTypeVariable ( typeRef ) ; typeVariable . tagBits |= TagBits . HierarchyHasProblems ; didAlreadyComplain = true ; } else if ( superType . isArrayType ( ) ) { if ( ! didAlreadyComplain ) { problemReporter ( ) . boundCannotBeArray ( typeRef , superType ) ; typeVariable . tagBits |= TagBits . HierarchyHasProblems ; } continue nextBound ; } else { if ( ! superType . isInterface ( ) ) { if ( ! didAlreadyComplain ) { problemReporter ( ) . boundMustBeAnInterface ( typeRef , superType ) ; typeVariable . tagBits |= TagBits . HierarchyHasProblems ; } continue nextBound ; } } if ( checkForErasedCandidateCollisions && typeVariable . firstBound == typeVariable . superclass ) { if ( hasErasedCandidatesCollisions ( superType , typeVariable . superclass , invocations , typeVariable , typeRef ) ) { continue nextBound ; } } ReferenceBinding superRefType = ( ReferenceBinding ) superType ; for ( int index = typeVariable . superInterfaces . length ; -- index >= 0 ; ) { ReferenceBinding previousInterface = typeVariable . superInterfaces [ index ] ; if ( previousInterface == superRefType ) { problemReporter ( ) . duplicateBounds ( typeRef , superType ) ; typeVariable . tagBits |= TagBits . HierarchyHasProblems ; continue nextBound ; } if ( checkForErasedCandidateCollisions ) { if ( hasErasedCandidatesCollisions ( superType , previousInterface , invocations , typeVariable , typeRef ) ) { continue nextBound ; } } } int size = typeVariable . superInterfaces . length ; System . arraycopy ( typeVariable . superInterfaces , 0 , typeVariable . superInterfaces = new ReferenceBinding [ size + 1 ] , 0 , size ) ; typeVariable . superInterfaces [ size ] = superRefType ; } } } noProblems &= ( typeVariable . tagBits & TagBits . HierarchyHasProblems ) == 0 ; } return noProblems ; } public ArrayBinding createArrayType ( TypeBinding type , int dimension ) { if ( type . isValidBinding ( ) ) return environment ( ) . createArrayType ( type , dimension ) ; return new ArrayBinding ( type , dimension , environment ( ) ) ; } public TypeVariableBinding [ ] createTypeVariables ( TypeParameter [ ] typeParameters , Binding declaringElement ) { if ( typeParameters == null || typeParameters . length == 0 ) return Binding . NO_TYPE_VARIABLES ; PackageBinding unitPackage = compilationUnitScope ( ) . fPackage ; int length = typeParameters . length ; TypeVariableBinding [ ] typeVariableBindings = new TypeVariableBinding [ length ] ; int count = 0 ; for ( int i = 0 ; i < length ; i ++ ) { TypeParameter typeParameter = typeParameters [ i ] ; TypeVariableBinding parameterBinding = new TypeVariableBinding ( typeParameter . name , declaringElement , i , environment ( ) ) ; parameterBinding . fPackage = unitPackage ; typeParameter . binding = parameterBinding ; for ( int j = 0 ; j < count ; j ++ ) { TypeVariableBinding knownVar = typeVariableBindings [ j ] ; if ( CharOperation . equals ( knownVar . sourceName , typeParameter . name ) ) problemReporter ( ) . duplicateTypeParameterInType ( typeParameter ) ; } typeVariableBindings [ count ++ ] = parameterBinding ; } if ( count != length ) System . arraycopy ( typeVariableBindings , 0 , typeVariableBindings = new TypeVariableBinding [ count ] , 0 , count ) ; return typeVariableBindings ; } public final ClassScope enclosingClassScope ( ) { Scope scope = this ; while ( ( scope = scope . parent ) != null ) { if ( scope instanceof ClassScope ) return ( ClassScope ) scope ; } return null ; } public final MethodScope enclosingMethodScope ( ) { Scope scope = this ; while ( ( scope = scope . parent ) != null ) { if ( scope instanceof MethodScope ) return ( MethodScope ) scope ; } return null ; } public final ReferenceBinding enclosingReceiverType ( ) { Scope scope = this ; do { if ( scope instanceof ClassScope ) { return environment ( ) . convertToParameterizedType ( ( ( ClassScope ) scope ) . referenceContext . binding ) ; } scope = scope . parent ; } while ( scope != null ) ; return null ; } public ReferenceContext enclosingReferenceContext ( ) { Scope current = this ; while ( ( current = current . parent ) != null ) { switch ( current . kind ) { case METHOD_SCOPE : return ( ( MethodScope ) current ) . referenceContext ; case CLASS_SCOPE : return ( ( ClassScope ) current ) . referenceContext ; case COMPILATION_UNIT_SCOPE : return ( ( CompilationUnitScope ) current ) . referenceContext ; } } return null ; } public final SourceTypeBinding enclosingSourceType ( ) { Scope scope = this ; do { if ( scope instanceof ClassScope ) return ( ( ClassScope ) scope ) . referenceContext . binding ; scope = scope . parent ; } while ( scope != null ) ; return null ; } public final LookupEnvironment environment ( ) { Scope scope , unitScope = this ; while ( ( scope = unitScope . parent ) != null ) unitScope = scope ; return ( ( CompilationUnitScope ) unitScope ) . environment ; } protected MethodBinding findDefaultAbstractMethod ( ReferenceBinding receiverType , char [ ] selector , TypeBinding [ ] argumentTypes , InvocationSite invocationSite , ReferenceBinding classHierarchyStart , ObjectVector found , MethodBinding concreteMatch ) { int startFoundSize = found . size ; ReferenceBinding currentType = classHierarchyStart ; while ( currentType != null ) { findMethodInSuperInterfaces ( currentType , selector , found , invocationSite ) ; currentType = currentType . superclass ( ) ; } MethodBinding [ ] candidates = null ; int candidatesCount = 0 ; MethodBinding problemMethod = null ; int foundSize = found . size ; if ( foundSize > startFoundSize ) { for ( int i = startFoundSize ; i < foundSize ; i ++ ) { MethodBinding methodBinding = ( MethodBinding ) found . elementAt ( i ) ; MethodBinding compatibleMethod = computeCompatibleMethod ( methodBinding , argumentTypes , invocationSite ) ; if ( compatibleMethod != null ) { if ( compatibleMethod . isValidBinding ( ) ) { if ( concreteMatch != null && environment ( ) . methodVerifier ( ) . areMethodsCompatible ( concreteMatch , compatibleMethod ) ) continue ; if ( candidatesCount == 0 ) { candidates = new MethodBinding [ foundSize - startFoundSize + 1 ] ; if ( concreteMatch != null ) candidates [ candidatesCount ++ ] = concreteMatch ; } candidates [ candidatesCount ++ ] = compatibleMethod ; } else if ( problemMethod == null ) { problemMethod = compatibleMethod ; } } } } if ( candidatesCount < 2 ) { if ( concreteMatch == null ) { if ( candidatesCount == 0 ) return problemMethod ; concreteMatch = candidates [ 0 ] ; } compilationUnitScope ( ) . recordTypeReferences ( concreteMatch . thrownExceptions ) ; return concreteMatch ; } if ( compilerOptions ( ) . complianceLevel >= ClassFileConstants . JDK1_4 ) return mostSpecificMethodBinding ( candidates , candidatesCount , argumentTypes , invocationSite , receiverType ) ; return mostSpecificInterfaceMethodBinding ( candidates , candidatesCount , invocationSite ) ; } public ReferenceBinding findDirectMemberType ( char [ ] typeName , ReferenceBinding enclosingType ) { if ( ( enclosingType . tagBits & TagBits . HasNoMemberTypes ) != 0 ) return null ; ReferenceBinding enclosingReceiverType = enclosingReceiverType ( ) ; CompilationUnitScope unitScope = compilationUnitScope ( ) ; unitScope . recordReference ( enclosingType , typeName ) ; ReferenceBinding memberType = enclosingType . getMemberType ( typeName ) ; if ( memberType != null ) { unitScope . recordTypeReference ( memberType ) ; if ( enclosingReceiverType == null ) { if ( memberType . canBeSeenBy ( getCurrentPackage ( ) ) ) { return memberType ; } if ( this instanceof CompilationUnitScope ) { TypeDeclaration [ ] types = ( ( CompilationUnitScope ) this ) . referenceContext . types ; if ( types != null ) { for ( int i = 0 , max = types . length ; i < max ; i ++ ) { if ( memberType . canBeSeenBy ( enclosingType , types [ i ] . binding ) ) { return memberType ; } } } } } else if ( memberType . canBeSeenBy ( enclosingType , enclosingReceiverType ) ) { return memberType ; } return new ProblemReferenceBinding ( new char [ ] [ ] { typeName } , memberType , ProblemReasons . NotVisible ) ; } return null ; } public MethodBinding findExactMethod ( ReferenceBinding receiverType , char [ ] selector , TypeBinding [ ] argumentTypes , InvocationSite invocationSite ) { CompilationUnitScope unitScope = compilationUnitScope ( ) ; unitScope . recordTypeReferences ( argumentTypes ) ; MethodBinding exactMethod = receiverType . getExactMethod ( selector , argumentTypes , unitScope ) ; if ( exactMethod != null && exactMethod . typeVariables == Binding . NO_TYPE_VARIABLES && ! exactMethod . isBridge ( ) ) { if ( compilerOptions ( ) . sourceLevel >= ClassFileConstants . JDK1_5 ) for ( int i = argumentTypes . length ; -- i >= 0 ; ) if ( isPossibleSubtypeOfRawType ( argumentTypes [ i ] ) ) return null ; unitScope . recordTypeReferences ( exactMethod . thrownExceptions ) ; if ( exactMethod . isAbstract ( ) && exactMethod . thrownExceptions != Binding . NO_EXCEPTIONS ) return null ; if ( receiverType . isInterface ( ) || exactMethod . canBeSeenBy ( receiverType , invocationSite , this ) ) { if ( argumentTypes == Binding . NO_PARAMETERS && CharOperation . equals ( selector , TypeConstants . GETCLASS ) && exactMethod . returnType . isParameterizedType ( ) ) { return environment ( ) . createGetClassMethod ( receiverType , exactMethod , this ) ; } if ( invocationSite . genericTypeArguments ( ) != null ) { exactMethod = computeCompatibleMethod ( exactMethod , argumentTypes , invocationSite ) ; } return exactMethod ; } } return null ; } public FieldBinding findField ( TypeBinding receiverType , char [ ] fieldName , InvocationSite invocationSite , boolean needResolve ) { return findField ( receiverType , fieldName , invocationSite , needResolve , false ) ; } public FieldBinding findField ( TypeBinding receiverType , char [ ] fieldName , InvocationSite invocationSite , boolean needResolve , boolean invisibleFieldsOk ) { CompilationUnitScope unitScope = compilationUnitScope ( ) ; unitScope . recordTypeReference ( receiverType ) ; checkArrayField : { TypeBinding leafType ; switch ( receiverType . kind ( ) ) { case Binding . BASE_TYPE : return null ; case Binding . WILDCARD_TYPE : case Binding . INTERSECTION_TYPE : case Binding . TYPE_PARAMETER : TypeBinding receiverErasure = receiverType . erasure ( ) ; if ( ! receiverErasure . isArrayType ( ) ) break checkArrayField ; leafType = receiverErasure . leafComponentType ( ) ; break ; case Binding . ARRAY_TYPE : leafType = receiverType . leafComponentType ( ) ; break ; default : break checkArrayField ; } if ( leafType instanceof ReferenceBinding ) if ( ! ( ( ReferenceBinding ) leafType ) . canBeSeenBy ( this ) ) return new ProblemFieldBinding ( ( ReferenceBinding ) leafType , fieldName , ProblemReasons . ReceiverTypeNotVisible ) ; if ( CharOperation . equals ( fieldName , TypeConstants . LENGTH ) ) { if ( ( leafType . tagBits & TagBits . HasMissingType ) != 0 ) { return new ProblemFieldBinding ( ArrayBinding . ArrayLength , null , fieldName , ProblemReasons . NotFound ) ; } return ArrayBinding . ArrayLength ; } return null ; } ReferenceBinding currentType = ( ReferenceBinding ) receiverType ; if ( ! currentType . canBeSeenBy ( this ) ) return new ProblemFieldBinding ( currentType , fieldName , ProblemReasons . ReceiverTypeNotVisible ) ; currentType . initializeForStaticImports ( ) ; FieldBinding field = currentType . getField ( fieldName , needResolve ) ; boolean insideTypeAnnotations = this instanceof MethodScope && ( ( MethodScope ) this ) . insideTypeAnnotation ; if ( field != null ) { if ( invisibleFieldsOk ) { return field ; } if ( invocationSite == null || insideTypeAnnotations ? field . canBeSeenBy ( getCurrentPackage ( ) ) : field . canBeSeenBy ( currentType , invocationSite , this ) ) return field ; return new ProblemFieldBinding ( field , field . declaringClass , fieldName , ProblemReasons . NotVisible ) ; } ReferenceBinding [ ] interfacesToVisit = null ; int nextPosition = 0 ; FieldBinding visibleField = null ; boolean keepLooking = true ; FieldBinding notVisibleField = null ; while ( keepLooking ) { ReferenceBinding [ ] itsInterfaces = currentType . superInterfaces ( ) ; if ( itsInterfaces != null && itsInterfaces != Binding . NO_SUPERINTERFACES ) { if ( interfacesToVisit == null ) { interfacesToVisit = itsInterfaces ; nextPosition = interfacesToVisit . length ; } else { int itsLength = itsInterfaces . length ; if ( nextPosition + itsLength >= interfacesToVisit . length ) System . arraycopy ( interfacesToVisit , 0 , interfacesToVisit = new ReferenceBinding [ nextPosition + itsLength + 5 ] , 0 , nextPosition ) ; nextInterface : for ( int a = 0 ; a < itsLength ; a ++ ) { ReferenceBinding next = itsInterfaces [ a ] ; for ( int b = 0 ; b < nextPosition ; b ++ ) if ( next == interfacesToVisit [ b ] ) continue nextInterface ; interfacesToVisit [ nextPosition ++ ] = next ; } } } if ( ( currentType = currentType . superclass ( ) ) == null ) break ; unitScope . recordTypeReference ( currentType ) ; currentType . initializeForStaticImports ( ) ; currentType = ( ReferenceBinding ) currentType . capture ( this , invocationSite == null ? 0 : invocationSite . sourceEnd ( ) ) ; if ( ( field = currentType . getField ( fieldName , needResolve ) ) != null ) { if ( invisibleFieldsOk ) { return field ; } keepLooking = false ; if ( field . canBeSeenBy ( receiverType , invocationSite , this ) ) { if ( visibleField == null ) visibleField = field ; else return new ProblemFieldBinding ( visibleField , visibleField . declaringClass , fieldName , ProblemReasons . Ambiguous ) ; } else { if ( notVisibleField == null ) notVisibleField = field ; } } } if ( interfacesToVisit != null ) { ProblemFieldBinding ambiguous = null ; done : for ( int i = 0 ; i < nextPosition ; i ++ ) { ReferenceBinding anInterface = interfacesToVisit [ i ] ; unitScope . recordTypeReference ( anInterface ) ; if ( ( field = anInterface . getField ( fieldName , true ) ) != null ) { if ( invisibleFieldsOk ) { return field ; } if ( visibleField == null ) { visibleField = field ; } else { ambiguous = new ProblemFieldBinding ( visibleField , visibleField . declaringClass , fieldName , ProblemReasons . Ambiguous ) ; break done ; } } else { ReferenceBinding [ ] itsInterfaces = anInterface . superInterfaces ( ) ; if ( itsInterfaces != null && itsInterfaces != Binding . NO_SUPERINTERFACES ) { int itsLength = itsInterfaces . length ; if ( nextPosition + itsLength >= interfacesToVisit . length ) System . arraycopy ( interfacesToVisit , 0 , interfacesToVisit = new ReferenceBinding [ nextPosition + itsLength + 5 ] , 0 , nextPosition ) ; nextInterface : for ( int a = 0 ; a < itsLength ; a ++ ) { ReferenceBinding next = itsInterfaces [ a ] ; for ( int b = 0 ; b < nextPosition ; b ++ ) if ( next == interfacesToVisit [ b ] ) continue nextInterface ; interfacesToVisit [ nextPosition ++ ] = next ; } } } } if ( ambiguous != null ) return ambiguous ; } if ( visibleField != null ) return visibleField ; if ( notVisibleField != null ) { return new ProblemFieldBinding ( notVisibleField , currentType , fieldName , ProblemReasons . NotVisible ) ; } return null ; } public ReferenceBinding findMemberType ( char [ ] typeName , ReferenceBinding enclosingType ) { if ( ( enclosingType . tagBits & TagBits . HasNoMemberTypes ) != 0 ) return null ; ReferenceBinding enclosingSourceType = enclosingSourceType ( ) ; PackageBinding currentPackage = getCurrentPackage ( ) ; CompilationUnitScope unitScope = compilationUnitScope ( ) ; unitScope . recordReference ( enclosingType , typeName ) ; ReferenceBinding memberType = enclosingType . getMemberType ( typeName ) ; if ( memberType != null ) { unitScope . recordTypeReference ( memberType ) ; if ( enclosingSourceType == null || ( this . parent == unitScope && ( enclosingSourceType . tagBits & TagBits . TypeVariablesAreConnected ) == 0 ) ? memberType . canBeSeenBy ( currentPackage ) : memberType . canBeSeenBy ( enclosingType , enclosingSourceType ) ) return memberType ; return new ProblemReferenceBinding ( new char [ ] [ ] { typeName } , memberType , ProblemReasons . NotVisible ) ; } ReferenceBinding currentType = enclosingType ; ReferenceBinding [ ] interfacesToVisit = null ; int nextPosition = 0 ; ReferenceBinding visibleMemberType = null ; boolean keepLooking = true ; ReferenceBinding notVisible = null ; while ( keepLooking ) { ReferenceBinding [ ] itsInterfaces = currentType . superInterfaces ( ) ; if ( itsInterfaces == null ) { ReferenceBinding sourceType = currentType . isParameterizedType ( ) ? ( ( ParameterizedTypeBinding ) currentType ) . genericType ( ) : currentType ; if ( sourceType . isHierarchyBeingConnected ( ) ) return null ; ( ( SourceTypeBinding ) sourceType ) . scope . connectTypeHierarchy ( ) ; itsInterfaces = currentType . superInterfaces ( ) ; } if ( itsInterfaces != null && itsInterfaces != Binding . NO_SUPERINTERFACES ) { if ( interfacesToVisit == null ) { interfacesToVisit = itsInterfaces ; nextPosition = interfacesToVisit . length ; } else { int itsLength = itsInterfaces . length ; if ( nextPosition + itsLength >= interfacesToVisit . length ) System . arraycopy ( interfacesToVisit , 0 , interfacesToVisit = new ReferenceBinding [ nextPosition + itsLength + 5 ] , 0 , nextPosition ) ; nextInterface : for ( int a = 0 ; a < itsLength ; a ++ ) { ReferenceBinding next = itsInterfaces [ a ] ; for ( int b = 0 ; b < nextPosition ; b ++ ) if ( next == interfacesToVisit [ b ] ) continue nextInterface ; interfacesToVisit [ nextPosition ++ ] = next ; } } } if ( ( currentType = currentType . superclass ( ) ) == null ) break ; unitScope . recordReference ( currentType , typeName ) ; if ( ( memberType = currentType . getMemberType ( typeName ) ) != null ) { unitScope . recordTypeReference ( memberType ) ; keepLooking = false ; if ( enclosingSourceType == null ? memberType . canBeSeenBy ( currentPackage ) : memberType . canBeSeenBy ( enclosingType , enclosingSourceType ) ) { if ( visibleMemberType == null ) visibleMemberType = memberType ; else return new ProblemReferenceBinding ( new char [ ] [ ] { typeName } , visibleMemberType , ProblemReasons . Ambiguous ) ; } else { notVisible = memberType ; } } } if ( interfacesToVisit != null ) { ProblemReferenceBinding ambiguous = null ; done : for ( int i = 0 ; i < nextPosition ; i ++ ) { ReferenceBinding anInterface = interfacesToVisit [ i ] ; unitScope . recordReference ( anInterface , typeName ) ; if ( ( memberType = anInterface . getMemberType ( typeName ) ) != null ) { unitScope . recordTypeReference ( memberType ) ; if ( visibleMemberType == null ) { visibleMemberType = memberType ; } else { ambiguous = new ProblemReferenceBinding ( new char [ ] [ ] { typeName } , visibleMemberType , ProblemReasons . Ambiguous ) ; break done ; } } else { ReferenceBinding [ ] itsInterfaces = anInterface . superInterfaces ( ) ; if ( itsInterfaces != null && itsInterfaces != Binding . NO_SUPERINTERFACES ) { int itsLength = itsInterfaces . length ; if ( nextPosition + itsLength >= interfacesToVisit . length ) System . arraycopy ( interfacesToVisit , 0 , interfacesToVisit = new ReferenceBinding [ nextPosition + itsLength + 5 ] , 0 , nextPosition ) ; nextInterface : for ( int a = 0 ; a < itsLength ; a ++ ) { ReferenceBinding next = itsInterfaces [ a ] ; for ( int b = 0 ; b < nextPosition ; b ++ ) if ( next == interfacesToVisit [ b ] ) continue nextInterface ; interfacesToVisit [ nextPosition ++ ] = next ; } } } } if ( ambiguous != null ) return ambiguous ; } if ( visibleMemberType != null ) return visibleMemberType ; if ( notVisible != null ) return new ProblemReferenceBinding ( new char [ ] [ ] { typeName } , notVisible , ProblemReasons . NotVisible ) ; return null ; } public MethodBinding findMethod ( ReferenceBinding receiverType , char [ ] selector , TypeBinding [ ] argumentTypes , InvocationSite invocationSite ) { return findMethod ( receiverType , selector , argumentTypes , invocationSite , false ) ; } public MethodBinding oneLastLook ( ReferenceBinding receiverType , char [ ] selector , TypeBinding [ ] argumentTypes , InvocationSite invocationSite ) { MethodBinding [ ] extraMethods = receiverType . getAnyExtraMethods ( selector ) ; if ( extraMethods != null ) { return extraMethods [ 0 ] ; } else { return null ; } } public MethodBinding findMethod ( ReferenceBinding receiverType , char [ ] selector , TypeBinding [ ] argumentTypes , InvocationSite invocationSite , boolean inStaticContext ) { ReferenceBinding currentType = receiverType ; boolean receiverTypeIsInterface = receiverType . isInterface ( ) ; ObjectVector found = new ObjectVector ( 3 ) ; CompilationUnitScope unitScope = compilationUnitScope ( ) ; unitScope . recordTypeReferences ( argumentTypes ) ; if ( receiverTypeIsInterface ) { unitScope . recordTypeReference ( receiverType ) ; MethodBinding [ ] receiverMethods = receiverType . getMethods ( selector , argumentTypes . length ) ; if ( receiverMethods . length > 0 ) found . addAll ( receiverMethods ) ; findMethodInSuperInterfaces ( receiverType , selector , found , invocationSite ) ; currentType = getJavaLangObject ( ) ; } long complianceLevel = compilerOptions ( ) . complianceLevel ; boolean isCompliant14 = complianceLevel >= ClassFileConstants . JDK1_4 ; boolean isCompliant15 = complianceLevel >= ClassFileConstants . JDK1_5 ; ReferenceBinding classHierarchyStart = currentType ; MethodVerifier verifier = environment ( ) . methodVerifier ( ) ; while ( currentType != null ) { unitScope . recordTypeReference ( currentType ) ; currentType = ( ReferenceBinding ) currentType . capture ( this , invocationSite == null ? 0 : invocationSite . sourceEnd ( ) ) ; MethodBinding [ ] currentMethods = currentType . getMethods ( selector , argumentTypes . length ) ; int currentLength = currentMethods . length ; if ( currentLength > 0 ) { if ( isCompliant14 && ( receiverTypeIsInterface || found . size > 0 ) ) { nextMethod : for ( int i = 0 , l = currentLength ; i < l ; i ++ ) { MethodBinding currentMethod = currentMethods [ i ] ; if ( currentMethod == null ) continue nextMethod ; if ( receiverTypeIsInterface && ! currentMethod . isPublic ( ) ) { currentLength -- ; currentMethods [ i ] = null ; continue nextMethod ; } for ( int j = 0 , max = found . size ; j < max ; j ++ ) { MethodBinding matchingMethod = ( MethodBinding ) found . elementAt ( j ) ; MethodBinding matchingOriginal = matchingMethod . original ( ) ; MethodBinding currentOriginal = matchingOriginal . findOriginalInheritedMethod ( currentMethod ) ; if ( currentOriginal != null && verifier . isParameterSubsignature ( matchingOriginal , currentOriginal ) ) { if ( isCompliant15 ) { if ( matchingMethod . isBridge ( ) && ! currentMethod . isBridge ( ) ) continue nextMethod ; } currentLength -- ; currentMethods [ i ] = null ; continue nextMethod ; } } } } if ( currentLength > 0 ) { if ( currentMethods . length == currentLength ) { found . addAll ( currentMethods ) ; } else { for ( int i = 0 , max = currentMethods . length ; i < max ; i ++ ) { MethodBinding currentMethod = currentMethods [ i ] ; if ( currentMethod != null ) found . add ( currentMethod ) ; } } } } currentType = currentType . superclass ( ) ; } int foundSize = found . size ; MethodBinding [ ] candidates = null ; int candidatesCount = 0 ; MethodBinding problemMethod = null ; boolean searchForDefaultAbstractMethod = isCompliant14 && ! receiverTypeIsInterface && ( receiverType . isAbstract ( ) || receiverType . isTypeVariable ( ) ) ; if ( foundSize > 0 ) { for ( int i = 0 ; i < foundSize ; i ++ ) { MethodBinding methodBinding = ( MethodBinding ) found . elementAt ( i ) ; MethodBinding compatibleMethod = computeCompatibleMethod ( methodBinding , argumentTypes , invocationSite ) ; if ( compatibleMethod != null ) { if ( compatibleMethod . isValidBinding ( ) ) { if ( foundSize == 1 && compatibleMethod . canBeSeenBy ( receiverType , invocationSite , this ) ) { if ( searchForDefaultAbstractMethod ) return findDefaultAbstractMethod ( receiverType , selector , argumentTypes , invocationSite , classHierarchyStart , found , compatibleMethod ) ; unitScope . recordTypeReferences ( compatibleMethod . thrownExceptions ) ; return compatibleMethod ; } if ( candidatesCount == 0 ) candidates = new MethodBinding [ foundSize ] ; candidates [ candidatesCount ++ ] = compatibleMethod ; } else if ( problemMethod == null ) { problemMethod = compatibleMethod ; } } } } if ( candidatesCount == 0 ) { if ( problemMethod != null ) { switch ( problemMethod . problemId ( ) ) { case ProblemReasons . TypeArgumentsForRawGenericMethod : case ProblemReasons . TypeParameterArityMismatch : return problemMethod ; } } MethodBinding interfaceMethod = findDefaultAbstractMethod ( receiverType , selector , argumentTypes , invocationSite , classHierarchyStart , found , null ) ; if ( interfaceMethod != null ) return interfaceMethod ; if ( found . size == 0 ) return null ; if ( problemMethod != null ) return problemMethod ; int bestArgMatches = - 1 ; MethodBinding bestGuess = ( MethodBinding ) found . elementAt ( 0 ) ; int argLength = argumentTypes . length ; foundSize = found . size ; nextMethod : for ( int i = 0 ; i < foundSize ; i ++ ) { MethodBinding methodBinding = ( MethodBinding ) found . elementAt ( i ) ; TypeBinding [ ] params = methodBinding . parameters ; int paramLength = params . length ; int argMatches = 0 ; next : for ( int a = 0 ; a < argLength ; a ++ ) { TypeBinding arg = argumentTypes [ a ] ; for ( int p = a == 0 ? 0 : a - 1 ; p < paramLength && p < a + 1 ; p ++ ) { if ( params [ p ] == arg ) { argMatches ++ ; continue next ; } } } if ( argMatches < bestArgMatches ) continue nextMethod ; if ( argMatches == bestArgMatches ) { int diff1 = paramLength < argLength ? 2 * ( argLength - paramLength ) : paramLength - argLength ; int bestLength = bestGuess . parameters . length ; int diff2 = bestLength < argLength ? 2 * ( argLength - bestLength ) : bestLength - argLength ; if ( diff1 >= diff2 ) continue nextMethod ; } bestArgMatches = argMatches ; bestGuess = methodBinding ; } return new ProblemMethodBinding ( bestGuess , bestGuess . selector , argumentTypes , ProblemReasons . NotFound ) ; } int visiblesCount = 0 ; if ( receiverTypeIsInterface ) { if ( candidatesCount == 1 ) { unitScope . recordTypeReferences ( candidates [ 0 ] . thrownExceptions ) ; return candidates [ 0 ] ; } visiblesCount = candidatesCount ; } else { for ( int i = 0 ; i < candidatesCount ; i ++ ) { MethodBinding methodBinding = candidates [ i ] ; if ( methodBinding . canBeSeenBy ( receiverType , invocationSite , this ) ) { if ( visiblesCount != i ) { candidates [ i ] = null ; candidates [ visiblesCount ] = methodBinding ; } visiblesCount ++ ; } } switch ( visiblesCount ) { case 0 : MethodBinding interfaceMethod = findDefaultAbstractMethod ( receiverType , selector , argumentTypes , invocationSite , classHierarchyStart , found , null ) ; if ( interfaceMethod != null ) return interfaceMethod ; return new ProblemMethodBinding ( candidates [ 0 ] , candidates [ 0 ] . selector , candidates [ 0 ] . parameters , ProblemReasons . NotVisible ) ; case 1 : if ( searchForDefaultAbstractMethod ) return findDefaultAbstractMethod ( receiverType , selector , argumentTypes , invocationSite , classHierarchyStart , found , candidates [ 0 ] ) ; unitScope . recordTypeReferences ( candidates [ 0 ] . thrownExceptions ) ; return candidates [ 0 ] ; default : break ; } } if ( complianceLevel <= ClassFileConstants . JDK1_3 ) { ReferenceBinding declaringClass = candidates [ 0 ] . declaringClass ; return ! declaringClass . isInterface ( ) ? mostSpecificClassMethodBinding ( candidates , visiblesCount , invocationSite ) : mostSpecificInterfaceMethodBinding ( candidates , visiblesCount , invocationSite ) ; } if ( compilerOptions ( ) . sourceLevel >= ClassFileConstants . JDK1_5 ) { for ( int i = 0 ; i < visiblesCount ; i ++ ) { MethodBinding candidate = candidates [ i ] ; if ( candidate instanceof ParameterizedGenericMethodBinding ) candidate = ( ( ParameterizedGenericMethodBinding ) candidate ) . originalMethod ; if ( candidate . hasSubstitutedParameters ( ) ) { for ( int j = i + 1 ; j < visiblesCount ; j ++ ) { MethodBinding otherCandidate = candidates [ j ] ; if ( otherCandidate . hasSubstitutedParameters ( ) ) { if ( otherCandidate == candidate || ( candidate . declaringClass == otherCandidate . declaringClass && candidate . areParametersEqual ( otherCandidate ) ) ) { return new ProblemMethodBinding ( candidates [ i ] , candidates [ i ] . selector , candidates [ i ] . parameters , ProblemReasons . Ambiguous ) ; } } } } } } if ( inStaticContext ) { MethodBinding [ ] staticCandidates = new MethodBinding [ visiblesCount ] ; int staticCount = 0 ; for ( int i = 0 ; i < visiblesCount ; i ++ ) if ( candidates [ i ] . isStatic ( ) ) staticCandidates [ staticCount ++ ] = candidates [ i ] ; if ( staticCount == 1 ) return staticCandidates [ 0 ] ; if ( staticCount > 1 ) return mostSpecificMethodBinding ( staticCandidates , staticCount , argumentTypes , invocationSite , receiverType ) ; } MethodBinding mostSpecificMethod = mostSpecificMethodBinding ( candidates , visiblesCount , argumentTypes , invocationSite , receiverType ) ; if ( searchForDefaultAbstractMethod ) { if ( mostSpecificMethod . isValidBinding ( ) ) return findDefaultAbstractMethod ( receiverType , selector , argumentTypes , invocationSite , classHierarchyStart , found , mostSpecificMethod ) ; MethodBinding interfaceMethod = findDefaultAbstractMethod ( receiverType , selector , argumentTypes , invocationSite , classHierarchyStart , found , null ) ; if ( interfaceMethod != null && interfaceMethod . isValidBinding ( ) ) return interfaceMethod ; } return mostSpecificMethod ; } public MethodBinding findMethodForArray ( ArrayBinding receiverType , char [ ] selector , TypeBinding [ ] argumentTypes , InvocationSite invocationSite ) { TypeBinding leafType = receiverType . leafComponentType ( ) ; if ( leafType instanceof ReferenceBinding ) { if ( ! ( ( ReferenceBinding ) leafType ) . canBeSeenBy ( this ) ) return new ProblemMethodBinding ( selector , Binding . NO_PARAMETERS , ( ReferenceBinding ) leafType , ProblemReasons . ReceiverTypeNotVisible ) ; } ReferenceBinding object = getJavaLangObject ( ) ; MethodBinding methodBinding = object . getExactMethod ( selector , argumentTypes , null ) ; if ( methodBinding != null ) { if ( argumentTypes == Binding . NO_PARAMETERS ) { switch ( selector [ 0 ] ) { case 'c' : if ( CharOperation . equals ( selector , TypeConstants . CLONE ) ) { return environment ( ) . computeArrayClone ( methodBinding ) ; } break ; case 'g' : if ( CharOperation . equals ( selector , TypeConstants . GETCLASS ) && methodBinding . returnType . isParameterizedType ( ) ) { return environment ( ) . createGetClassMethod ( receiverType , methodBinding , this ) ; } break ; } } if ( methodBinding . canBeSeenBy ( receiverType , invocationSite , this ) ) return methodBinding ; } methodBinding = findMethod ( object , selector , argumentTypes , invocationSite ) ; if ( methodBinding == null ) return new ProblemMethodBinding ( selector , argumentTypes , ProblemReasons . NotFound ) ; return methodBinding ; } protected void findMethodInSuperInterfaces ( ReferenceBinding currentType , char [ ] selector , ObjectVector found , InvocationSite invocationSite ) { ReferenceBinding [ ] itsInterfaces = currentType . superInterfaces ( ) ; if ( itsInterfaces != null && itsInterfaces != Binding . NO_SUPERINTERFACES ) { ReferenceBinding [ ] interfacesToVisit = itsInterfaces ; int nextPosition = interfacesToVisit . length ; for ( int i = 0 ; i < nextPosition ; i ++ ) { currentType = interfacesToVisit [ i ] ; compilationUnitScope ( ) . recordTypeReference ( currentType ) ; currentType = ( ReferenceBinding ) currentType . capture ( this , invocationSite == null ? 0 : invocationSite . sourceEnd ( ) ) ; MethodBinding [ ] currentMethods = currentType . getMethods ( selector ) ; if ( currentMethods . length > 0 ) { int foundSize = found . size ; if ( foundSize > 0 ) { next : for ( int c = 0 , l = currentMethods . length ; c < l ; c ++ ) { MethodBinding current = currentMethods [ c ] ; for ( int f = 0 ; f < foundSize ; f ++ ) if ( current == found . elementAt ( f ) ) continue next ; found . add ( current ) ; } } else { found . addAll ( currentMethods ) ; } } if ( ( itsInterfaces = currentType . superInterfaces ( ) ) != null && itsInterfaces != Binding . NO_SUPERINTERFACES ) { int itsLength = itsInterfaces . length ; if ( nextPosition + itsLength >= interfacesToVisit . length ) System . arraycopy ( interfacesToVisit , 0 , interfacesToVisit = new ReferenceBinding [ nextPosition + itsLength + 5 ] , 0 , nextPosition ) ; nextInterface : for ( int a = 0 ; a < itsLength ; a ++ ) { ReferenceBinding next = itsInterfaces [ a ] ; for ( int b = 0 ; b < nextPosition ; b ++ ) if ( next == interfacesToVisit [ b ] ) continue nextInterface ; interfacesToVisit [ nextPosition ++ ] = next ; } } } } } public ReferenceBinding findType ( char [ ] typeName , PackageBinding declarationPackage , PackageBinding invocationPackage ) { compilationUnitScope ( ) . recordReference ( declarationPackage . compoundName , typeName ) ; ReferenceBinding typeBinding = declarationPackage . getType ( typeName ) ; if ( typeBinding == null ) return null ; if ( typeBinding . isValidBinding ( ) ) { if ( declarationPackage != invocationPackage && ! typeBinding . canBeSeenBy ( invocationPackage ) ) return new ProblemReferenceBinding ( new char [ ] [ ] { typeName } , typeBinding , ProblemReasons . NotVisible ) ; } return typeBinding ; } public LocalVariableBinding findVariable ( char [ ] variable ) { return null ; } public Binding getBinding ( char [ ] name , int mask , InvocationSite invocationSite , boolean needResolve ) { CompilationUnitScope unitScope = compilationUnitScope ( ) ; LookupEnvironment env = unitScope . environment ; try { env . missingClassFileLocation = invocationSite ; Binding binding = null ; FieldBinding problemField = null ; if ( ( mask & Binding . VARIABLE ) != 0 ) { boolean insideStaticContext = false ; boolean insideConstructorCall = false ; boolean insideTypeAnnotation = false ; FieldBinding foundField = null ; ProblemFieldBinding foundInsideProblem = null ; Scope scope = this ; int depth = 0 ; int foundDepth = 0 ; ReferenceBinding foundActualReceiverType = null ; done : while ( true ) { switch ( scope . kind ) { case METHOD_SCOPE : MethodScope methodScope = ( MethodScope ) scope ; insideStaticContext |= methodScope . isStatic ; insideConstructorCall |= methodScope . isConstructorCall ; insideTypeAnnotation = methodScope . insideTypeAnnotation ; case BLOCK_SCOPE : LocalVariableBinding variableBinding = scope . findVariable ( name ) ; if ( variableBinding != null ) { if ( foundField != null && foundField . isValidBinding ( ) ) return new ProblemFieldBinding ( foundField , foundField . declaringClass , name , ProblemReasons . InheritedNameHidesEnclosingName ) ; if ( depth > 0 ) invocationSite . setDepth ( depth ) ; return variableBinding ; } break ; case CLASS_SCOPE : ClassScope classScope = ( ClassScope ) scope ; ReferenceBinding receiverType = classScope . enclosingReceiverType ( ) ; if ( ! insideTypeAnnotation ) { FieldBinding fieldBinding = classScope . findField ( receiverType , name , invocationSite , needResolve ) ; if ( fieldBinding != null ) { if ( fieldBinding . problemId ( ) == ProblemReasons . Ambiguous ) { if ( foundField == null || foundField . problemId ( ) == ProblemReasons . NotVisible ) return fieldBinding ; return new ProblemFieldBinding ( foundField , foundField . declaringClass , name , ProblemReasons . InheritedNameHidesEnclosingName ) ; } ProblemFieldBinding insideProblem = null ; if ( fieldBinding . isValidBinding ( ) ) { if ( ! fieldBinding . isStatic ( ) ) { if ( insideConstructorCall ) { insideProblem = new ProblemFieldBinding ( fieldBinding , fieldBinding . declaringClass , name , ProblemReasons . NonStaticReferenceInConstructorInvocation ) ; } else if ( insideStaticContext ) { insideProblem = new ProblemFieldBinding ( fieldBinding , fieldBinding . declaringClass , name , ProblemReasons . NonStaticReferenceInStaticContext ) ; } } if ( receiverType == fieldBinding . declaringClass || compilerOptions ( ) . complianceLevel >= ClassFileConstants . JDK1_4 ) { if ( foundField == null ) { if ( depth > 0 ) { invocationSite . setDepth ( depth ) ; invocationSite . setActualReceiverType ( receiverType ) ; } return insideProblem == null ? fieldBinding : insideProblem ; } if ( foundField . isValidBinding ( ) ) if ( foundField . declaringClass != fieldBinding . declaringClass && foundField . declaringClass != foundActualReceiverType ) return new ProblemFieldBinding ( foundField , foundField . declaringClass , name , ProblemReasons . InheritedNameHidesEnclosingName ) ; } } if ( foundField == null || ( foundField . problemId ( ) == ProblemReasons . NotVisible && fieldBinding . problemId ( ) != ProblemReasons . NotVisible ) ) { foundDepth = depth ; foundActualReceiverType = receiverType ; foundInsideProblem = insideProblem ; foundField = fieldBinding ; } } } insideTypeAnnotation = false ; depth ++ ; insideStaticContext |= receiverType . isStatic ( ) ; MethodScope enclosingMethodScope = scope . methodScope ( ) ; insideConstructorCall = enclosingMethodScope == null ? false : enclosingMethodScope . isConstructorCall ; break ; case COMPILATION_UNIT_SCOPE : break done ; } scope = scope . parent ; } if ( foundInsideProblem != null ) return foundInsideProblem ; if ( foundField != null ) { if ( foundField . isValidBinding ( ) ) { if ( foundDepth > 0 ) { invocationSite . setDepth ( foundDepth ) ; invocationSite . setActualReceiverType ( foundActualReceiverType ) ; } return foundField ; } problemField = foundField ; foundField = null ; } if ( compilerOptions ( ) . sourceLevel >= ClassFileConstants . JDK1_5 ) { unitScope . faultInImports ( ) ; ImportBinding [ ] imports = unitScope . imports ; if ( imports != null ) { for ( int i = 0 , length = imports . length ; i < length ; i ++ ) { ImportBinding importBinding = imports [ i ] ; if ( importBinding . isStatic ( ) && ! importBinding . onDemand ) { if ( CharOperation . equals ( importBinding . compoundName [ importBinding . compoundName . length - 1 ] , name ) ) { if ( unitScope . resolveSingleImport ( importBinding , Binding . TYPE | Binding . FIELD | Binding . METHOD ) != null && importBinding . resolvedImport instanceof FieldBinding ) { foundField = ( FieldBinding ) importBinding . resolvedImport ; ImportReference importReference = importBinding . reference ; if ( importReference != null && needResolve ) { importReference . bits |= ASTNode . Used ; } invocationSite . setActualReceiverType ( foundField . declaringClass ) ; if ( foundField . isValidBinding ( ) ) { return foundField ; } if ( problemField == null ) problemField = foundField ; } } } } boolean foundInImport = false ; for ( int i = 0 , length = imports . length ; i < length ; i ++ ) { ImportBinding importBinding = imports [ i ] ; if ( importBinding . isStatic ( ) && importBinding . onDemand ) { Binding resolvedImport = importBinding . resolvedImport ; if ( resolvedImport instanceof ReferenceBinding ) { FieldBinding temp = findField ( ( ReferenceBinding ) resolvedImport , name , invocationSite , needResolve ) ; if ( temp != null ) { if ( ! temp . isValidBinding ( ) ) { if ( problemField == null ) problemField = temp ; } else if ( temp . isStatic ( ) ) { if ( foundField == temp ) continue ; ImportReference importReference = importBinding . reference ; if ( importReference != null && needResolve ) { importReference . bits |= ASTNode . Used ; } if ( foundInImport ) return new ProblemFieldBinding ( foundField , foundField . declaringClass , name , ProblemReasons . Ambiguous ) ; foundField = temp ; foundInImport = true ; } } } } } if ( foundField != null ) { invocationSite . setActualReceiverType ( foundField . declaringClass ) ; return foundField ; } } } } if ( ( mask & Binding . TYPE ) != 0 ) { if ( ( binding = getBaseType ( name ) ) != null ) return binding ; binding = getTypeOrPackage ( name , ( mask & Binding . PACKAGE ) == 0 ? Binding . TYPE : Binding . TYPE | Binding . PACKAGE , needResolve ) ; if ( binding . isValidBinding ( ) || mask == Binding . TYPE ) return binding ; } else if ( ( mask & Binding . PACKAGE ) != 0 ) { unitScope . recordSimpleReference ( name ) ; if ( ( binding = env . getTopLevelPackage ( name ) ) != null ) return binding ; } if ( problemField != null ) return problemField ; if ( binding != null && binding . problemId ( ) != ProblemReasons . NotFound ) return binding ; return new ProblemBinding ( name , enclosingSourceType ( ) , ProblemReasons . NotFound ) ; } catch ( AbortCompilation e ) { e . updateContext ( invocationSite , referenceCompilationUnit ( ) . compilationResult ) ; throw e ; } finally { env . missingClassFileLocation = null ; } } public MethodBinding getConstructor ( ReferenceBinding receiverType , TypeBinding [ ] argumentTypes , InvocationSite invocationSite ) { CompilationUnitScope unitScope = compilationUnitScope ( ) ; LookupEnvironment env = unitScope . environment ; try { env . missingClassFileLocation = invocationSite ; unitScope . recordTypeReference ( receiverType ) ; unitScope . recordTypeReferences ( argumentTypes ) ; MethodBinding methodBinding = receiverType . getExactConstructor ( argumentTypes ) ; if ( methodBinding != null && methodBinding . canBeSeenBy ( invocationSite , this ) ) { if ( invocationSite . genericTypeArguments ( ) != null ) methodBinding = computeCompatibleMethod ( methodBinding , argumentTypes , invocationSite ) ; return methodBinding ; } MethodBinding [ ] methods = receiverType . getMethods ( TypeConstants . INIT , argumentTypes . length ) ; if ( methods == Binding . NO_METHODS ) return new ProblemMethodBinding ( TypeConstants . INIT , argumentTypes , ProblemReasons . NotFound ) ; MethodBinding [ ] compatible = new MethodBinding [ methods . length ] ; int compatibleIndex = 0 ; MethodBinding problemMethod = null ; for ( int i = 0 , length = methods . length ; i < length ; i ++ ) { MethodBinding compatibleMethod = computeCompatibleMethod ( methods [ i ] , argumentTypes , invocationSite ) ; if ( compatibleMethod != null ) { if ( compatibleMethod . isValidBinding ( ) ) compatible [ compatibleIndex ++ ] = compatibleMethod ; else if ( problemMethod == null ) problemMethod = compatibleMethod ; } } if ( compatibleIndex == 0 ) { if ( problemMethod == null ) return new ProblemMethodBinding ( methods [ 0 ] , TypeConstants . INIT , argumentTypes , ProblemReasons . NotFound ) ; return problemMethod ; } MethodBinding [ ] visible = new MethodBinding [ compatibleIndex ] ; int visibleIndex = 0 ; for ( int i = 0 ; i < compatibleIndex ; i ++ ) { MethodBinding method = compatible [ i ] ; if ( method . canBeSeenBy ( invocationSite , this ) ) visible [ visibleIndex ++ ] = method ; } if ( visibleIndex == 1 ) return visible [ 0 ] ; if ( visibleIndex == 0 ) return new ProblemMethodBinding ( compatible [ 0 ] , TypeConstants . INIT , compatible [ 0 ] . parameters , ProblemReasons . NotVisible ) ; return mostSpecificMethodBinding ( visible , visibleIndex , argumentTypes , invocationSite , receiverType ) ; } catch ( AbortCompilation e ) { e . updateContext ( invocationSite , referenceCompilationUnit ( ) . compilationResult ) ; throw e ; } finally { env . missingClassFileLocation = null ; } } public final PackageBinding getCurrentPackage ( ) { Scope scope , unitScope = this ; while ( ( scope = unitScope . parent ) != null ) unitScope = scope ; return ( ( CompilationUnitScope ) unitScope ) . fPackage ; } public int getDeclarationModifiers ( ) { switch ( this . kind ) { case Scope . BLOCK_SCOPE : case Scope . METHOD_SCOPE : MethodScope methodScope = methodScope ( ) ; if ( ! methodScope . isInsideInitializer ( ) ) { MethodBinding context = ( ( AbstractMethodDeclaration ) methodScope . referenceContext ) . binding ; if ( context != null ) return context . modifiers ; } else { SourceTypeBinding type = ( ( BlockScope ) this ) . referenceType ( ) . binding ; if ( methodScope . initializedField != null ) return methodScope . initializedField . modifiers ; if ( type != null ) return type . modifiers ; } break ; case Scope . CLASS_SCOPE : ReferenceBinding context = ( ( ClassScope ) this ) . referenceType ( ) . binding ; if ( context != null ) return context . modifiers ; break ; } return - 1 ; } public FieldBinding getField ( TypeBinding receiverType , char [ ] fieldName , InvocationSite invocationSite ) { LookupEnvironment env = environment ( ) ; try { env . missingClassFileLocation = invocationSite ; FieldBinding field = findField ( receiverType , fieldName , invocationSite , true ) ; if ( field != null ) return field ; return new ProblemFieldBinding ( receiverType instanceof ReferenceBinding ? ( ReferenceBinding ) receiverType : null , fieldName , ProblemReasons . NotFound ) ; } catch ( AbortCompilation e ) { e . updateContext ( invocationSite , referenceCompilationUnit ( ) . compilationResult ) ; throw e ; } finally { env . missingClassFileLocation = null ; } } public MethodBinding getImplicitMethod ( char [ ] selector , TypeBinding [ ] argumentTypes , InvocationSite invocationSite ) { boolean insideStaticContext = false ; boolean insideConstructorCall = false ; boolean insideTypeAnnotation = false ; MethodBinding foundMethod = null ; MethodBinding foundProblem = null ; boolean foundProblemVisible = false ; Scope scope = this ; int depth = 0 ; CompilerOptions options ; boolean inheritedHasPrecedence = ( options = compilerOptions ( ) ) . complianceLevel >= ClassFileConstants . JDK1_4 ; done : while ( true ) { switch ( scope . kind ) { case METHOD_SCOPE : MethodScope methodScope = ( MethodScope ) scope ; insideStaticContext |= methodScope . isStatic ; insideConstructorCall |= methodScope . isConstructorCall ; insideTypeAnnotation = methodScope . insideTypeAnnotation ; break ; case CLASS_SCOPE : ClassScope classScope = ( ClassScope ) scope ; ReferenceBinding receiverType = classScope . enclosingReceiverType ( ) ; if ( ! insideTypeAnnotation ) { MethodBinding methodBinding = classScope . findExactMethod ( receiverType , selector , argumentTypes , invocationSite ) ; if ( methodBinding == null ) methodBinding = classScope . findMethod ( receiverType , selector , argumentTypes , invocationSite ) ; if ( methodBinding != null ) { if ( foundMethod == null ) { if ( methodBinding . isValidBinding ( ) ) { if ( ! methodBinding . isStatic ( ) && ( insideConstructorCall || insideStaticContext ) ) { if ( foundProblem != null && foundProblem . problemId ( ) != ProblemReasons . NotVisible ) return foundProblem ; return new ProblemMethodBinding ( methodBinding , methodBinding . selector , methodBinding . parameters , insideConstructorCall ? ProblemReasons . NonStaticReferenceInConstructorInvocation : ProblemReasons . NonStaticReferenceInStaticContext ) ; } if ( inheritedHasPrecedence || receiverType == methodBinding . declaringClass || ( receiverType . getMethods ( selector ) ) != Binding . NO_METHODS ) { if ( foundProblemVisible ) { return foundProblem ; } if ( depth > 0 ) { invocationSite . setDepth ( depth ) ; invocationSite . setActualReceiverType ( receiverType ) ; } if ( argumentTypes == Binding . NO_PARAMETERS && CharOperation . equals ( selector , TypeConstants . GETCLASS ) && methodBinding . returnType . isParameterizedType ( ) ) { return environment ( ) . createGetClassMethod ( receiverType , methodBinding , this ) ; } return methodBinding ; } if ( foundProblem == null || foundProblem . problemId ( ) == ProblemReasons . NotVisible ) { if ( foundProblem != null ) foundProblem = null ; if ( depth > 0 ) { invocationSite . setDepth ( depth ) ; invocationSite . setActualReceiverType ( receiverType ) ; } foundMethod = methodBinding ; } } else { if ( methodBinding . problemId ( ) != ProblemReasons . NotVisible && methodBinding . problemId ( ) != ProblemReasons . NotFound ) return methodBinding ; if ( foundProblem == null ) { foundProblem = methodBinding ; } if ( ! foundProblemVisible && methodBinding . problemId ( ) == ProblemReasons . NotFound ) { MethodBinding closestMatch = ( ( ProblemMethodBinding ) methodBinding ) . closestMatch ; if ( closestMatch != null && closestMatch . canBeSeenBy ( receiverType , invocationSite , this ) ) { foundProblem = methodBinding ; foundProblemVisible = true ; } } } } else { if ( methodBinding . problemId ( ) == ProblemReasons . Ambiguous || ( foundMethod . declaringClass != methodBinding . declaringClass && ( receiverType == methodBinding . declaringClass || receiverType . getMethods ( selector ) != Binding . NO_METHODS ) ) ) return new ProblemMethodBinding ( methodBinding , selector , argumentTypes , ProblemReasons . InheritedNameHidesEnclosingName ) ; } } } insideTypeAnnotation = false ; depth ++ ; insideStaticContext |= receiverType . isStatic ( ) ; MethodScope enclosingMethodScope = scope . methodScope ( ) ; insideConstructorCall = enclosingMethodScope == null ? false : enclosingMethodScope . isConstructorCall ; break ; case COMPILATION_UNIT_SCOPE : break done ; } scope = scope . parent ; } if ( insideStaticContext && options . sourceLevel >= ClassFileConstants . JDK1_5 ) { if ( foundProblem != null ) { if ( foundProblem . declaringClass != null && foundProblem . declaringClass . id == TypeIds . T_JavaLangObject ) return foundProblem ; if ( foundProblem . problemId ( ) == ProblemReasons . NotFound && foundProblemVisible ) { return foundProblem ; } } CompilationUnitScope unitScope = ( CompilationUnitScope ) scope ; unitScope . faultInImports ( ) ; ImportBinding [ ] imports = unitScope . imports ; if ( imports != null ) { ObjectVector visible = null ; boolean skipOnDemand = false ; for ( int i = 0 , length = imports . length ; i < length ; i ++ ) { ImportBinding importBinding = imports [ i ] ; if ( importBinding . isStatic ( ) ) { Binding resolvedImport = importBinding . resolvedImport ; MethodBinding possible = null ; if ( importBinding . onDemand ) { if ( ! skipOnDemand && resolvedImport instanceof ReferenceBinding ) possible = findMethod ( ( ReferenceBinding ) resolvedImport , selector , argumentTypes , invocationSite , true ) ; } else { if ( resolvedImport instanceof MethodBinding ) { MethodBinding staticMethod = ( MethodBinding ) resolvedImport ; if ( CharOperation . equals ( staticMethod . selector , selector ) ) possible = findMethod ( staticMethod . declaringClass , selector , argumentTypes , invocationSite , true ) ; } else if ( resolvedImport instanceof FieldBinding ) { FieldBinding staticField = ( FieldBinding ) resolvedImport ; if ( CharOperation . equals ( staticField . name , selector ) ) { char [ ] [ ] importName = importBinding . reference . tokens ; TypeBinding referencedType = getType ( importName , importName . length - 1 ) ; if ( referencedType != null ) possible = findMethod ( ( ReferenceBinding ) referencedType , selector , argumentTypes , invocationSite , true ) ; } } } if ( possible != null && possible != foundProblem ) { if ( ! possible . isValidBinding ( ) ) { if ( foundProblem == null ) foundProblem = possible ; } else if ( possible . isStatic ( ) ) { MethodBinding compatibleMethod = computeCompatibleMethod ( possible , argumentTypes , invocationSite ) ; if ( compatibleMethod != null ) { if ( compatibleMethod . isValidBinding ( ) ) { if ( compatibleMethod . canBeSeenBy ( unitScope . fPackage ) ) { if ( visible == null || ! visible . contains ( compatibleMethod ) ) { ImportReference importReference = importBinding . reference ; if ( importReference != null ) { importReference . bits |= ASTNode . Used ; } if ( ! skipOnDemand && ! importBinding . onDemand ) { visible = null ; skipOnDemand = true ; } if ( visible == null ) visible = new ObjectVector ( 3 ) ; visible . add ( compatibleMethod ) ; } } else if ( foundProblem == null ) { foundProblem = new ProblemMethodBinding ( compatibleMethod , selector , compatibleMethod . parameters , ProblemReasons . NotVisible ) ; } } else if ( foundProblem == null ) { foundProblem = compatibleMethod ; } } else if ( foundProblem == null ) { foundProblem = new ProblemMethodBinding ( possible , selector , argumentTypes , ProblemReasons . NotFound ) ; } } } } } if ( visible != null ) { MethodBinding [ ] temp = new MethodBinding [ visible . size ] ; visible . copyInto ( temp ) ; foundMethod = mostSpecificMethodBinding ( temp , temp . length , argumentTypes , invocationSite , null ) ; } } } if ( foundMethod != null ) { invocationSite . setActualReceiverType ( foundMethod . declaringClass ) ; return foundMethod ; } if ( foundProblem != null ) return foundProblem ; return new ProblemMethodBinding ( selector , argumentTypes , ProblemReasons . NotFound ) ; } public final ReferenceBinding getJavaIoSerializable ( ) { CompilationUnitScope unitScope = compilationUnitScope ( ) ; unitScope . recordQualifiedReference ( TypeConstants . JAVA_IO_SERIALIZABLE ) ; return unitScope . environment . getResolvedType ( TypeConstants . JAVA_IO_SERIALIZABLE , this ) ; } public final ReferenceBinding getJavaLangAnnotationAnnotation ( ) { CompilationUnitScope unitScope = compilationUnitScope ( ) ; unitScope . recordQualifiedReference ( TypeConstants . JAVA_LANG_ANNOTATION_ANNOTATION ) ; return unitScope . environment . getResolvedType ( TypeConstants . JAVA_LANG_ANNOTATION_ANNOTATION , this ) ; } public final ReferenceBinding getJavaLangAssertionError ( ) { CompilationUnitScope unitScope = compilationUnitScope ( ) ; unitScope . recordQualifiedReference ( TypeConstants . JAVA_LANG_ASSERTIONERROR ) ; return unitScope . environment . getResolvedType ( TypeConstants . JAVA_LANG_ASSERTIONERROR , this ) ; } public final ReferenceBinding getJavaLangClass ( ) { CompilationUnitScope unitScope = compilationUnitScope ( ) ; unitScope . recordQualifiedReference ( TypeConstants . JAVA_LANG_CLASS ) ; return unitScope . environment . getResolvedType ( TypeConstants . JAVA_LANG_CLASS , this ) ; } public final ReferenceBinding getJavaLangCloneable ( ) { CompilationUnitScope unitScope = compilationUnitScope ( ) ; unitScope . recordQualifiedReference ( TypeConstants . JAVA_LANG_CLONEABLE ) ; return unitScope . environment . getResolvedType ( TypeConstants . JAVA_LANG_CLONEABLE , this ) ; } public final ReferenceBinding getJavaLangEnum ( ) { CompilationUnitScope unitScope = compilationUnitScope ( ) ; unitScope . recordQualifiedReference ( TypeConstants . JAVA_LANG_ENUM ) ; return unitScope . environment . getResolvedType ( TypeConstants . JAVA_LANG_ENUM , this ) ; } public final ReferenceBinding getJavaLangIterable ( ) { CompilationUnitScope unitScope = compilationUnitScope ( ) ; unitScope . recordQualifiedReference ( TypeConstants . JAVA_LANG_ITERABLE ) ; return unitScope . environment . getResolvedType ( TypeConstants . JAVA_LANG_ITERABLE , this ) ; } public final ReferenceBinding getJavaLangObject ( ) { CompilationUnitScope unitScope = compilationUnitScope ( ) ; unitScope . recordQualifiedReference ( TypeConstants . JAVA_LANG_OBJECT ) ; return unitScope . environment . getResolvedType ( TypeConstants . JAVA_LANG_OBJECT , this ) ; } public final ReferenceBinding getJavaLangString ( ) { CompilationUnitScope unitScope = compilationUnitScope ( ) ; unitScope . recordQualifiedReference ( TypeConstants . JAVA_LANG_STRING ) ; return unitScope . environment . getResolvedType ( TypeConstants . JAVA_LANG_STRING , this ) ; } public final ReferenceBinding getJavaLangThrowable ( ) { CompilationUnitScope unitScope = compilationUnitScope ( ) ; unitScope . recordQualifiedReference ( TypeConstants . JAVA_LANG_THROWABLE ) ; return unitScope . environment . getResolvedType ( TypeConstants . JAVA_LANG_THROWABLE , this ) ; } public final ReferenceBinding getJavaUtilIterator ( ) { CompilationUnitScope unitScope = compilationUnitScope ( ) ; unitScope . recordQualifiedReference ( TypeConstants . JAVA_UTIL_ITERATOR ) ; return unitScope . environment . getResolvedType ( TypeConstants . JAVA_UTIL_ITERATOR , this ) ; } public final ReferenceBinding getMemberType ( char [ ] typeName , ReferenceBinding enclosingType ) { ReferenceBinding memberType = findMemberType ( typeName , enclosingType ) ; if ( memberType != null ) return memberType ; char [ ] [ ] compoundName = new char [ ] [ ] { typeName } ; return new ProblemReferenceBinding ( compoundName , null , ProblemReasons . NotFound ) ; } public MethodBinding getMethod ( TypeBinding receiverType , char [ ] selector , TypeBinding [ ] argumentTypes , InvocationSite invocationSite ) { CompilationUnitScope unitScope = compilationUnitScope ( ) ; LookupEnvironment env = unitScope . environment ; try { env . missingClassFileLocation = invocationSite ; switch ( receiverType . kind ( ) ) { case Binding . BASE_TYPE : return new ProblemMethodBinding ( selector , argumentTypes , ProblemReasons . NotFound ) ; case Binding . ARRAY_TYPE : unitScope . recordTypeReference ( receiverType ) ; return findMethodForArray ( ( ArrayBinding ) receiverType , selector , argumentTypes , invocationSite ) ; } unitScope . recordTypeReference ( receiverType ) ; ReferenceBinding currentType = ( ReferenceBinding ) receiverType ; if ( ! currentType . canBeSeenBy ( this ) ) return new ProblemMethodBinding ( selector , argumentTypes , ProblemReasons . ReceiverTypeNotVisible ) ; MethodBinding methodBinding = findExactMethod ( currentType , selector , argumentTypes , invocationSite ) ; if ( methodBinding != null ) return methodBinding ; methodBinding = findMethod ( currentType , selector , argumentTypes , invocationSite ) ; if ( methodBinding == null ) { methodBinding = oneLastLook ( currentType , selector , argumentTypes , invocationSite ) ; } if ( methodBinding == null ) return new ProblemMethodBinding ( selector , argumentTypes , ProblemReasons . NotFound ) ; if ( ! methodBinding . isValidBinding ( ) ) return methodBinding ; if ( argumentTypes == Binding . NO_PARAMETERS && CharOperation . equals ( selector , TypeConstants . GETCLASS ) && methodBinding . returnType . isParameterizedType ( ) ) { return environment ( ) . createGetClassMethod ( receiverType , methodBinding , this ) ; } return methodBinding ; } catch ( AbortCompilation e ) { e . updateContext ( invocationSite , referenceCompilationUnit ( ) . compilationResult ) ; throw e ; } finally { env . missingClassFileLocation = null ; } } public final Binding getPackage ( char [ ] [ ] compoundName ) { compilationUnitScope ( ) . recordQualifiedReference ( compoundName ) ; Binding binding = getTypeOrPackage ( compoundName [ 0 ] , Binding . TYPE | Binding . PACKAGE , true ) ; if ( binding == null ) { char [ ] [ ] qName = new char [ ] [ ] { compoundName [ 0 ] } ; return new ProblemReferenceBinding ( qName , environment ( ) . createMissingType ( null , compoundName ) , ProblemReasons . NotFound ) ; } if ( ! binding . isValidBinding ( ) ) { if ( binding instanceof PackageBinding ) { char [ ] [ ] qName = new char [ ] [ ] { compoundName [ 0 ] } ; return new ProblemReferenceBinding ( qName , null , ProblemReasons . NotFound ) ; } return binding ; } if ( ! ( binding instanceof PackageBinding ) ) return null ; int currentIndex = 1 , length = compoundName . length ; PackageBinding packageBinding = ( PackageBinding ) binding ; while ( currentIndex < length ) { binding = packageBinding . getTypeOrPackage ( compoundName [ currentIndex ++ ] ) ; if ( binding == null ) { return new ProblemReferenceBinding ( CharOperation . subarray ( compoundName , 0 , currentIndex ) , null , ProblemReasons . NotFound ) ; } if ( ! binding . isValidBinding ( ) ) return new ProblemReferenceBinding ( CharOperation . subarray ( compoundName , 0 , currentIndex ) , binding instanceof ReferenceBinding ? ( ReferenceBinding ) ( ( ReferenceBinding ) binding ) . closestMatch ( ) : null , binding . problemId ( ) ) ; if ( ! ( binding instanceof PackageBinding ) ) return packageBinding ; packageBinding = ( PackageBinding ) binding ; } return new ProblemReferenceBinding ( compoundName , null , ProblemReasons . NotFound ) ; } public final TypeBinding getType ( char [ ] name ) { TypeBinding binding = getBaseType ( name ) ; if ( binding != null ) return binding ; return ( ReferenceBinding ) getTypeOrPackage ( name , Binding . TYPE , true ) ; } public final TypeBinding getType ( char [ ] name , PackageBinding packageBinding ) { if ( packageBinding == null ) return getType ( name ) ; Binding binding = packageBinding . getTypeOrPackage ( name ) ; if ( binding == null ) { return new ProblemReferenceBinding ( CharOperation . arrayConcat ( packageBinding . compoundName , name ) , null , ProblemReasons . NotFound ) ; } if ( ! binding . isValidBinding ( ) ) { return new ProblemReferenceBinding ( binding instanceof ReferenceBinding ? ( ( ReferenceBinding ) binding ) . compoundName : CharOperation . arrayConcat ( packageBinding . compoundName , name ) , binding instanceof ReferenceBinding ? ( ReferenceBinding ) ( ( ReferenceBinding ) binding ) . closestMatch ( ) : null , binding . problemId ( ) ) ; } ReferenceBinding typeBinding = ( ReferenceBinding ) binding ; if ( ! typeBinding . canBeSeenBy ( this ) ) return new ProblemReferenceBinding ( typeBinding . compoundName , typeBinding , ProblemReasons . NotVisible ) ; return typeBinding ; } public final TypeBinding getType ( char [ ] [ ] compoundName , int typeNameLength ) { if ( typeNameLength == 1 ) { TypeBinding binding = getBaseType ( compoundName [ 0 ] ) ; if ( binding != null ) return binding ; } CompilationUnitScope unitScope = compilationUnitScope ( ) ; unitScope . recordQualifiedReference ( compoundName ) ; Binding binding = getTypeOrPackage ( compoundName [ 0 ] , typeNameLength == 1 ? Binding . TYPE : Binding . TYPE | Binding . PACKAGE , true ) ; if ( binding == null ) { char [ ] [ ] qName = new char [ ] [ ] { compoundName [ 0 ] } ; return new ProblemReferenceBinding ( qName , environment ( ) . createMissingType ( compilationUnitScope ( ) . getCurrentPackage ( ) , qName ) , ProblemReasons . NotFound ) ; } if ( ! binding . isValidBinding ( ) ) { if ( binding instanceof PackageBinding ) { char [ ] [ ] qName = new char [ ] [ ] { compoundName [ 0 ] } ; return new ProblemReferenceBinding ( qName , environment ( ) . createMissingType ( null , qName ) , ProblemReasons . NotFound ) ; } return ( ReferenceBinding ) binding ; } int currentIndex = 1 ; boolean checkVisibility = false ; if ( binding instanceof PackageBinding ) { PackageBinding packageBinding = ( PackageBinding ) binding ; while ( currentIndex < typeNameLength ) { binding = packageBinding . getTypeOrPackage ( compoundName [ currentIndex ++ ] ) ; if ( binding == null ) { char [ ] [ ] qName = CharOperation . subarray ( compoundName , 0 , currentIndex ) ; return new ProblemReferenceBinding ( qName , environment ( ) . createMissingType ( packageBinding , qName ) , ProblemReasons . NotFound ) ; } if ( ! binding . isValidBinding ( ) ) return new ProblemReferenceBinding ( CharOperation . subarray ( compoundName , 0 , currentIndex ) , binding instanceof ReferenceBinding ? ( ReferenceBinding ) ( ( ReferenceBinding ) binding ) . closestMatch ( ) : null , binding . problemId ( ) ) ; if ( ! ( binding instanceof PackageBinding ) ) break ; packageBinding = ( PackageBinding ) binding ; } if ( binding instanceof PackageBinding ) { char [ ] [ ] qName = CharOperation . subarray ( compoundName , 0 , currentIndex ) ; return new ProblemReferenceBinding ( qName , environment ( ) . createMissingType ( null , qName ) , ProblemReasons . NotFound ) ; } checkVisibility = true ; } ReferenceBinding typeBinding = ( ReferenceBinding ) binding ; unitScope . recordTypeReference ( typeBinding ) ; if ( checkVisibility ) if ( ! typeBinding . canBeSeenBy ( this ) ) return new ProblemReferenceBinding ( CharOperation . subarray ( compoundName , 0 , currentIndex ) , typeBinding , ProblemReasons . NotVisible ) ; while ( currentIndex < typeNameLength ) { typeBinding = getMemberType ( compoundName [ currentIndex ++ ] , typeBinding ) ; if ( ! typeBinding . isValidBinding ( ) ) { if ( typeBinding instanceof ProblemReferenceBinding ) { ProblemReferenceBinding problemBinding = ( ProblemReferenceBinding ) typeBinding ; return new ProblemReferenceBinding ( CharOperation . subarray ( compoundName , 0 , currentIndex ) , problemBinding . closestReferenceMatch ( ) , typeBinding . problemId ( ) ) ; } return new ProblemReferenceBinding ( CharOperation . subarray ( compoundName , 0 , currentIndex ) , ( ReferenceBinding ) ( ( ReferenceBinding ) binding ) . closestMatch ( ) , typeBinding . problemId ( ) ) ; } } return typeBinding ; } final Binding getTypeOrPackage ( char [ ] name , int mask , boolean needResolve ) { Scope scope = this ; ReferenceBinding foundType = null ; boolean insideStaticContext = false ; boolean insideTypeAnnotation = false ; if ( ( mask & Binding . TYPE ) == 0 ) { Scope next = scope ; while ( ( next = scope . parent ) != null ) scope = next ; } else { boolean inheritedHasPrecedence = compilerOptions ( ) . complianceLevel >= ClassFileConstants . JDK1_4 ; done : while ( true ) { switch ( scope . kind ) { case METHOD_SCOPE : MethodScope methodScope = ( MethodScope ) scope ; AbstractMethodDeclaration methodDecl = methodScope . referenceMethod ( ) ; if ( methodDecl != null ) { if ( methodDecl . binding != null ) { TypeVariableBinding typeVariable = methodDecl . binding . getTypeVariable ( name ) ; if ( typeVariable != null ) return typeVariable ; } else { TypeParameter [ ] params = methodDecl . typeParameters ( ) ; for ( int i = params == null ? 0 : params . length ; -- i >= 0 ; ) if ( CharOperation . equals ( params [ i ] . name , name ) ) if ( params [ i ] . binding != null && params [ i ] . binding . isValidBinding ( ) ) return params [ i ] . binding ; } } insideStaticContext |= methodScope . isStatic ; insideTypeAnnotation = methodScope . insideTypeAnnotation ; case BLOCK_SCOPE : ReferenceBinding localType = ( ( BlockScope ) scope ) . findLocalType ( name ) ; if ( localType != null ) { if ( foundType != null && foundType != localType ) return new ProblemReferenceBinding ( new char [ ] [ ] { name } , foundType , ProblemReasons . InheritedNameHidesEnclosingName ) ; return localType ; } break ; case CLASS_SCOPE : SourceTypeBinding sourceType = ( ( ClassScope ) scope ) . referenceContext . binding ; if ( scope == this && ( sourceType . tagBits & TagBits . TypeVariablesAreConnected ) == 0 ) { TypeVariableBinding typeVariable = sourceType . getTypeVariable ( name ) ; if ( typeVariable != null ) return typeVariable ; if ( CharOperation . equals ( name , sourceType . sourceName ) ) return sourceType ; insideStaticContext |= sourceType . isStatic ( ) ; break ; } if ( ! insideTypeAnnotation ) { ReferenceBinding memberType = findMemberType ( name , sourceType ) ; if ( memberType != null ) { if ( memberType . problemId ( ) == ProblemReasons . Ambiguous ) { if ( foundType == null || foundType . problemId ( ) == ProblemReasons . NotVisible ) return memberType ; return new ProblemReferenceBinding ( new char [ ] [ ] { name } , foundType , ProblemReasons . InheritedNameHidesEnclosingName ) ; } if ( memberType . isValidBinding ( ) ) { if ( sourceType == memberType . enclosingType ( ) || inheritedHasPrecedence ) { if ( insideStaticContext && ! memberType . isStatic ( ) && sourceType . isGenericType ( ) ) return new ProblemReferenceBinding ( new char [ ] [ ] { name } , memberType , ProblemReasons . NonStaticReferenceInStaticContext ) ; if ( foundType == null || ( inheritedHasPrecedence && foundType . problemId ( ) == ProblemReasons . NotVisible ) ) return memberType ; if ( foundType . isValidBinding ( ) && foundType != memberType ) return new ProblemReferenceBinding ( new char [ ] [ ] { name } , foundType , ProblemReasons . InheritedNameHidesEnclosingName ) ; } } if ( foundType == null || ( foundType . problemId ( ) == ProblemReasons . NotVisible && memberType . problemId ( ) != ProblemReasons . NotVisible ) ) foundType = memberType ; } } TypeVariableBinding typeVariable = sourceType . getTypeVariable ( name ) ; if ( typeVariable != null ) { if ( insideStaticContext ) return new ProblemReferenceBinding ( new char [ ] [ ] { name } , typeVariable , ProblemReasons . NonStaticReferenceInStaticContext ) ; return typeVariable ; } insideStaticContext |= sourceType . isStatic ( ) ; insideTypeAnnotation = false ; if ( CharOperation . equals ( sourceType . sourceName , name ) ) { if ( foundType != null && foundType != sourceType && foundType . problemId ( ) != ProblemReasons . NotVisible ) return new ProblemReferenceBinding ( new char [ ] [ ] { name } , foundType , ProblemReasons . InheritedNameHidesEnclosingName ) ; return sourceType ; } break ; case COMPILATION_UNIT_SCOPE : break done ; } scope = scope . parent ; } if ( foundType != null && foundType . problemId ( ) != ProblemReasons . NotVisible ) return foundType ; } CompilationUnitScope unitScope = ( CompilationUnitScope ) scope ; HashtableOfObject typeOrPackageCache = unitScope . typeOrPackageCache ; if ( typeOrPackageCache != null ) { Binding cachedBinding = ( Binding ) typeOrPackageCache . get ( name ) ; if ( cachedBinding != null ) { if ( cachedBinding instanceof ImportBinding ) { ImportReference importReference = ( ( ImportBinding ) cachedBinding ) . reference ; if ( importReference != null ) { importReference . bits |= ASTNode . Used ; } if ( cachedBinding instanceof ImportConflictBinding ) typeOrPackageCache . put ( name , cachedBinding = ( ( ImportConflictBinding ) cachedBinding ) . conflictingTypeBinding ) ; else typeOrPackageCache . put ( name , cachedBinding = ( ( ImportBinding ) cachedBinding ) . resolvedImport ) ; } if ( ( mask & Binding . TYPE ) != 0 ) { if ( foundType != null && foundType . problemId ( ) != ProblemReasons . NotVisible && cachedBinding . problemId ( ) != ProblemReasons . Ambiguous ) return foundType ; if ( cachedBinding instanceof ReferenceBinding ) return cachedBinding ; } if ( ( mask & Binding . PACKAGE ) != 0 && cachedBinding instanceof PackageBinding ) return cachedBinding ; } } if ( ( mask & Binding . TYPE ) != 0 ) { ImportBinding [ ] imports = unitScope . imports ; if ( imports != null && typeOrPackageCache == null ) { nextImport : for ( int i = 0 , length = imports . length ; i < length ; i ++ ) { ImportBinding importBinding = imports [ i ] ; if ( ! importBinding . onDemand ) { if ( CharOperation . equals ( getSimpleName ( importBinding ) , name ) ) { Binding resolvedImport = unitScope . resolveSingleImport ( importBinding , Binding . TYPE ) ; if ( resolvedImport == null ) continue nextImport ; if ( resolvedImport instanceof TypeBinding ) { ImportReference importReference = importBinding . reference ; if ( importReference != null ) importReference . bits |= ASTNode . Used ; return resolvedImport ; } } } } } PackageBinding currentPackage = unitScope . fPackage ; unitScope . recordReference ( currentPackage . compoundName , name ) ; Binding binding = currentPackage . getTypeOrPackage ( name ) ; if ( binding instanceof ReferenceBinding ) { ReferenceBinding referenceType = ( ReferenceBinding ) binding ; if ( ( referenceType . tagBits & TagBits . HasMissingType ) == 0 ) { if ( typeOrPackageCache != null ) typeOrPackageCache . put ( name , referenceType ) ; return referenceType ; } } if ( imports != null ) { boolean foundInImport = false ; ReferenceBinding type = null ; for ( int i = 0 , length = imports . length ; i < length ; i ++ ) { ImportBinding someImport = imports [ i ] ; if ( someImport . onDemand ) { Binding resolvedImport = someImport . resolvedImport ; ReferenceBinding temp = null ; if ( resolvedImport instanceof PackageBinding ) { temp = findType ( name , ( PackageBinding ) resolvedImport , currentPackage ) ; } else if ( someImport . isStatic ( ) ) { temp = findMemberType ( name , ( ReferenceBinding ) resolvedImport ) ; if ( temp != null && ! temp . isStatic ( ) ) temp = null ; } else { temp = findDirectMemberType ( name , ( ReferenceBinding ) resolvedImport ) ; } if ( temp != type && temp != null ) { if ( temp . isValidBinding ( ) ) { boolean conflict = true ; if ( this . parent != null && foundInImport ) { CompilationUnitScope cuScope = compilationUnitScope ( ) ; if ( cuScope != null ) { ReferenceBinding chosenBinding = cuScope . selectBinding ( temp , type , someImport . reference != null ) ; if ( chosenBinding != null ) { conflict = false ; foundInImport = true ; type = chosenBinding ; } } } if ( conflict ) { ImportReference importReference = someImport . reference ; if ( importReference != null ) { importReference . bits |= ASTNode . Used ; } if ( foundInImport ) { temp = new ProblemReferenceBinding ( new char [ ] [ ] { name } , type , ProblemReasons . Ambiguous ) ; if ( typeOrPackageCache != null ) typeOrPackageCache . put ( name , temp ) ; return temp ; } type = temp ; foundInImport = true ; } } else if ( foundType == null ) { foundType = temp ; } } } } if ( type != null ) { if ( typeOrPackageCache != null ) typeOrPackageCache . put ( name , type ) ; return type ; } } } unitScope . recordSimpleReference ( name ) ; if ( ( mask & Binding . PACKAGE ) != 0 ) { PackageBinding packageBinding = unitScope . environment . getTopLevelPackage ( name ) ; if ( packageBinding != null ) { if ( typeOrPackageCache != null ) typeOrPackageCache . put ( name , packageBinding ) ; return packageBinding ; } } if ( foundType == null ) { char [ ] [ ] qName = new char [ ] [ ] { name } ; ReferenceBinding closestMatch = null ; if ( ( mask & Binding . PACKAGE ) != 0 ) { if ( needResolve ) { closestMatch = environment ( ) . createMissingType ( unitScope . fPackage , qName ) ; } } else { PackageBinding packageBinding = unitScope . environment . getTopLevelPackage ( name ) ; if ( packageBinding == null || ! packageBinding . isValidBinding ( ) ) { if ( needResolve ) { closestMatch = environment ( ) . createMissingType ( unitScope . fPackage , qName ) ; } } } foundType = new ProblemReferenceBinding ( qName , closestMatch , ProblemReasons . NotFound ) ; if ( typeOrPackageCache != null && ( mask & Binding . PACKAGE ) != 0 ) { typeOrPackageCache . put ( name , foundType ) ; } } else if ( ( foundType . tagBits & TagBits . HasMissingType ) != 0 ) { char [ ] [ ] qName = new char [ ] [ ] { name } ; foundType = new ProblemReferenceBinding ( qName , foundType , ProblemReasons . NotFound ) ; if ( typeOrPackageCache != null && ( mask & Binding . PACKAGE ) != 0 ) typeOrPackageCache . put ( name , foundType ) ; } return foundType ; } public final Binding getTypeOrPackage ( char [ ] [ ] compoundName ) { int nameLength = compoundName . length ; if ( nameLength == 1 ) { TypeBinding binding = getBaseType ( compoundName [ 0 ] ) ; if ( binding != null ) return binding ; } Binding binding = getTypeOrPackage ( compoundName [ 0 ] , Binding . TYPE | Binding . PACKAGE , true ) ; if ( ! binding . isValidBinding ( ) ) return binding ; int currentIndex = 1 ; boolean checkVisibility = false ; if ( binding instanceof PackageBinding ) { PackageBinding packageBinding = ( PackageBinding ) binding ; while ( currentIndex < nameLength ) { binding = packageBinding . getTypeOrPackage ( compoundName [ currentIndex ++ ] ) ; if ( binding == null ) return new ProblemReferenceBinding ( CharOperation . subarray ( compoundName , 0 , currentIndex ) , null , ProblemReasons . NotFound ) ; if ( ! binding . isValidBinding ( ) ) return new ProblemReferenceBinding ( CharOperation . subarray ( compoundName , 0 , currentIndex ) , binding instanceof ReferenceBinding ? ( ReferenceBinding ) ( ( ReferenceBinding ) binding ) . closestMatch ( ) : null , binding . problemId ( ) ) ; if ( ! ( binding instanceof PackageBinding ) ) break ; packageBinding = ( PackageBinding ) binding ; } if ( binding instanceof PackageBinding ) return binding ; checkVisibility = true ; } ReferenceBinding typeBinding = ( ReferenceBinding ) binding ; ReferenceBinding qualifiedType = ( ReferenceBinding ) environment ( ) . convertToRawType ( typeBinding , false ) ; if ( checkVisibility ) if ( ! typeBinding . canBeSeenBy ( this ) ) return new ProblemReferenceBinding ( CharOperation . subarray ( compoundName , 0 , currentIndex ) , typeBinding , ProblemReasons . NotVisible ) ; while ( currentIndex < nameLength ) { typeBinding = getMemberType ( compoundName [ currentIndex ++ ] , typeBinding ) ; if ( ! typeBinding . isValidBinding ( ) ) return new ProblemReferenceBinding ( CharOperation . subarray ( compoundName , 0 , currentIndex ) , ( ReferenceBinding ) typeBinding . closestMatch ( ) , typeBinding . problemId ( ) ) ; if ( typeBinding . isGenericType ( ) ) { qualifiedType = environment ( ) . createRawType ( typeBinding , qualifiedType ) ; } else { qualifiedType = ( qualifiedType != null && ( qualifiedType . isRawType ( ) || qualifiedType . isParameterizedType ( ) ) ) ? environment ( ) . createParameterizedType ( typeBinding , null , qualifiedType ) : typeBinding ; } } return qualifiedType ; } protected boolean hasErasedCandidatesCollisions ( TypeBinding one , TypeBinding two , Map invocations , ReferenceBinding type , ASTNode typeRef ) { invocations . clear ( ) ; TypeBinding [ ] mecs = minimalErasedCandidates ( new TypeBinding [ ] { one , two } , invocations ) ; if ( mecs != null ) { nextCandidate : for ( int k = 0 , max = mecs . length ; k < max ; k ++ ) { TypeBinding mec = mecs [ k ] ; if ( mec == null ) continue nextCandidate ; Object value = invocations . get ( mec ) ; if ( value instanceof TypeBinding [ ] ) { TypeBinding [ ] invalidInvocations = ( TypeBinding [ ] ) value ; problemReporter ( ) . superinterfacesCollide ( invalidInvocations [ 0 ] . erasure ( ) , typeRef , invalidInvocations [ 0 ] , invalidInvocations [ 1 ] ) ; type . tagBits |= TagBits . HierarchyHasProblems ; return true ; } } } return false ; } protected char [ ] getSimpleName ( ImportBinding importBinding ) { if ( importBinding . reference == null ) { return importBinding . compoundName [ importBinding . compoundName . length - 1 ] ; } else { return importBinding . reference . getSimpleName ( ) ; } } public CaseStatement innermostSwitchCase ( ) { Scope scope = this ; do { if ( scope instanceof BlockScope ) return ( ( BlockScope ) scope ) . enclosingCase ; scope = scope . parent ; } while ( scope != null ) ; return null ; } protected boolean isAcceptableMethod ( MethodBinding one , MethodBinding two ) { TypeBinding [ ] oneParams = one . parameters ; TypeBinding [ ] twoParams = two . parameters ; int oneParamsLength = oneParams . length ; int twoParamsLength = twoParams . length ; if ( oneParamsLength == twoParamsLength ) { boolean applyErasure = environment ( ) . globalOptions . sourceLevel < ClassFileConstants . JDK1_5 ; next : for ( int i = 0 ; i < oneParamsLength ; i ++ ) { TypeBinding oneParam = applyErasure ? oneParams [ i ] . erasure ( ) : oneParams [ i ] ; TypeBinding twoParam = applyErasure ? twoParams [ i ] . erasure ( ) : twoParams [ i ] ; if ( oneParam == twoParam || oneParam . isCompatibleWith ( twoParam ) ) { if ( two . declaringClass . isRawType ( ) ) continue next ; TypeBinding leafComponentType = two . original ( ) . parameters [ i ] . leafComponentType ( ) ; TypeBinding originalTwoParam = applyErasure ? leafComponentType . erasure ( ) : leafComponentType ; switch ( originalTwoParam . kind ( ) ) { case Binding . TYPE_PARAMETER : if ( ( ( TypeVariableBinding ) originalTwoParam ) . hasOnlyRawBounds ( ) ) continue next ; case Binding . WILDCARD_TYPE : case Binding . INTERSECTION_TYPE : case Binding . PARAMETERIZED_TYPE : TypeBinding originalOneParam = one . original ( ) . parameters [ i ] . leafComponentType ( ) ; switch ( originalOneParam . kind ( ) ) { case Binding . TYPE : case Binding . GENERIC_TYPE : TypeBinding inheritedTwoParam = oneParam . findSuperTypeOriginatingFrom ( twoParam ) ; if ( inheritedTwoParam == null || ! inheritedTwoParam . leafComponentType ( ) . isRawType ( ) ) break ; return false ; case Binding . TYPE_PARAMETER : if ( ! ( ( TypeVariableBinding ) originalOneParam ) . upperBound ( ) . isRawType ( ) ) break ; return false ; case Binding . RAW_TYPE : return false ; } } } else { if ( i == oneParamsLength - 1 && one . isVarargs ( ) && two . isVarargs ( ) ) { TypeBinding eType = ( ( ArrayBinding ) twoParam ) . elementsType ( ) ; if ( oneParam == eType || oneParam . isCompatibleWith ( eType ) ) return true ; } return false ; } } return true ; } if ( one . isVarargs ( ) && two . isVarargs ( ) ) { if ( oneParamsLength > twoParamsLength ) { if ( ( ( ArrayBinding ) twoParams [ twoParamsLength - 1 ] ) . elementsType ( ) . id != TypeIds . T_JavaLangObject ) return false ; } for ( int i = ( oneParamsLength > twoParamsLength ? twoParamsLength : oneParamsLength ) - 2 ; i >= 0 ; i -- ) if ( oneParams [ i ] != twoParams [ i ] && ! oneParams [ i ] . isCompatibleWith ( twoParams [ i ] ) ) return false ; if ( parameterCompatibilityLevel ( one , twoParams ) == NOT_COMPATIBLE && parameterCompatibilityLevel ( two , oneParams ) == VARARGS_COMPATIBLE ) return true ; } return false ; } public boolean isBoxingCompatibleWith ( TypeBinding expressionType , TypeBinding targetType ) { LookupEnvironment environment = environment ( ) ; if ( environment . globalOptions . sourceLevel < ClassFileConstants . JDK1_5 || expressionType . isBaseType ( ) == targetType . isBaseType ( ) ) return false ; TypeBinding convertedType = environment . computeBoxingType ( expressionType ) ; return convertedType == targetType || convertedType . isCompatibleWith ( targetType ) ; } public final boolean isDefinedInField ( FieldBinding field ) { Scope scope = this ; do { if ( scope instanceof MethodScope ) { MethodScope methodScope = ( MethodScope ) scope ; if ( methodScope . initializedField == field ) return true ; } scope = scope . parent ; } while ( scope != null ) ; return false ; } public final boolean isDefinedInMethod ( MethodBinding method ) { Scope scope = this ; do { if ( scope instanceof MethodScope ) { ReferenceContext refContext = ( ( MethodScope ) scope ) . referenceContext ; if ( refContext instanceof AbstractMethodDeclaration ) if ( ( ( AbstractMethodDeclaration ) refContext ) . binding == method ) return true ; } scope = scope . parent ; } while ( scope != null ) ; return false ; } public final boolean isDefinedInSameUnit ( ReferenceBinding type ) { ReferenceBinding enclosingType = type ; while ( ( type = enclosingType . enclosingType ( ) ) != null ) enclosingType = type ; Scope scope , unitScope = this ; while ( ( scope = unitScope . parent ) != null ) unitScope = scope ; SourceTypeBinding [ ] topLevelTypes = ( ( CompilationUnitScope ) unitScope ) . topLevelTypes ; for ( int i = topLevelTypes . length ; -- i >= 0 ; ) if ( topLevelTypes [ i ] == enclosingType ) return true ; return false ; } public final boolean isDefinedInType ( ReferenceBinding type ) { Scope scope = this ; do { if ( scope instanceof ClassScope ) if ( ( ( ClassScope ) scope ) . referenceContext . binding == type ) return true ; scope = scope . parent ; } while ( scope != null ) ; return false ; } public boolean isInsideCase ( CaseStatement caseStatement ) { Scope scope = this ; do { switch ( scope . kind ) { case Scope . BLOCK_SCOPE : if ( ( ( BlockScope ) scope ) . enclosingCase == caseStatement ) { return true ; } } scope = scope . parent ; } while ( scope != null ) ; return false ; } public boolean isInsideDeprecatedCode ( ) { switch ( this . kind ) { case Scope . BLOCK_SCOPE : case Scope . METHOD_SCOPE : MethodScope methodScope = methodScope ( ) ; if ( ! methodScope . isInsideInitializer ( ) ) { MethodBinding context = ( ( AbstractMethodDeclaration ) methodScope . referenceContext ) . binding ; if ( context != null && context . isViewedAsDeprecated ( ) ) return true ; } else if ( methodScope . initializedField != null && methodScope . initializedField . isViewedAsDeprecated ( ) ) { return true ; } SourceTypeBinding declaringType = ( ( BlockScope ) this ) . referenceType ( ) . binding ; if ( declaringType != null ) { declaringType . initializeDeprecatedAnnotationTagBits ( ) ; if ( declaringType . isViewedAsDeprecated ( ) ) return true ; } break ; case Scope . CLASS_SCOPE : ReferenceBinding context = ( ( ClassScope ) this ) . referenceType ( ) . binding ; if ( context != null ) { context . initializeDeprecatedAnnotationTagBits ( ) ; if ( context . isViewedAsDeprecated ( ) ) return true ; } break ; case Scope . COMPILATION_UNIT_SCOPE : CompilationUnitDeclaration unit = referenceCompilationUnit ( ) ; if ( unit . types != null && unit . types . length > 0 ) { SourceTypeBinding type = unit . types [ 0 ] . binding ; if ( type != null ) { type . initializeDeprecatedAnnotationTagBits ( ) ; if ( type . isViewedAsDeprecated ( ) ) return true ; } } } return false ; } private boolean isOverriddenMethodGeneric ( MethodBinding method ) { MethodVerifier verifier = environment ( ) . methodVerifier ( ) ; ReferenceBinding currentType = method . declaringClass . superclass ( ) ; while ( currentType != null ) { MethodBinding [ ] currentMethods = currentType . getMethods ( method . selector ) ; for ( int i = 0 , l = currentMethods . length ; i < l ; i ++ ) { MethodBinding currentMethod = currentMethods [ i ] ; if ( currentMethod != null && currentMethod . original ( ) . typeVariables != Binding . NO_TYPE_VARIABLES ) if ( verifier . doesMethodOverride ( method , currentMethod ) ) return true ; } currentType = currentType . superclass ( ) ; } return false ; } public boolean isPossibleSubtypeOfRawType ( TypeBinding paramType ) { TypeBinding t = paramType . leafComponentType ( ) ; if ( t . isBaseType ( ) ) return false ; ReferenceBinding currentType = ( ReferenceBinding ) t ; ReferenceBinding [ ] interfacesToVisit = null ; int nextPosition = 0 ; do { if ( currentType . isRawType ( ) ) return true ; if ( ! currentType . isHierarchyConnected ( ) ) return true ; ReferenceBinding [ ] itsInterfaces = currentType . superInterfaces ( ) ; if ( itsInterfaces != null && itsInterfaces != Binding . NO_SUPERINTERFACES ) { if ( interfacesToVisit == null ) { interfacesToVisit = itsInterfaces ; nextPosition = interfacesToVisit . length ; } else { int itsLength = itsInterfaces . length ; if ( nextPosition + itsLength >= interfacesToVisit . length ) System . arraycopy ( interfacesToVisit , 0 , interfacesToVisit = new ReferenceBinding [ nextPosition + itsLength + 5 ] , 0 , nextPosition ) ; nextInterface : for ( int a = 0 ; a < itsLength ; a ++ ) { ReferenceBinding next = itsInterfaces [ a ] ; for ( int b = 0 ; b < nextPosition ; b ++ ) if ( next == interfacesToVisit [ b ] ) continue nextInterface ; interfacesToVisit [ nextPosition ++ ] = next ; } } } } while ( ( currentType = currentType . superclass ( ) ) != null ) ; for ( int i = 0 ; i < nextPosition ; i ++ ) { currentType = interfacesToVisit [ i ] ; if ( currentType . isRawType ( ) ) return true ; ReferenceBinding [ ] itsInterfaces = currentType . superInterfaces ( ) ; if ( itsInterfaces != null && itsInterfaces != Binding . NO_SUPERINTERFACES ) { int itsLength = itsInterfaces . length ; if ( nextPosition + itsLength >= interfacesToVisit . length ) System . arraycopy ( interfacesToVisit , 0 , interfacesToVisit = new ReferenceBinding [ nextPosition + itsLength + 5 ] , 0 , nextPosition ) ; nextInterface : for ( int a = 0 ; a < itsLength ; a ++ ) { ReferenceBinding next = itsInterfaces [ a ] ; for ( int b = 0 ; b < nextPosition ; b ++ ) if ( next == interfacesToVisit [ b ] ) continue nextInterface ; interfacesToVisit [ nextPosition ++ ] = next ; } } } return false ; } private TypeBinding leastContainingInvocation ( TypeBinding mec , Object invocationData , List lubStack ) { if ( invocationData == null ) return mec ; if ( invocationData instanceof TypeBinding ) { return ( TypeBinding ) invocationData ; } TypeBinding [ ] invocations = ( TypeBinding [ ] ) invocationData ; int dim = mec . dimensions ( ) ; mec = mec . leafComponentType ( ) ; int argLength = mec . typeVariables ( ) . length ; if ( argLength == 0 ) return mec ; TypeBinding [ ] bestArguments = new TypeBinding [ argLength ] ; for ( int i = 0 , length = invocations . length ; i < length ; i ++ ) { TypeBinding invocation = invocations [ i ] . leafComponentType ( ) ; switch ( invocation . kind ( ) ) { case Binding . GENERIC_TYPE : TypeVariableBinding [ ] invocationVariables = invocation . typeVariables ( ) ; for ( int j = 0 ; j < argLength ; j ++ ) { TypeBinding bestArgument = leastContainingTypeArgument ( bestArguments [ j ] , invocationVariables [ j ] , ( ReferenceBinding ) mec , j , lubStack ) ; if ( bestArgument == null ) return null ; bestArguments [ j ] = bestArgument ; } break ; case Binding . PARAMETERIZED_TYPE : ParameterizedTypeBinding parameterizedType = ( ParameterizedTypeBinding ) invocation ; for ( int j = 0 ; j < argLength ; j ++ ) { TypeBinding bestArgument = leastContainingTypeArgument ( bestArguments [ j ] , parameterizedType . arguments [ j ] , ( ReferenceBinding ) mec , j , lubStack ) ; if ( bestArgument == null ) return null ; bestArguments [ j ] = bestArgument ; } break ; case Binding . RAW_TYPE : return dim == 0 ? invocation : environment ( ) . createArrayType ( invocation , dim ) ; } } TypeBinding least = environment ( ) . createParameterizedType ( ( ReferenceBinding ) mec . erasure ( ) , bestArguments , mec . enclosingType ( ) ) ; return dim == 0 ? least : environment ( ) . createArrayType ( least , dim ) ; } private TypeBinding leastContainingTypeArgument ( TypeBinding u , TypeBinding v , ReferenceBinding genericType , int rank , List lubStack ) { if ( u == null ) return v ; if ( u == v ) return u ; if ( v . isWildcard ( ) ) { WildcardBinding wildV = ( WildcardBinding ) v ; if ( u . isWildcard ( ) ) { WildcardBinding wildU = ( WildcardBinding ) u ; switch ( wildU . boundKind ) { case Wildcard . EXTENDS : switch ( wildV . boundKind ) { case Wildcard . EXTENDS : TypeBinding lub = lowerUpperBound ( new TypeBinding [ ] { wildU . bound , wildV . bound } , lubStack ) ; if ( lub == null ) return null ; if ( lub == TypeBinding . INT ) return environment ( ) . createWildcard ( genericType , rank , null , null , Wildcard . UNBOUND ) ; return environment ( ) . createWildcard ( genericType , rank , lub , null , Wildcard . EXTENDS ) ; case Wildcard . SUPER : if ( wildU . bound == wildV . bound ) return wildU . bound ; return environment ( ) . createWildcard ( genericType , rank , null , null , Wildcard . UNBOUND ) ; } break ; case Wildcard . SUPER : if ( wildU . boundKind == Wildcard . SUPER ) { TypeBinding [ ] glb = greaterLowerBound ( new TypeBinding [ ] { wildU . bound , wildV . bound } ) ; if ( glb == null ) return null ; return environment ( ) . createWildcard ( genericType , rank , glb [ 0 ] , null , Wildcard . SUPER ) ; } } } else { switch ( wildV . boundKind ) { case Wildcard . EXTENDS : TypeBinding lub = lowerUpperBound ( new TypeBinding [ ] { u , wildV . bound } , lubStack ) ; if ( lub == null ) return null ; if ( lub == TypeBinding . INT ) return environment ( ) . createWildcard ( genericType , rank , null , null , Wildcard . UNBOUND ) ; return environment ( ) . createWildcard ( genericType , rank , lub , null , Wildcard . EXTENDS ) ; case Wildcard . SUPER : TypeBinding [ ] glb = greaterLowerBound ( new TypeBinding [ ] { u , wildV . bound } ) ; if ( glb == null ) return null ; return environment ( ) . createWildcard ( genericType , rank , glb [ 0 ] , null , Wildcard . SUPER ) ; case Wildcard . UNBOUND : } } } else if ( u . isWildcard ( ) ) { WildcardBinding wildU = ( WildcardBinding ) u ; switch ( wildU . boundKind ) { case Wildcard . EXTENDS : TypeBinding lub = lowerUpperBound ( new TypeBinding [ ] { wildU . bound , v } , lubStack ) ; if ( lub == null ) return null ; if ( lub == TypeBinding . INT ) return environment ( ) . createWildcard ( genericType , rank , null , null , Wildcard . UNBOUND ) ; return environment ( ) . createWildcard ( genericType , rank , lub , null , Wildcard . EXTENDS ) ; case Wildcard . SUPER : TypeBinding [ ] glb = greaterLowerBound ( new TypeBinding [ ] { wildU . bound , v } ) ; if ( glb == null ) return null ; return environment ( ) . createWildcard ( genericType , rank , glb [ 0 ] , null , Wildcard . SUPER ) ; case Wildcard . UNBOUND : } } TypeBinding lub = lowerUpperBound ( new TypeBinding [ ] { u , v } , lubStack ) ; if ( lub == null ) return null ; if ( lub == TypeBinding . INT ) return environment ( ) . createWildcard ( genericType , rank , null , null , Wildcard . UNBOUND ) ; return environment ( ) . createWildcard ( genericType , rank , lub , null , Wildcard . EXTENDS ) ; } public TypeBinding lowerUpperBound ( TypeBinding [ ] types ) { int typeLength = types . length ; if ( typeLength == 1 ) { TypeBinding type = types [ 0 ] ; return type == null ? TypeBinding . VOID : type ; } return lowerUpperBound ( types , new ArrayList ( 1 ) ) ; } private TypeBinding lowerUpperBound ( TypeBinding [ ] types , List lubStack ) { int typeLength = types . length ; if ( typeLength == 1 ) { TypeBinding type = types [ 0 ] ; return type == null ? TypeBinding . VOID : type ; } int stackLength = lubStack . size ( ) ; nextLubCheck : for ( int i = 0 ; i < stackLength ; i ++ ) { TypeBinding [ ] lubTypes = ( TypeBinding [ ] ) lubStack . get ( i ) ; int lubTypeLength = lubTypes . length ; if ( lubTypeLength < typeLength ) continue nextLubCheck ; nextTypeCheck : for ( int j = 0 ; j < typeLength ; j ++ ) { TypeBinding type = types [ j ] ; if ( type == null ) continue nextTypeCheck ; for ( int k = 0 ; k < lubTypeLength ; k ++ ) { TypeBinding lubType = lubTypes [ k ] ; if ( lubType == null ) continue ; if ( lubType == type || lubType . isEquivalentTo ( type ) ) continue nextTypeCheck ; } continue nextLubCheck ; } return TypeBinding . INT ; } lubStack . add ( types ) ; Map invocations = new HashMap ( 1 ) ; TypeBinding [ ] mecs = minimalErasedCandidates ( types , invocations ) ; if ( mecs == null ) return null ; int length = mecs . length ; if ( length == 0 ) return TypeBinding . VOID ; int count = 0 ; TypeBinding firstBound = null ; int commonDim = - 1 ; for ( int i = 0 ; i < length ; i ++ ) { TypeBinding mec = mecs [ i ] ; if ( mec == null ) continue ; mec = leastContainingInvocation ( mec , invocations . get ( mec ) , lubStack ) ; if ( mec == null ) return null ; int dim = mec . dimensions ( ) ; if ( commonDim == - 1 ) { commonDim = dim ; } else if ( dim != commonDim ) { return null ; } if ( firstBound == null && ! mec . leafComponentType ( ) . isInterface ( ) ) firstBound = mec . leafComponentType ( ) ; mecs [ count ++ ] = mec ; } switch ( count ) { case 0 : return TypeBinding . VOID ; case 1 : return mecs [ 0 ] ; case 2 : if ( ( commonDim == 0 ? mecs [ 1 ] . id : mecs [ 1 ] . leafComponentType ( ) . id ) == TypeIds . T_JavaLangObject ) return mecs [ 0 ] ; if ( ( commonDim == 0 ? mecs [ 0 ] . id : mecs [ 0 ] . leafComponentType ( ) . id ) == TypeIds . T_JavaLangObject ) return mecs [ 1 ] ; } TypeBinding [ ] otherBounds = new TypeBinding [ count - 1 ] ; int rank = 0 ; for ( int i = 0 ; i < count ; i ++ ) { TypeBinding mec = commonDim == 0 ? mecs [ i ] : mecs [ i ] . leafComponentType ( ) ; if ( mec . isInterface ( ) ) { otherBounds [ rank ++ ] = mec ; } } TypeBinding intersectionType = environment ( ) . createWildcard ( null , 0 , firstBound , otherBounds , Wildcard . EXTENDS ) ; return commonDim == 0 ? intersectionType : environment ( ) . createArrayType ( intersectionType , commonDim ) ; } public final MethodScope methodScope ( ) { Scope scope = this ; do { if ( scope instanceof MethodScope ) return ( MethodScope ) scope ; scope = scope . parent ; } while ( scope != null ) ; return null ; } protected TypeBinding [ ] minimalErasedCandidates ( TypeBinding [ ] types , Map allInvocations ) { int length = types . length ; int indexOfFirst = - 1 , actualLength = 0 ; for ( int i = 0 ; i < length ; i ++ ) { TypeBinding type = types [ i ] ; if ( type == null ) continue ; if ( type . isBaseType ( ) ) return null ; if ( indexOfFirst < 0 ) indexOfFirst = i ; actualLength ++ ; } switch ( actualLength ) { case 0 : return Binding . NO_TYPES ; case 1 : return types ; } TypeBinding firstType = types [ indexOfFirst ] ; if ( firstType . isBaseType ( ) ) return null ; ArrayList typesToVisit = new ArrayList ( 5 ) ; int dim = firstType . dimensions ( ) ; TypeBinding leafType = firstType . leafComponentType ( ) ; TypeBinding firstErasure ; switch ( leafType . kind ( ) ) { case Binding . PARAMETERIZED_TYPE : case Binding . RAW_TYPE : case Binding . ARRAY_TYPE : firstErasure = firstType . erasure ( ) ; break ; default : firstErasure = firstType ; break ; } if ( firstErasure != firstType ) { allInvocations . put ( firstErasure , firstType ) ; } typesToVisit . add ( firstType ) ; int max = 1 ; ReferenceBinding currentType ; for ( int i = 0 ; i < max ; i ++ ) { TypeBinding typeToVisit = ( TypeBinding ) typesToVisit . get ( i ) ; dim = typeToVisit . dimensions ( ) ; if ( dim > 0 ) { leafType = typeToVisit . leafComponentType ( ) ; switch ( leafType . id ) { case TypeIds . T_JavaLangObject : if ( dim > 1 ) { TypeBinding elementType = ( ( ArrayBinding ) typeToVisit ) . elementsType ( ) ; if ( ! typesToVisit . contains ( elementType ) ) { typesToVisit . add ( elementType ) ; max ++ ; } continue ; } case TypeIds . T_byte : case TypeIds . T_short : case TypeIds . T_char : case TypeIds . T_boolean : case TypeIds . T_int : case TypeIds . T_long : case TypeIds . T_float : case TypeIds . T_double : TypeBinding superType = getJavaIoSerializable ( ) ; if ( ! typesToVisit . contains ( superType ) ) { typesToVisit . add ( superType ) ; max ++ ; } superType = getJavaLangCloneable ( ) ; if ( ! typesToVisit . contains ( superType ) ) { typesToVisit . add ( superType ) ; max ++ ; } superType = getJavaLangObject ( ) ; if ( ! typesToVisit . contains ( superType ) ) { typesToVisit . add ( superType ) ; max ++ ; } continue ; default : } typeToVisit = leafType ; } currentType = ( ReferenceBinding ) typeToVisit ; if ( currentType . isCapture ( ) ) { TypeBinding firstBound = ( ( CaptureBinding ) currentType ) . firstBound ; if ( firstBound != null && firstBound . isArrayType ( ) ) { TypeBinding superType = dim == 0 ? firstBound : ( TypeBinding ) environment ( ) . createArrayType ( firstBound , dim ) ; if ( ! typesToVisit . contains ( superType ) ) { typesToVisit . add ( superType ) ; max ++ ; TypeBinding superTypeErasure = ( firstBound . isTypeVariable ( ) || firstBound . isWildcard ( ) ) ? superType : superType . erasure ( ) ; if ( superTypeErasure != superType ) { allInvocations . put ( superTypeErasure , superType ) ; } } continue ; } } ReferenceBinding [ ] itsInterfaces = currentType . superInterfaces ( ) ; if ( itsInterfaces != null ) { for ( int j = 0 , count = itsInterfaces . length ; j < count ; j ++ ) { TypeBinding itsInterface = itsInterfaces [ j ] ; TypeBinding superType = dim == 0 ? itsInterface : ( TypeBinding ) environment ( ) . createArrayType ( itsInterface , dim ) ; if ( ! typesToVisit . contains ( superType ) ) { typesToVisit . add ( superType ) ; max ++ ; TypeBinding superTypeErasure = ( itsInterface . isTypeVariable ( ) || itsInterface . isWildcard ( ) ) ? superType : superType . erasure ( ) ; if ( superTypeErasure != superType ) { allInvocations . put ( superTypeErasure , superType ) ; } } } } TypeBinding itsSuperclass = currentType . superclass ( ) ; if ( itsSuperclass != null ) { TypeBinding superType = dim == 0 ? itsSuperclass : ( TypeBinding ) environment ( ) . createArrayType ( itsSuperclass , dim ) ; if ( ! typesToVisit . contains ( superType ) ) { typesToVisit . add ( superType ) ; max ++ ; TypeBinding superTypeErasure = ( itsSuperclass . isTypeVariable ( ) || itsSuperclass . isWildcard ( ) ) ? superType : superType . erasure ( ) ; if ( superTypeErasure != superType ) { allInvocations . put ( superTypeErasure , superType ) ; } } } } int superLength = typesToVisit . size ( ) ; TypeBinding [ ] erasedSuperTypes = new TypeBinding [ superLength ] ; int rank = 0 ; for ( Iterator iter = typesToVisit . iterator ( ) ; iter . hasNext ( ) ; ) { TypeBinding type = ( TypeBinding ) iter . next ( ) ; leafType = type . leafComponentType ( ) ; erasedSuperTypes [ rank ++ ] = ( leafType . isTypeVariable ( ) || leafType . isWildcard ( ) ) ? type : type . erasure ( ) ; } int remaining = superLength ; nextOtherType : for ( int i = indexOfFirst + 1 ; i < length ; i ++ ) { TypeBinding otherType = types [ i ] ; if ( otherType == null ) continue nextOtherType ; if ( otherType . isArrayType ( ) ) { nextSuperType : for ( int j = 0 ; j < superLength ; j ++ ) { TypeBinding erasedSuperType = erasedSuperTypes [ j ] ; if ( erasedSuperType == null || erasedSuperType == otherType ) continue nextSuperType ; TypeBinding match ; if ( ( match = otherType . findSuperTypeOriginatingFrom ( erasedSuperType ) ) == null ) { erasedSuperTypes [ j ] = null ; if ( -- remaining == 0 ) return null ; continue nextSuperType ; } Object invocationData = allInvocations . get ( erasedSuperType ) ; if ( invocationData == null ) { allInvocations . put ( erasedSuperType , match ) ; } else if ( invocationData instanceof TypeBinding ) { if ( match != invocationData ) { TypeBinding [ ] someInvocations = { ( TypeBinding ) invocationData , match , } ; allInvocations . put ( erasedSuperType , someInvocations ) ; } } else { TypeBinding [ ] someInvocations = ( TypeBinding [ ] ) invocationData ; checkExisting : { int invocLength = someInvocations . length ; for ( int k = 0 ; k < invocLength ; k ++ ) { if ( someInvocations [ k ] == match ) break checkExisting ; } System . arraycopy ( someInvocations , 0 , someInvocations = new TypeBinding [ invocLength + 1 ] , 0 , invocLength ) ; allInvocations . put ( erasedSuperType , someInvocations ) ; someInvocations [ invocLength ] = match ; } } } continue nextOtherType ; } nextSuperType : for ( int j = 0 ; j < superLength ; j ++ ) { TypeBinding erasedSuperType = erasedSuperTypes [ j ] ; if ( erasedSuperType == null ) continue nextSuperType ; TypeBinding match ; if ( erasedSuperType == otherType || erasedSuperType . id == TypeIds . T_JavaLangObject && otherType . isInterface ( ) ) { match = erasedSuperType ; } else { if ( erasedSuperType . isArrayType ( ) ) { match = null ; } else { match = otherType . findSuperTypeOriginatingFrom ( erasedSuperType ) ; } if ( match == null ) { erasedSuperTypes [ j ] = null ; if ( -- remaining == 0 ) return null ; continue nextSuperType ; } } Object invocationData = allInvocations . get ( erasedSuperType ) ; if ( invocationData == null ) { allInvocations . put ( erasedSuperType , match ) ; } else if ( invocationData instanceof TypeBinding ) { if ( match != invocationData ) { TypeBinding [ ] someInvocations = { ( TypeBinding ) invocationData , match , } ; allInvocations . put ( erasedSuperType , someInvocations ) ; } } else { TypeBinding [ ] someInvocations = ( TypeBinding [ ] ) invocationData ; checkExisting : { int invocLength = someInvocations . length ; for ( int k = 0 ; k < invocLength ; k ++ ) { if ( someInvocations [ k ] == match ) break checkExisting ; } System . arraycopy ( someInvocations , 0 , someInvocations = new TypeBinding [ invocLength + 1 ] , 0 , invocLength ) ; allInvocations . put ( erasedSuperType , someInvocations ) ; someInvocations [ invocLength ] = match ; } } } } if ( remaining > 1 ) { nextType : for ( int i = 0 ; i < superLength ; i ++ ) { TypeBinding erasedSuperType = erasedSuperTypes [ i ] ; if ( erasedSuperType == null ) continue nextType ; nextOtherType : for ( int j = 0 ; j < superLength ; j ++ ) { if ( i == j ) continue nextOtherType ; TypeBinding otherType = erasedSuperTypes [ j ] ; if ( otherType == null ) continue nextOtherType ; if ( erasedSuperType instanceof ReferenceBinding ) { if ( otherType . id == TypeIds . T_JavaLangObject && erasedSuperType . isInterface ( ) ) continue nextOtherType ; if ( erasedSuperType . findSuperTypeOriginatingFrom ( otherType ) != null ) { erasedSuperTypes [ j ] = null ; remaining -- ; } } else if ( erasedSuperType . isArrayType ( ) ) { if ( otherType . isArrayType ( ) && otherType . leafComponentType ( ) . id == TypeIds . T_JavaLangObject && otherType . dimensions ( ) == erasedSuperType . dimensions ( ) && erasedSuperType . leafComponentType ( ) . isInterface ( ) ) continue nextOtherType ; if ( erasedSuperType . findSuperTypeOriginatingFrom ( otherType ) != null ) { erasedSuperTypes [ j ] = null ; remaining -- ; } } } } } return erasedSuperTypes ; } protected final MethodBinding mostSpecificClassMethodBinding ( MethodBinding [ ] visible , int visibleSize , InvocationSite invocationSite ) { MethodBinding previous = null ; nextVisible : for ( int i = 0 ; i < visibleSize ; i ++ ) { MethodBinding method = visible [ i ] ; if ( previous != null && method . declaringClass != previous . declaringClass ) break ; if ( ! method . isStatic ( ) ) previous = method ; for ( int j = 0 ; j < visibleSize ; j ++ ) { if ( i == j ) continue ; if ( ! visible [ j ] . areParametersCompatibleWith ( method . parameters ) ) continue nextVisible ; } compilationUnitScope ( ) . recordTypeReferences ( method . thrownExceptions ) ; return method ; } return new ProblemMethodBinding ( visible [ 0 ] , visible [ 0 ] . selector , visible [ 0 ] . parameters , ProblemReasons . Ambiguous ) ; } protected final MethodBinding mostSpecificInterfaceMethodBinding ( MethodBinding [ ] visible , int visibleSize , InvocationSite invocationSite ) { nextVisible : for ( int i = 0 ; i < visibleSize ; i ++ ) { MethodBinding method = visible [ i ] ; for ( int j = 0 ; j < visibleSize ; j ++ ) { if ( i == j ) continue ; if ( ! visible [ j ] . areParametersCompatibleWith ( method . parameters ) ) continue nextVisible ; } compilationUnitScope ( ) . recordTypeReferences ( method . thrownExceptions ) ; return method ; } return new ProblemMethodBinding ( visible [ 0 ] , visible [ 0 ] . selector , visible [ 0 ] . parameters , ProblemReasons . Ambiguous ) ; } protected final MethodBinding mostSpecificMethodBinding ( MethodBinding [ ] visible , int visibleSize , TypeBinding [ ] argumentTypes , final InvocationSite invocationSite , ReferenceBinding receiverType ) { int [ ] compatibilityLevels = new int [ visibleSize ] ; for ( int i = 0 ; i < visibleSize ; i ++ ) compatibilityLevels [ i ] = parameterCompatibilityLevel ( visible [ i ] , argumentTypes ) ; InvocationSite tieBreakInvocationSite = new InvocationSite ( ) { public TypeBinding [ ] genericTypeArguments ( ) { return null ; } public boolean isSuperAccess ( ) { return invocationSite . isSuperAccess ( ) ; } public boolean isTypeAccess ( ) { return invocationSite . isTypeAccess ( ) ; } public void setActualReceiverType ( ReferenceBinding actualReceiverType ) { } public void setDepth ( int depth ) { } public void setFieldIndex ( int depth ) { } public int sourceStart ( ) { return invocationSite . sourceStart ( ) ; } public int sourceEnd ( ) { return invocationSite . sourceStart ( ) ; } public TypeBinding expectedType ( ) { return invocationSite . expectedType ( ) ; } } ; MethodBinding [ ] moreSpecific = new MethodBinding [ visibleSize ] ; int count = 0 ; for ( int level = 0 , max = VARARGS_COMPATIBLE ; level <= max ; level ++ ) { nextVisible : for ( int i = 0 ; i < visibleSize ; i ++ ) { if ( compatibilityLevels [ i ] != level ) continue nextVisible ; max = level ; MethodBinding current = visible [ i ] ; MethodBinding original = current . original ( ) ; MethodBinding tiebreakMethod = current . tiebreakMethod ( ) ; for ( int j = 0 ; j < visibleSize ; j ++ ) { if ( i == j || compatibilityLevels [ j ] != level ) continue ; MethodBinding next = visible [ j ] ; if ( original == next . original ( ) ) { compatibilityLevels [ j ] = - 1 ; continue ; } MethodBinding methodToTest = next ; if ( next instanceof ParameterizedGenericMethodBinding ) { ParameterizedGenericMethodBinding pNext = ( ParameterizedGenericMethodBinding ) next ; if ( pNext . isRaw && ! pNext . isStatic ( ) ) { } else { methodToTest = pNext . originalMethod ; } } MethodBinding acceptable = computeCompatibleMethod ( methodToTest , tiebreakMethod . parameters , tieBreakInvocationSite ) ; if ( acceptable == null || ! acceptable . isValidBinding ( ) ) continue nextVisible ; if ( ! isAcceptableMethod ( tiebreakMethod , acceptable ) ) continue nextVisible ; if ( current . isBridge ( ) && ! next . isBridge ( ) ) if ( tiebreakMethod . areParametersEqual ( acceptable ) ) continue nextVisible ; } moreSpecific [ i ] = current ; count ++ ; } } if ( count == 1 ) { for ( int i = 0 ; i < visibleSize ; i ++ ) { if ( moreSpecific [ i ] != null ) { compilationUnitScope ( ) . recordTypeReferences ( visible [ i ] . thrownExceptions ) ; return visible [ i ] ; } } } else if ( count == 0 ) { return new ProblemMethodBinding ( visible [ 0 ] , visible [ 0 ] . selector , visible [ 0 ] . parameters , ProblemReasons . Ambiguous ) ; } if ( receiverType != null ) receiverType = receiverType instanceof CaptureBinding ? receiverType : ( ReferenceBinding ) receiverType . erasure ( ) ; nextSpecific : for ( int i = 0 ; i < visibleSize ; i ++ ) { MethodBinding current = moreSpecific [ i ] ; if ( current != null ) { ReferenceBinding [ ] mostSpecificExceptions = null ; MethodBinding original = current . original ( ) ; boolean shouldIntersectExceptions = original . declaringClass . isAbstract ( ) && original . thrownExceptions != Binding . NO_EXCEPTIONS ; for ( int j = 0 ; j < visibleSize ; j ++ ) { MethodBinding next = moreSpecific [ j ] ; if ( next == null || i == j ) continue ; MethodBinding original2 = next . original ( ) ; if ( original . declaringClass == original2 . declaringClass ) break nextSpecific ; if ( ! original . isAbstract ( ) ) { if ( original2 . isAbstract ( ) ) continue ; original2 = original . findOriginalInheritedMethod ( original2 ) ; if ( original2 == null ) continue nextSpecific ; if ( current . hasSubstitutedParameters ( ) || original . typeVariables != Binding . NO_TYPE_VARIABLES ) { if ( ! environment ( ) . methodVerifier ( ) . isParameterSubsignature ( original , original2 ) ) continue nextSpecific ; } } else if ( receiverType != null ) { TypeBinding superType = receiverType . findSuperTypeOriginatingFrom ( original . declaringClass . erasure ( ) ) ; if ( original . declaringClass == superType || ! ( superType instanceof ReferenceBinding ) ) { } else { MethodBinding [ ] superMethods = ( ( ReferenceBinding ) superType ) . getMethods ( original . selector , argumentTypes . length ) ; for ( int m = 0 , l = superMethods . length ; m < l ; m ++ ) { if ( superMethods [ m ] . original ( ) == original ) { original = superMethods [ m ] ; break ; } } } superType = receiverType . findSuperTypeOriginatingFrom ( original2 . declaringClass . erasure ( ) ) ; if ( original2 . declaringClass == superType || ! ( superType instanceof ReferenceBinding ) ) { } else { MethodBinding [ ] superMethods = ( ( ReferenceBinding ) superType ) . getMethods ( original2 . selector , argumentTypes . length ) ; for ( int m = 0 , l = superMethods . length ; m < l ; m ++ ) { if ( superMethods [ m ] . original ( ) == original2 ) { original2 = superMethods [ m ] ; break ; } } } if ( original . typeVariables != Binding . NO_TYPE_VARIABLES ) original2 = original . computeSubstitutedMethod ( original2 , environment ( ) ) ; if ( original2 == null || ! original . areParameterErasuresEqual ( original2 ) ) continue nextSpecific ; if ( original . returnType != original2 . returnType ) { if ( next . original ( ) . typeVariables != Binding . NO_TYPE_VARIABLES ) { if ( original . returnType . erasure ( ) . findSuperTypeOriginatingFrom ( original2 . returnType . erasure ( ) ) == null ) continue nextSpecific ; } else if ( ! current . returnType . isCompatibleWith ( next . returnType ) ) { continue nextSpecific ; } } if ( shouldIntersectExceptions && original2 . declaringClass . isInterface ( ) ) { if ( current . thrownExceptions != next . thrownExceptions ) { if ( next . thrownExceptions == Binding . NO_EXCEPTIONS ) { mostSpecificExceptions = Binding . NO_EXCEPTIONS ; } else { if ( mostSpecificExceptions == null ) { mostSpecificExceptions = current . thrownExceptions ; } int mostSpecificLength = mostSpecificExceptions . length ; int nextLength = next . thrownExceptions . length ; SimpleSet temp = new SimpleSet ( mostSpecificLength ) ; boolean changed = false ; nextException : for ( int t = 0 ; t < mostSpecificLength ; t ++ ) { ReferenceBinding exception = mostSpecificExceptions [ t ] ; for ( int s = 0 ; s < nextLength ; s ++ ) { ReferenceBinding nextException = next . thrownExceptions [ s ] ; if ( exception . isCompatibleWith ( nextException ) ) { temp . add ( exception ) ; continue nextException ; } else if ( nextException . isCompatibleWith ( exception ) ) { temp . add ( nextException ) ; changed = true ; continue nextException ; } else { changed = true ; } } } if ( changed ) { mostSpecificExceptions = temp . elementSize == 0 ? Binding . NO_EXCEPTIONS : new ReferenceBinding [ temp . elementSize ] ; temp . asArray ( mostSpecificExceptions ) ; } } } } } } if ( mostSpecificExceptions != null && mostSpecificExceptions != current . thrownExceptions ) { return new MostSpecificExceptionMethodBinding ( current , mostSpecificExceptions ) ; } return current ; } } return new ProblemMethodBinding ( visible [ 0 ] , visible [ 0 ] . selector , visible [ 0 ] . parameters , ProblemReasons . Ambiguous ) ; } public final ClassScope outerMostClassScope ( ) { ClassScope lastClassScope = null ; Scope scope = this ; do { if ( scope instanceof ClassScope ) lastClassScope = ( ClassScope ) scope ; scope = scope . parent ; } while ( scope != null ) ; return lastClassScope ; } public final MethodScope outerMostMethodScope ( ) { MethodScope lastMethodScope = null ; Scope scope = this ; do { if ( scope instanceof MethodScope ) lastMethodScope = ( MethodScope ) scope ; scope = scope . parent ; } while ( scope != null ) ; return lastMethodScope ; } public int parameterCompatibilityLevel ( MethodBinding method , TypeBinding [ ] arguments ) { TypeBinding [ ] parameters = method . parameters ; int paramLength = parameters . length ; int argLength = arguments . length ; if ( compilerOptions ( ) . sourceLevel < ClassFileConstants . JDK1_5 ) { if ( paramLength != argLength ) return NOT_COMPATIBLE ; for ( int i = 0 ; i < argLength ; i ++ ) { TypeBinding param = parameters [ i ] ; TypeBinding arg = arguments [ i ] ; if ( arg != param && ! arg . isCompatibleWith ( param . erasure ( ) ) ) return NOT_COMPATIBLE ; } return COMPATIBLE ; } int level = COMPATIBLE ; int lastIndex = argLength ; LookupEnvironment env = environment ( ) ; if ( method . isVarargs ( ) ) { lastIndex = paramLength - 1 ; if ( paramLength == argLength ) { TypeBinding param = parameters [ lastIndex ] ; TypeBinding arg = arguments [ lastIndex ] ; if ( param != arg ) { level = parameterCompatibilityLevel ( arg , param , env ) ; if ( level == NOT_COMPATIBLE ) { param = ( ( ArrayBinding ) param ) . elementsType ( ) ; if ( parameterCompatibilityLevel ( arg , param , env ) == NOT_COMPATIBLE ) return NOT_COMPATIBLE ; level = VARARGS_COMPATIBLE ; } } } else { if ( paramLength < argLength ) { TypeBinding param = ( ( ArrayBinding ) parameters [ lastIndex ] ) . elementsType ( ) ; for ( int i = lastIndex ; i < argLength ; i ++ ) { TypeBinding arg = arguments [ i ] ; if ( param != arg && parameterCompatibilityLevel ( arg , param , env ) == NOT_COMPATIBLE ) return NOT_COMPATIBLE ; } } else if ( lastIndex != argLength ) { return NOT_COMPATIBLE ; } level = VARARGS_COMPATIBLE ; } } else if ( paramLength != argLength ) { return NOT_COMPATIBLE ; } for ( int i = 0 ; i < lastIndex ; i ++ ) { TypeBinding param = parameters [ i ] ; TypeBinding arg = arguments [ i ] ; if ( arg != param ) { int newLevel = parameterCompatibilityLevel ( arg , param , env ) ; if ( newLevel == NOT_COMPATIBLE ) return NOT_COMPATIBLE ; if ( newLevel > level ) level = newLevel ; } } return level ; } private int parameterCompatibilityLevel ( TypeBinding arg , TypeBinding param , LookupEnvironment env ) { if ( arg . isCompatibleWith ( param ) ) return COMPATIBLE ; if ( arg . isBaseType ( ) != param . isBaseType ( ) ) { TypeBinding convertedType = env . computeBoxingType ( arg ) ; if ( convertedType == param || convertedType . isCompatibleWith ( param ) ) return AUTOBOX_COMPATIBLE ; } return NOT_COMPATIBLE ; } public abstract ProblemReporter problemReporter ( ) ; public final CompilationUnitDeclaration referenceCompilationUnit ( ) { Scope scope , unitScope = this ; while ( ( scope = unitScope . parent ) != null ) unitScope = scope ; return ( ( CompilationUnitScope ) unitScope ) . referenceContext ; } public ReferenceContext referenceContext ( ) { Scope current = this ; do { switch ( current . kind ) { case METHOD_SCOPE : return ( ( MethodScope ) current ) . referenceContext ; case CLASS_SCOPE : return ( ( ClassScope ) current ) . referenceContext ; case COMPILATION_UNIT_SCOPE : return ( ( CompilationUnitScope ) current ) . referenceContext ; } } while ( ( current = current . parent ) != null ) ; return null ; } public void deferBoundCheck ( TypeReference typeRef ) { if ( this . kind == CLASS_SCOPE ) { ClassScope classScope = ( ClassScope ) this ; if ( classScope . deferredBoundChecks == null ) { classScope . deferredBoundChecks = new ArrayList ( 3 ) ; classScope . deferredBoundChecks . add ( typeRef ) ; } else if ( ! classScope . deferredBoundChecks . contains ( typeRef ) ) { classScope . deferredBoundChecks . add ( typeRef ) ; } } } int startIndex ( ) { return 0 ; } public MethodBinding getStaticFactory ( ReferenceBinding allocationType , ReferenceBinding originalEnclosingType , TypeBinding [ ] argumentTypes , final InvocationSite allocationSite ) { TypeVariableBinding [ ] classTypeVariables = allocationType . typeVariables ( ) ; int classTypeVariablesArity = classTypeVariables . length ; MethodBinding [ ] methods = allocationType . getMethods ( TypeConstants . INIT , argumentTypes . length ) ; MethodBinding [ ] staticFactories = new MethodBinding [ methods . length ] ; int sfi = 0 ; for ( int i = 0 , length = methods . length ; i < length ; i ++ ) { MethodBinding method = methods [ i ] ; int paramLength = method . parameters . length ; boolean isVarArgs = method . isVarargs ( ) ; if ( argumentTypes . length != paramLength ) if ( ! isVarArgs || argumentTypes . length < paramLength - 1 ) continue ; TypeVariableBinding [ ] methodTypeVariables = method . typeVariables ( ) ; int methodTypeVariablesArity = methodTypeVariables . length ; MethodBinding staticFactory = new MethodBinding ( method . modifiers | ClassFileConstants . AccStatic , TypeConstants . SYNTHETIC_STATIC_FACTORY , null , null , null , method . declaringClass ) ; staticFactory . typeVariables = new TypeVariableBinding [ classTypeVariablesArity + methodTypeVariablesArity ] ; final SimpleLookupTable map = new SimpleLookupTable ( classTypeVariablesArity + methodTypeVariablesArity ) ; final LookupEnvironment environment = environment ( ) ; for ( int j = 0 ; j < classTypeVariablesArity ; j ++ ) { map . put ( classTypeVariables [ j ] , staticFactory . typeVariables [ j ] = new TypeVariableBinding ( CharOperation . concat ( classTypeVariables [ j ] . sourceName , "'" . toCharArray ( ) ) , staticFactory , j , environment ) ) ; } for ( int j = classTypeVariablesArity , max = classTypeVariablesArity + methodTypeVariablesArity ; j < max ; j ++ ) { map . put ( methodTypeVariables [ j - classTypeVariablesArity ] , ( staticFactory . typeVariables [ j ] = new TypeVariableBinding ( CharOperation . concat ( methodTypeVariables [ j - classTypeVariablesArity ] . sourceName , "''" . toCharArray ( ) ) , staticFactory , j , environment ) ) ) ; } ReferenceBinding enclosingType = originalEnclosingType ; while ( enclosingType != null ) { if ( enclosingType . kind ( ) == Binding . PARAMETERIZED_TYPE ) { final ParameterizedTypeBinding parameterizedType = ( ParameterizedTypeBinding ) enclosingType ; final ReferenceBinding genericType = parameterizedType . genericType ( ) ; TypeVariableBinding [ ] enclosingClassTypeVariables = genericType . typeVariables ( ) ; int enclosingClassTypeVariablesArity = enclosingClassTypeVariables . length ; for ( int j = 0 ; j < enclosingClassTypeVariablesArity ; j ++ ) { map . put ( enclosingClassTypeVariables [ j ] , parameterizedType . arguments [ j ] ) ; } } enclosingType = enclosingType . enclosingType ( ) ; } final Scope scope = this ; Substitution substitution = new Substitution ( ) { public LookupEnvironment environment ( ) { return scope . environment ( ) ; } public boolean isRawSubstitution ( ) { return false ; } public TypeBinding substitute ( TypeVariableBinding typeVariable ) { TypeBinding retVal = ( TypeBinding ) map . get ( typeVariable ) ; return retVal != null ? retVal : typeVariable ; } } ; for ( int j = 0 , max = classTypeVariablesArity + methodTypeVariablesArity ; j < max ; j ++ ) { TypeVariableBinding originalVariable = j < classTypeVariablesArity ? classTypeVariables [ j ] : methodTypeVariables [ j - classTypeVariablesArity ] ; TypeBinding substitutedType = ( TypeBinding ) map . get ( originalVariable ) ; if ( substitutedType instanceof TypeVariableBinding ) { TypeVariableBinding substitutedVariable = ( TypeVariableBinding ) substitutedType ; TypeBinding substitutedSuperclass = Scope . substitute ( substitution , originalVariable . superclass ) ; ReferenceBinding [ ] substitutedInterfaces = Scope . substitute ( substitution , originalVariable . superInterfaces ) ; if ( originalVariable . firstBound != null ) { substitutedVariable . firstBound = originalVariable . firstBound == originalVariable . superclass ? substitutedSuperclass : substitutedInterfaces [ 0 ] ; } switch ( substitutedSuperclass . kind ( ) ) { case Binding . ARRAY_TYPE : substitutedVariable . superclass = environment . getResolvedType ( TypeConstants . JAVA_LANG_OBJECT , null ) ; substitutedVariable . superInterfaces = substitutedInterfaces ; break ; default : if ( substitutedSuperclass . isInterface ( ) ) { substitutedVariable . superclass = environment . getResolvedType ( TypeConstants . JAVA_LANG_OBJECT , null ) ; int interfaceCount = substitutedInterfaces . length ; System . arraycopy ( substitutedInterfaces , 0 , substitutedInterfaces = new ReferenceBinding [ interfaceCount + 1 ] , 1 , interfaceCount ) ; substitutedInterfaces [ 0 ] = ( ReferenceBinding ) substitutedSuperclass ; substitutedVariable . superInterfaces = substitutedInterfaces ; } else { substitutedVariable . superclass = ( ReferenceBinding ) substitutedSuperclass ; substitutedVariable . superInterfaces = substitutedInterfaces ; } } } } TypeVariableBinding [ ] returnTypeParameters = new TypeVariableBinding [ classTypeVariablesArity ] ; for ( int j = 0 ; j < classTypeVariablesArity ; j ++ ) { returnTypeParameters [ j ] = ( TypeVariableBinding ) map . get ( classTypeVariables [ j ] ) ; } staticFactory . returnType = environment . createParameterizedType ( allocationType , returnTypeParameters , allocationType . enclosingType ( ) ) ; staticFactory . parameters = Scope . substitute ( substitution , method . parameters ) ; staticFactory . thrownExceptions = Scope . substitute ( substitution , method . thrownExceptions ) ; if ( staticFactory . thrownExceptions == null ) { staticFactory . thrownExceptions = Binding . NO_EXCEPTIONS ; } staticFactories [ sfi ++ ] = new ParameterizedMethodBinding ( ( ParameterizedTypeBinding ) environment . convertToParameterizedType ( staticFactory . declaringClass ) , staticFactory ) ; } if ( sfi == 0 ) return null ; if ( sfi != methods . length ) { System . arraycopy ( staticFactories , 0 , staticFactories = new MethodBinding [ sfi ] , 0 , sfi ) ; } MethodBinding [ ] compatible = new MethodBinding [ sfi ] ; int compatibleIndex = 0 ; for ( int i = 0 ; i < sfi ; i ++ ) { MethodBinding compatibleMethod = computeCompatibleMethod ( staticFactories [ i ] , argumentTypes , allocationSite ) ; if ( compatibleMethod != null ) { if ( compatibleMethod . isValidBinding ( ) ) compatible [ compatibleIndex ++ ] = compatibleMethod ; } } if ( compatibleIndex == 0 ) { return null ; } MethodBinding [ ] visible = new MethodBinding [ compatibleIndex ] ; int visibleIndex = 0 ; for ( int i = 0 ; i < compatibleIndex ; i ++ ) { MethodBinding method = compatible [ i ] ; if ( method . canBeSeenBy ( allocationSite , this ) ) visible [ visibleIndex ++ ] = method ; } if ( visibleIndex == 0 ) { return null ; } return visibleIndex == 1 ? visible [ 0 ] : mostSpecificMethodBinding ( visible , visibleIndex , argumentTypes , allocationSite , allocationType ) ; } } </s>