<s> package org . eclipse . jdt . internal . compiler . lookup ; import java . util . List ; import org . eclipse . jdt . core . compiler . CharOperation ; import org . eclipse . jdt . internal . compiler . ast . Wildcard ; import org . eclipse . jdt . internal . compiler . classfmt . ClassFileConstants ; public class WildcardBinding extends ReferenceBinding { public ReferenceBinding genericType ; public int rank ; public TypeBinding bound ; public TypeBinding [ ] otherBounds ; char [ ] genericSignature ; public int boundKind ; ReferenceBinding superclass ; ReferenceBinding [ ] superInterfaces ; TypeVariableBinding typeVariable ; LookupEnvironment environment ; public WildcardBinding ( ReferenceBinding genericType , int rank , TypeBinding bound , TypeBinding [ ] otherBounds , int boundKind , LookupEnvironment environment ) { this . rank = rank ; this . boundKind = boundKind ; this . modifiers = ClassFileConstants . AccPublic | ExtraCompilerModifiers . AccGenericSignature ; this . environment = environment ; initialize ( genericType , bound , otherBounds ) ; if ( genericType instanceof UnresolvedReferenceBinding ) ( ( UnresolvedReferenceBinding ) genericType ) . addWrapper ( this , environment ) ; if ( bound instanceof UnresolvedReferenceBinding ) ( ( UnresolvedReferenceBinding ) bound ) . addWrapper ( this , environment ) ; this . tagBits |= TagBits . HasUnresolvedTypeVariables ; this . typeBits = TypeIds . BitUninitialized ; } public int kind ( ) { return this . otherBounds == null ? Binding . WILDCARD_TYPE : Binding . INTERSECTION_TYPE ; } public boolean boundCheck ( TypeBinding argumentType ) { switch ( this . boundKind ) { case Wildcard . UNBOUND : return true ; case Wildcard . EXTENDS : if ( ! argumentType . isCompatibleWith ( this . bound ) ) return false ; for ( int i = 0 , length = this . otherBounds == null ? 0 : this . otherBounds . length ; i < length ; i ++ ) { if ( ! argumentType . isCompatibleWith ( this . otherBounds [ i ] ) ) return false ; } return true ; default : return argumentType . isCompatibleWith ( this . bound ) ; } } public boolean canBeInstantiated ( ) { return false ; } public List collectMissingTypes ( List missingTypes ) { if ( ( this . tagBits & TagBits . HasMissingType ) != 0 ) { missingTypes = this . bound . collectMissingTypes ( missingTypes ) ; } return missingTypes ; } public void collectSubstitutes ( Scope scope , TypeBinding actualType , InferenceContext inferenceContext , int constraint ) { if ( ( this . tagBits & TagBits . HasTypeVariable ) == 0 ) return ; if ( actualType == TypeBinding . NULL ) return ; if ( actualType . isCapture ( ) ) { CaptureBinding capture = ( CaptureBinding ) actualType ; actualType = capture . wildcard ; } switch ( constraint ) { case TypeConstants . CONSTRAINT_EXTENDS : switch ( this . boundKind ) { case Wildcard . UNBOUND : break ; case Wildcard . EXTENDS : switch ( actualType . kind ( ) ) { case Binding . WILDCARD_TYPE : WildcardBinding actualWildcard = ( WildcardBinding ) actualType ; switch ( actualWildcard . boundKind ) { case Wildcard . UNBOUND : break ; case Wildcard . EXTENDS : this . bound . collectSubstitutes ( scope , actualWildcard . bound , inferenceContext , TypeConstants . CONSTRAINT_EXTENDS ) ; break ; case Wildcard . SUPER : break ; } break ; case Binding . INTERSECTION_TYPE : WildcardBinding actualIntersection = ( WildcardBinding ) actualType ; this . bound . collectSubstitutes ( scope , actualIntersection . bound , inferenceContext , TypeConstants . CONSTRAINT_EXTENDS ) ; for ( int i = 0 , length = actualIntersection . otherBounds . length ; i < length ; i ++ ) { this . bound . collectSubstitutes ( scope , actualIntersection . otherBounds [ i ] , inferenceContext , TypeConstants . CONSTRAINT_EXTENDS ) ; } break ; default : this . bound . collectSubstitutes ( scope , actualType , inferenceContext , TypeConstants . CONSTRAINT_EXTENDS ) ; break ; } break ; case Wildcard . SUPER : switch ( actualType . kind ( ) ) { case Binding . WILDCARD_TYPE : WildcardBinding actualWildcard = ( WildcardBinding ) actualType ; switch ( actualWildcard . boundKind ) { case Wildcard . UNBOUND : break ; case Wildcard . EXTENDS : break ; case Wildcard . SUPER : this . bound . collectSubstitutes ( scope , actualWildcard . bound , inferenceContext , TypeConstants . CONSTRAINT_SUPER ) ; for ( int i = 0 , length = actualWildcard . otherBounds == null ? 0 : actualWildcard . otherBounds . length ; i < length ; i ++ ) { this . bound . collectSubstitutes ( scope , actualWildcard . otherBounds [ i ] , inferenceContext , TypeConstants . CONSTRAINT_SUPER ) ; } break ; } break ; case Binding . INTERSECTION_TYPE : break ; default : this . bound . collectSubstitutes ( scope , actualType , inferenceContext , TypeConstants . CONSTRAINT_SUPER ) ; break ; } break ; } break ; case TypeConstants . CONSTRAINT_EQUAL : switch ( this . boundKind ) { case Wildcard . UNBOUND : break ; case Wildcard . EXTENDS : switch ( actualType . kind ( ) ) { case Binding . WILDCARD_TYPE : WildcardBinding actualWildcard = ( WildcardBinding ) actualType ; switch ( actualWildcard . boundKind ) { case Wildcard . UNBOUND : break ; case Wildcard . EXTENDS : this . bound . collectSubstitutes ( scope , actualWildcard . bound , inferenceContext , TypeConstants . CONSTRAINT_EQUAL ) ; for ( int i = 0 , length = actualWildcard . otherBounds == null ? 0 : actualWildcard . otherBounds . length ; i < length ; i ++ ) { this . bound . collectSubstitutes ( scope , actualWildcard . otherBounds [ i ] , inferenceContext , TypeConstants . CONSTRAINT_EQUAL ) ; } break ; case Wildcard . SUPER : break ; } break ; case Binding . INTERSECTION_TYPE : WildcardBinding actuaIntersection = ( WildcardBinding ) actualType ; this . bound . collectSubstitutes ( scope , actuaIntersection . bound , inferenceContext , TypeConstants . CONSTRAINT_EQUAL ) ; for ( int i = 0 , length = actuaIntersection . otherBounds == null ? 0 : actuaIntersection . otherBounds . length ; i < length ; i ++ ) { this . bound . collectSubstitutes ( scope , actuaIntersection . otherBounds [ i ] , inferenceContext , TypeConstants . CONSTRAINT_EQUAL ) ; } break ; default : break ; } break ; case Wildcard . SUPER : switch ( actualType . kind ( ) ) { case Binding . WILDCARD_TYPE : WildcardBinding actualWildcard = ( WildcardBinding ) actualType ; switch ( actualWildcard . boundKind ) { case Wildcard . UNBOUND : break ; case Wildcard . EXTENDS : break ; case Wildcard . SUPER : this . bound . collectSubstitutes ( scope , actualWildcard . bound , inferenceContext , TypeConstants . CONSTRAINT_EQUAL ) ; for ( int i = 0 , length = actualWildcard . otherBounds == null ? 0 : actualWildcard . otherBounds . length ; i < length ; i ++ ) { this . bound . collectSubstitutes ( scope , actualWildcard . otherBounds [ i ] , inferenceContext , TypeConstants . CONSTRAINT_EQUAL ) ; } break ; } break ; case Binding . INTERSECTION_TYPE : break ; default : break ; } break ; } break ; case TypeConstants . CONSTRAINT_SUPER : switch ( this . boundKind ) { case Wildcard . UNBOUND : break ; case Wildcard . EXTENDS : switch ( actualType . kind ( ) ) { case Binding . WILDCARD_TYPE : WildcardBinding actualWildcard = ( WildcardBinding ) actualType ; switch ( actualWildcard . boundKind ) { case Wildcard . UNBOUND : break ; case Wildcard . EXTENDS : this . bound . collectSubstitutes ( scope , actualWildcard . bound , inferenceContext , TypeConstants . CONSTRAINT_SUPER ) ; for ( int i = 0 , length = actualWildcard . otherBounds == null ? 0 : actualWildcard . otherBounds . length ; i < length ; i ++ ) { this . bound . collectSubstitutes ( scope , actualWildcard . otherBounds [ i ] , inferenceContext , TypeConstants . CONSTRAINT_SUPER ) ; } break ; case Wildcard . SUPER : break ; } break ; case Binding . INTERSECTION_TYPE : WildcardBinding actualIntersection = ( WildcardBinding ) actualType ; this . bound . collectSubstitutes ( scope , actualIntersection . bound , inferenceContext , TypeConstants . CONSTRAINT_SUPER ) ; for ( int i = 0 , length = actualIntersection . otherBounds == null ? 0 : actualIntersection . otherBounds . length ; i < length ; i ++ ) { this . bound . collectSubstitutes ( scope , actualIntersection . otherBounds [ i ] , inferenceContext , TypeConstants . CONSTRAINT_SUPER ) ; } break ; default : break ; } break ; case Wildcard . SUPER : switch ( actualType . kind ( ) ) { case Binding . WILDCARD_TYPE : WildcardBinding actualWildcard = ( WildcardBinding ) actualType ; switch ( actualWildcard . boundKind ) { case Wildcard . UNBOUND : break ; case Wildcard . EXTENDS : break ; case Wildcard . SUPER : this . bound . collectSubstitutes ( scope , actualWildcard . bound , inferenceContext , TypeConstants . CONSTRAINT_SUPER ) ; for ( int i = 0 , length = actualWildcard . otherBounds == null ? 0 : actualWildcard . otherBounds . length ; i < length ; i ++ ) { this . bound . collectSubstitutes ( scope , actualWildcard . otherBounds [ i ] , inferenceContext , TypeConstants . CONSTRAINT_SUPER ) ; } break ; } break ; case Binding . INTERSECTION_TYPE : break ; default : break ; } break ; } break ; } } public char [ ] computeUniqueKey ( boolean isLeaf ) { char [ ] genericTypeKey = this . genericType . computeUniqueKey ( false ) ; char [ ] wildCardKey ; char [ ] rankComponent = ( '{' + String . valueOf ( this . rank ) + '}' ) . toCharArray ( ) ; switch ( this . boundKind ) { case Wildcard . UNBOUND : wildCardKey = TypeConstants . WILDCARD_STAR ; break ; case Wildcard . EXTENDS : wildCardKey = CharOperation . concat ( TypeConstants . WILDCARD_PLUS , this . bound . computeUniqueKey ( false ) ) ; break ; default : wildCardKey = CharOperation . concat ( TypeConstants . WILDCARD_MINUS , this . bound . computeUniqueKey ( false ) ) ; break ; } return CharOperation . concat ( genericTypeKey , rankComponent , wildCardKey ) ; } public char [ ] constantPoolName ( ) { return erasure ( ) . constantPoolName ( ) ; } public String debugName ( ) { return toString ( ) ; } public TypeBinding erasure ( ) { if ( this . otherBounds == null ) { if ( this . boundKind == Wildcard . EXTENDS ) return this . bound . erasure ( ) ; TypeVariableBinding var = typeVariable ( ) ; if ( var != null ) return var . erasure ( ) ; return this . genericType ; } return this . bound . id == TypeIds . T_JavaLangObject ? this . otherBounds [ 0 ] . erasure ( ) : this . bound . erasure ( ) ; } public char [ ] genericTypeSignature ( ) { if ( this . genericSignature == null ) { switch ( this . boundKind ) { case Wildcard . UNBOUND : this . genericSignature = TypeConstants . WILDCARD_STAR ; break ; case Wildcard . EXTENDS : this . genericSignature = CharOperation . concat ( TypeConstants . WILDCARD_PLUS , this . bound . genericTypeSignature ( ) ) ; break ; default : this . genericSignature = CharOperation . concat ( TypeConstants . WILDCARD_MINUS , this . bound . genericTypeSignature ( ) ) ; } } return this . genericSignature ; } public int hashCode ( ) { return this . genericType . hashCode ( ) ; } public boolean hasTypeBit ( int bit ) { if ( this . typeBits == TypeIds . BitUninitialized ) { this . typeBits = 0 ; if ( this . superclass != null && this . superclass . hasTypeBit ( ~ TypeIds . BitUninitialized ) ) this . typeBits |= ( this . superclass . typeBits & TypeIds . InheritableBits ) ; if ( this . superInterfaces != null ) for ( int i = 0 , l = this . superInterfaces . length ; i < l ; i ++ ) if ( this . superInterfaces [ i ] . hasTypeBit ( ~ TypeIds . BitUninitialized ) ) this . typeBits |= ( this . superInterfaces [ i ] . typeBits & TypeIds . InheritableBits ) ; } return ( this . typeBits & bit ) != 0 ; } void initialize ( ReferenceBinding someGenericType , TypeBinding someBound , TypeBinding [ ] someOtherBounds ) { this . genericType = someGenericType ; this . bound = someBound ; this . otherBounds = someOtherBounds ; if ( someGenericType != null ) { this . fPackage = someGenericType . getPackage ( ) ; } if ( someBound != null ) { this . tagBits |= someBound . tagBits & ( TagBits . HasTypeVariable | TagBits . HasMissingType | TagBits . ContainsNestedTypeReferences ) ; } if ( someOtherBounds != null ) { for ( int i = 0 , max = someOtherBounds . length ; i < max ; i ++ ) { TypeBinding someOtherBound = someOtherBounds [ i ] ; this . tagBits |= someOtherBound . tagBits & TagBits . ContainsNestedTypeReferences ; } } } public boolean isSuperclassOf ( ReferenceBinding otherType ) { if ( this . boundKind == Wildcard . SUPER ) { if ( this . bound instanceof ReferenceBinding ) { return ( ( ReferenceBinding ) this . bound ) . isSuperclassOf ( otherType ) ; } else { return otherType . id == TypeIds . T_JavaLangObject ; } } return false ; } public boolean isIntersectionType ( ) { return this . otherBounds != null ; } public boolean isHierarchyConnected ( ) { return this . superclass != null && this . superInterfaces != null ; } public boolean isUnboundWildcard ( ) { return this . boundKind == Wildcard . UNBOUND ; } public boolean isWildcard ( ) { return true ; } public char [ ] readableName ( ) { switch ( this . boundKind ) { case Wildcard . UNBOUND : return TypeConstants . WILDCARD_NAME ; case Wildcard . EXTENDS : if ( this . otherBounds == null ) return CharOperation . concat ( TypeConstants . WILDCARD_NAME , TypeConstants . WILDCARD_EXTENDS , this . bound . readableName ( ) ) ; StringBuffer buffer = new StringBuffer ( 10 ) ; buffer . append ( this . bound . readableName ( ) ) ; for ( int i = 0 , length = this . otherBounds . length ; i < length ; i ++ ) { buffer . append ( '&' ) . append ( this . otherBounds [ i ] . readableName ( ) ) ; } int length ; char [ ] result = new char [ length = buffer . length ( ) ] ; buffer . getChars ( 0 , length , result , 0 ) ; return result ; default : return CharOperation . concat ( TypeConstants . WILDCARD_NAME , TypeConstants . WILDCARD_SUPER , this . bound . readableName ( ) ) ; } } ReferenceBinding resolve ( ) { if ( ( this . tagBits & TagBits . HasUnresolvedTypeVariables ) == 0 ) return this ; this . tagBits &= ~ TagBits . HasUnresolvedTypeVariables ; BinaryTypeBinding . resolveType ( this . genericType , this . environment , false ) ; switch ( this . boundKind ) { case Wildcard . EXTENDS : TypeBinding resolveType = BinaryTypeBinding . resolveType ( this . bound , this . environment , true ) ; this . bound = resolveType ; this . tagBits |= resolveType . tagBits & TagBits . ContainsNestedTypeReferences ; for ( int i = 0 , length = this . otherBounds == null ? 0 : this . otherBounds . length ; i < length ; i ++ ) { resolveType = BinaryTypeBinding . resolveType ( this . otherBounds [ i ] , this . environment , true ) ; this . otherBounds [ i ] = resolveType ; this . tagBits |= resolveType . tagBits & TagBits . ContainsNestedTypeReferences ; } break ; case Wildcard . SUPER : resolveType = BinaryTypeBinding . resolveType ( this . bound , this . environment , true ) ; this . bound = resolveType ; this . tagBits |= resolveType . tagBits & TagBits . ContainsNestedTypeReferences ; break ; case Wildcard . UNBOUND : } return this ; } public char [ ] shortReadableName ( ) { switch ( this . boundKind ) { case Wildcard . UNBOUND : return TypeConstants . WILDCARD_NAME ; case Wildcard . EXTENDS : if ( this . otherBounds == null ) return CharOperation . concat ( TypeConstants . WILDCARD_NAME , TypeConstants . WILDCARD_EXTENDS , this . bound . shortReadableName ( ) ) ; StringBuffer buffer = new StringBuffer ( 10 ) ; buffer . append ( this . bound . shortReadableName ( ) ) ; for ( int i = 0 , length = this . otherBounds . length ; i < length ; i ++ ) { buffer . append ( '&' ) . append ( this . otherBounds [ i ] . shortReadableName ( ) ) ; } int length ; char [ ] result = new char [ length = buffer . length ( ) ] ; buffer . getChars ( 0 , length , result , 0 ) ; return result ; default : return CharOperation . concat ( TypeConstants . WILDCARD_NAME , TypeConstants . WILDCARD_SUPER , this . bound . shortReadableName ( ) ) ; } } public char [ ] signature ( ) { if ( this . signature == null ) { switch ( this . boundKind ) { case Wildcard . EXTENDS : return this . bound . signature ( ) ; default : return typeVariable ( ) . signature ( ) ; } } return this . signature ; } public char [ ] sourceName ( ) { switch ( this . boundKind ) { case Wildcard . UNBOUND : return TypeConstants . WILDCARD_NAME ; case Wildcard . EXTENDS : return CharOperation . concat ( TypeConstants . WILDCARD_NAME , TypeConstants . WILDCARD_EXTENDS , this . bound . sourceName ( ) ) ; default : return CharOperation . concat ( TypeConstants . WILDCARD_NAME , TypeConstants . WILDCARD_SUPER , this . bound . sourceName ( ) ) ; } } public ReferenceBinding superclass ( ) { if ( this . superclass == null ) { TypeBinding superType = null ; if ( this . boundKind == Wildcard . EXTENDS && ! this . bound . isInterface ( ) ) { superType = this . bound ; } else { TypeVariableBinding variable = typeVariable ( ) ; if ( variable != null ) superType = variable . firstBound ; } this . superclass = superType instanceof ReferenceBinding && ! superType . isInterface ( ) ? ( ReferenceBinding ) superType : this . environment . getResolvedType ( TypeConstants . JAVA_LANG_OBJECT , null ) ; } return this . superclass ; } public ReferenceBinding [ ] superInterfaces ( ) { if ( this . superInterfaces == null ) { if ( typeVariable ( ) != null ) { this . superInterfaces = this . typeVariable . superInterfaces ( ) ; } else { this . superInterfaces = Binding . NO_SUPERINTERFACES ; } if ( this . boundKind == Wildcard . EXTENDS ) { if ( this . bound . isInterface ( ) ) { int length = this . superInterfaces . length ; System . arraycopy ( this . superInterfaces , 0 , this . superInterfaces = new ReferenceBinding [ length + 1 ] , 1 , length ) ; this . superInterfaces [ 0 ] = ( ReferenceBinding ) this . bound ; } if ( this . otherBounds != null ) { int length = this . superInterfaces . length ; int otherLength = this . otherBounds . length ; System . arraycopy ( this . superInterfaces , 0 , this . superInterfaces = new ReferenceBinding [ length + otherLength ] , 0 , length ) ; for ( int i = 0 ; i < otherLength ; i ++ ) { this . superInterfaces [ length + i ] = ( ReferenceBinding ) this . otherBounds [ i ] ; } } } } return this . superInterfaces ; } public void swapUnresolved ( UnresolvedReferenceBinding unresolvedType , ReferenceBinding resolvedType , LookupEnvironment env ) { boolean affected = false ; if ( this . genericType == unresolvedType ) { this . genericType = resolvedType ; affected = true ; } if ( this . bound == unresolvedType ) { this . bound = env . convertUnresolvedBinaryToRawType ( resolvedType ) ; affected = true ; } if ( this . otherBounds != null ) { for ( int i = 0 , length = this . otherBounds . length ; i < length ; i ++ ) { if ( this . otherBounds [ i ] == unresolvedType ) { this . otherBounds [ i ] = env . convertUnresolvedBinaryToRawType ( resolvedType ) ; affected = true ; } } } if ( affected ) initialize ( this . genericType , this . bound , this . otherBounds ) ; } public String toString ( ) { switch ( this . boundKind ) { case Wildcard . UNBOUND : return new String ( TypeConstants . WILDCARD_NAME ) ; case Wildcard . EXTENDS : if ( this . otherBounds == null ) return new String ( CharOperation . concat ( TypeConstants . WILDCARD_NAME , TypeConstants . WILDCARD_EXTENDS , this . bound . debugName ( ) . toCharArray ( ) ) ) ; StringBuffer buffer = new StringBuffer ( this . bound . debugName ( ) ) ; for ( int i = 0 , length = this . otherBounds . length ; i < length ; i ++ ) { buffer . append ( '&' ) . append ( this . otherBounds [ i ] . debugName ( ) ) ; } return buffer . toString ( ) ; default : return new String ( CharOperation . concat ( TypeConstants . WILDCARD_NAME , TypeConstants . WILDCARD_SUPER , this . bound . debugName ( ) . toCharArray ( ) ) ) ; } } public TypeVariableBinding typeVariable ( ) { if ( this . typeVariable == null ) { TypeVariableBinding [ ] typeVariables = this . genericType . typeVariables ( ) ; if ( this . rank < typeVariables . length ) this . typeVariable = typeVariables [ this . rank ] ; } return this . typeVariable ; } } </s>