EMMA Coverage Report (generated Thu Dec 06 15:52:10 GMT 2007)
[all classes][com.sun.tools.javac.code]

COVERAGE SUMMARY FOR SOURCE FILE [Types.java]

nameclass, %method, %block, %line, %
Types.java88%  (30/34)38%  (101/267)20%  (1533/7595)21%  (267.2/1274)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class Types$240%   (0/1)0%   (0/1)0%   (0/26)0%   (0/1)
<static initializer> 0%   (0/1)0%   (0/26)0%   (0/1)
     
class Types$AdaptFailure0%   (0/1)0%   (0/1)0%   (0/3)0%   (0/1)
Types$AdaptFailure (): void 0%   (0/1)0%   (0/3)0%   (0/1)
     
class Types$SingletonType0%   (0/1)0%   (0/4)0%   (0/36)0%   (0/6)
Types$SingletonType (Types, Type): void 0%   (0/1)0%   (0/9)0%   (0/3)
equals (Object): boolean 0%   (0/1)0%   (0/16)0%   (0/1)
hashCode (): int 0%   (0/1)0%   (0/7)0%   (0/1)
toString (): String 0%   (0/1)0%   (0/4)0%   (0/1)
     
class Types$TypePair0%   (0/1)0%   (0/3)0%   (0/56)0%   (0/9)
Types$TypePair (Types, Type, Type): void 0%   (0/1)0%   (0/12)0%   (0/4)
equals (Object): boolean 0%   (0/1)0%   (0/28)0%   (0/4)
hashCode (): int 0%   (0/1)0%   (0/16)0%   (0/1)
     
class Types$8100% (1/1)12%  (1/8)2%   (6/261)3%   (1/31)
L (Type): Type 0%   (0/1)0%   (0/21)0%   (0/7)
U (Type): Type 0%   (0/1)0%   (0/28)0%   (0/7)
debugContainsType (Type$WildcardType, Type): void 0%   (0/1)0%   (0/115)0%   (0/6)
visitErrorType (Type$ErrorType, Type): Boolean 0%   (0/1)0%   (0/3)0%   (0/1)
visitType (Type, Type): Boolean 0%   (0/1)0%   (0/18)0%   (0/3)
visitUndetVar (Type$UndetVar, Type): Boolean 0%   (0/1)0%   (0/14)0%   (0/3)
visitWildcardType (Type$WildcardType, Type): Boolean 0%   (0/1)0%   (0/56)0%   (0/3)
Types$8 (Types): void 100% (1/1)100% (6/6)100% (1/1)
     
class Types$23100% (1/1)12%  (1/8)3%   (3/97)6%   (1/18)
visitArrayType (Type$ArrayType, Void): Integer 0%   (0/1)0%   (0/10)0%   (0/1)
visitClassType (Type$ClassType, Void): Integer 0%   (0/1)0%   (0/45)0%   (0/7)
visitErrorType (Type$ErrorType, Void): Integer 0%   (0/1)0%   (0/3)0%   (0/1)
visitType (Type, Void): Integer 0%   (0/1)0%   (0/4)0%   (0/1)
visitTypeVar (Type$TypeVar, Void): Integer 0%   (0/1)0%   (0/5)0%   (0/1)
visitUndetVar (Type$UndetVar, Void): Integer 0%   (0/1)0%   (0/4)0%   (0/1)
visitWildcardType (Type$WildcardType, Void): Integer 0%   (0/1)0%   (0/23)0%   (0/5)
Types$23 (): void 100% (1/1)100% (3/3)100% (1/1)
     
class Types$10100% (1/1)20%  (1/5)6%   (11/193)6%   (2/32)
isCastableRecursive (Type, Type): boolean 0%   (0/1)0%   (0/36)0%   (0/5)
notSoftSubtypeRecursive (Type, Type): boolean 0%   (0/1)0%   (0/36)0%   (0/5)
visitType (Type, Type): Boolean 0%   (0/1)0%   (0/25)0%   (0/3)
visitWildcardType (Type$WildcardType, Type): Boolean 0%   (0/1)0%   (0/85)0%   (0/17)
Types$10 (Types): void 100% (1/1)100% (11/11)100% (2/2)
     
class Types$Subst100% (1/1)18%  (2/11)9%   (30/335)14%  (10/70)
subst (List): List 0%   (0/1)0%   (0/40)0%   (0/9)
visitArrayType (Type$ArrayType, Void): Type 0%   (0/1)0%   (0/21)0%   (0/4)
visitClassType (Type$ClassType, Void): Type 0%   (0/1)0%   (0/71)0%   (0/13)
visitErrorType (Type$ErrorType, Void): Type 0%   (0/1)0%   (0/2)0%   (0/1)
visitForAll (Type$ForAll, Void): Type 0%   (0/1)0%   (0/47)0%   (0/7)
visitMethodType (Type$MethodType, Void): Type 0%   (0/1)0%   (0/38)0%   (0/6)
visitType (Type, Void): Type 0%   (0/1)0%   (0/2)0%   (0/1)
visitTypeVar (Type$TypeVar, Void): Type 0%   (0/1)0%   (0/28)0%   (0/6)
visitWildcardType (Type$WildcardType, Void): Type 0%   (0/1)0%   (0/41)0%   (0/8)
subst (Type): Type 100% (1/1)55%  (6/11)67%  (2/3)
Types$Subst (Types, List, List): void 100% (1/1)71%  (24/34)67%  (8/12)
     
class Types$3100% (1/1)33%  (1/3)11%  (6/57)8%   (1/12)
visitClassType (Type$ClassType, Void): Boolean 0%   (0/1)0%   (0/48)0%   (0/10)
visitType (Type, Void): Boolean 0%   (0/1)0%   (0/3)0%   (0/1)
Types$3 (Types): void 100% (1/1)100% (6/6)100% (1/1)
     
class Types$5100% (1/1)38%  (3/8)11%  (44/390)9%   (4.8/54)
containsTypeRecursive (Type, Type): boolean 0%   (0/1)0%   (0/46)0%   (0/5)
rewriteSupers (Type): Type 0%   (0/1)0%   (0/99)0%   (0/22)
visitArrayType (Type$ArrayType, Type): Boolean 0%   (0/1)0%   (0/65)0%   (0/8)
visitType (Type, Type): Boolean 0%   (0/1)0%   (0/93)0%   (0/8)
visitUndetVar (Type$UndetVar, Type): Boolean 0%   (0/1)0%   (0/38)0%   (0/6)
visitClassType (Type$ClassType, Type): Boolean 100% (1/1)86%  (30/35)92%  (1.8/2)
Types$5 (Types): void 100% (1/1)100% (11/11)100% (2/2)
visitErrorType (Type$ErrorType, Type): Boolean 100% (1/1)100% (3/3)100% (1/1)
     
class Types$12100% (1/1)20%  (1/5)13%  (6/45)10%  (1/10)
visitArrayType (Type$ArrayType, Void): Boolean 0%   (0/1)0%   (0/6)0%   (0/1)
visitClassType (Type$ClassType, Void): Boolean 0%   (0/1)0%   (0/27)0%   (0/6)
visitType (Type, Void): Boolean 0%   (0/1)0%   (0/3)0%   (0/1)
visitTypeVar (Type$TypeVar, Void): Boolean 0%   (0/1)0%   (0/3)0%   (0/1)
Types$12 (Types): void 100% (1/1)100% (6/6)100% (1/1)
     
class Types$SimpleVisitor100% (1/1)25%  (1/4)15%  (3/20)25%  (1/4)
visitCapturedType (Type$CapturedType, Object): Object 0%   (0/1)0%   (0/5)0%   (0/1)
visitForAll (Type$ForAll, Object): Object 0%   (0/1)0%   (0/6)0%   (0/1)
visitUndetVar (Type$UndetVar, Object): Object 0%   (0/1)0%   (0/6)0%   (0/1)
Types$SimpleVisitor (): void 100% (1/1)100% (3/3)100% (1/1)
     
class Types$6100% (1/1)40%  (4/10)17%  (75/431)16%  (9/55)
visitArrayType (Type$ArrayType, Type): Boolean 0%   (0/1)0%   (0/35)0%   (0/5)
visitErrorType (Type$ErrorType, Type): Boolean 0%   (0/1)0%   (0/3)0%   (0/1)
visitForAll (Type$ForAll, Type): Boolean 0%   (0/1)0%   (0/37)0%   (0/4)
visitPackageType (Type$PackageType, Type): Boolean 0%   (0/1)0%   (0/8)0%   (0/1)
visitUndetVar (Type$UndetVar, Type): Boolean 0%   (0/1)0%   (0/89)0%   (0/14)
visitWildcardType (Type$WildcardType, Type): Boolean 0%   (0/1)0%   (0/13)0%   (0/3)
visitType (Type, Type): Boolean 100% (1/1)10%  (6/63)25%  (2/8)
visitClassType (Type$ClassType, Type): Boolean 100% (1/1)27%  (43/157)29%  (5/17)
Types$6 (Types): void 100% (1/1)100% (6/6)100% (1/1)
visitMethodType (Type$MethodType, Type): Boolean 100% (1/1)100% (20/20)100% (1/1)
     
class Types100% (1/1)37%  (41/111)19%  (768/4065)21%  (152.5/732)
access$000 (Types, Type, ListBuffer, ListBuffer): void 0%   (0/1)0%   (0/6)0%   (0/1)
access$100 (Types, Type, Type): boolean 0%   (0/1)0%   (0/5)0%   (0/1)
access$400 (Types, Type, Type, Warner): boolean 0%   (0/1)0%   (0/6)0%   (0/1)
access$500 (Types, Type, Type, Warner): boolean 0%   (0/1)0%   (0/6)0%   (0/1)
access$700 (Types): Type 0%   (0/1)0%   (0/3)0%   (0/1)
access$800 (Types, List): List 0%   (0/1)0%   (0/4)0%   (0/1)
appendTyparamString (Type$TypeVar, StringBuffer): void 0%   (0/1)0%   (0/97)0%   (0/18)
arraySuperType (): Type 0%   (0/1)0%   (0/35)0%   (0/6)
asEnclosingSuper (Type, Symbol): Type 0%   (0/1)0%   (0/60)0%   (0/11)
boxedClass (Type): Symbol$ClassSymbol 0%   (0/1)0%   (0/10)0%   (0/1)
closureMin (List): List 0%   (0/1)0%   (0/55)0%   (0/14)
compoundMin (List): Type 0%   (0/1)0%   (0/28)0%   (0/7)
containedBy (Type, Type): boolean 0%   (0/1)0%   (0/44)0%   (0/9)
containsType (List, List): boolean 0%   (0/1)0%   (0/32)0%   (0/4)
containsType (Type, Type): boolean 0%   (0/1)0%   (0/8)0%   (0/1)
covariantReturnType (Type, Type, Warner): boolean 0%   (0/1)0%   (0/25)0%   (0/1)
dimensions (Type): int 0%   (0/1)0%   (0/14)0%   (0/5)
disjointType (Type, Type): boolean 0%   (0/1)0%   (0/8)0%   (0/1)
elemtype (Type): Type 0%   (0/1)0%   (0/23)0%   (0/6)
erasure (List): List 0%   (0/1)0%   (0/5)0%   (0/1)
freshTypeVariables (List): List 0%   (0/1)0%   (0/52)0%   (0/10)
getBounds (Type$TypeVar): List 0%   (0/1)0%   (0/34)0%   (0/5)
glb (Type, Type): Type 0%   (0/1)0%   (0/74)0%   (0/19)
hasSameBounds (Type$ForAll, Type$ForAll): boolean 0%   (0/1)0%   (0/46)0%   (0/6)
hashCode (Type): int 0%   (0/1)0%   (0/6)0%   (0/1)
intersect (List, List): List 0%   (0/1)0%   (0/145)0%   (0/17)
isArray (Type): boolean 0%   (0/1)0%   (0/17)0%   (0/3)
isAssignable (Type, Type): boolean 0%   (0/1)0%   (0/6)0%   (0/1)
isCaptureOf (Type, Type$WildcardType): boolean 0%   (0/1)0%   (0/16)0%   (0/3)
isCastable (Type, Type): boolean 0%   (0/1)0%   (0/6)0%   (0/1)
isConvertible (Type, Type): boolean 0%   (0/1)0%   (0/6)0%   (0/1)
isDerivedRaw (List): boolean 0%   (0/1)0%   (0/18)0%   (0/3)
isDerivedRaw (Type): boolean 0%   (0/1)0%   (0/22)0%   (0/5)
isDerivedRawInternal (Type): boolean 0%   (0/1)0%   (0/28)0%   (0/3)
isReifiable (Type): boolean 0%   (0/1)0%   (0/7)0%   (0/1)
isSameTypes (List, List): boolean 0%   (0/1)0%   (0/32)0%   (0/4)
isSameWildcard (Type$WildcardType, Type): boolean 0%   (0/1)0%   (0/23)0%   (0/4)
isSubtypeUnchecked (Type, List, Warner): boolean 0%   (0/1)0%   (0/21)0%   (0/4)
isSubtypeUnchecked (Type, Type): boolean 0%   (0/1)0%   (0/6)0%   (0/1)
isSubtypes (List, List): boolean 0%   (0/1)0%   (0/32)0%   (0/4)
isSubtypesUnchecked (List, List, Warner): boolean 0%   (0/1)0%   (0/33)0%   (0/4)
isUnbounded (Type): boolean 0%   (0/1)0%   (0/7)0%   (0/1)
lowerBoundArgtypes (Type): List 0%   (0/1)0%   (0/6)0%   (0/1)
lub (List): Type 0%   (0/1)0%   (0/208)0%   (0/41)
lub (Type, Type): Type 0%   (0/1)0%   (0/6)0%   (0/1)
makeCompoundType (List): Type 0%   (0/1)0%   (0/23)0%   (0/2)
makeCompoundType (List, Type): Type 0%   (0/1)0%   (0/88)0%   (0/14)
makeCompoundType (Type, Type): Type 0%   (0/1)0%   (0/6)0%   (0/1)
makeExtendsWildcard (Type, Type$TypeVar): Type$WildcardType 0%   (0/1)0%   (0/27)0%   (0/3)
makeSuperWildcard (Type, Type$TypeVar): Type$WildcardType 0%   (0/1)0%   (0/26)0%   (0/3)
merge (Type, Type): Type 0%   (0/1)0%   (0/152)0%   (0/22)
newInstances (List): List 0%   (0/1)0%   (0/27)0%   (0/5)
notSoftSubtype (Type, Type): boolean 0%   (0/1)0%   (0/54)0%   (0/11)
overrideEquivalent (Type, Type): boolean 0%   (0/1)0%   (0/23)0%   (0/1)
resultSubtype (Type, Type, Warner): boolean 0%   (0/1)0%   (0/22)0%   (0/5)
returnTypeSubstitutable (Type, Type): boolean 0%   (0/1)0%   (0/21)0%   (0/3)
returnTypeSubstitutable (Type, Type, Type, Warner): boolean 0%   (0/1)0%   (0/58)0%   (0/14)
setBounds (Type$TypeVar, List): void 0%   (0/1)0%   (0/27)0%   (0/4)
setBounds (Type$TypeVar, List, Type): void 0%   (0/1)0%   (0/20)0%   (0/5)
sideCast (Type, Type, Warner): boolean 0%   (0/1)0%   (0/111)0%   (0/22)
sideCastFinal (Type, Type, Warner): boolean 0%   (0/1)0%   (0/100)0%   (0/18)
subst (List, List, List): List 0%   (0/1)0%   (0/9)0%   (0/1)
substBound (Type$TypeVar, List, List): Type$TypeVar 0%   (0/1)0%   (0/23)0%   (0/4)
substBounds (List, List, List): List 0%   (0/1)0%   (0/135)0%   (0/30)
superClosure (Type, Type): List 0%   (0/1)0%   (0/42)0%   (0/6)
toString (Type): String 0%   (0/1)0%   (0/29)0%   (0/4)
typaramsString (List): String 0%   (0/1)0%   (0/41)0%   (0/9)
unboxedType (Type): Type 0%   (0/1)0%   (0/37)0%   (0/6)
union (List, List): List 0%   (0/1)0%   (0/60)0%   (0/9)
upperBounds (List): List 0%   (0/1)0%   (0/30)0%   (0/6)
capture (Type): Type 100% (1/1)10%  (17/167)12%  (5/40)
isSuperType (Type, Type): boolean 100% (1/1)11%  (5/47)20%  (2/10)
adaptRecursive (Type, Type, ListBuffer, ListBuffer, Map): void 100% (1/1)17%  (23/138)23%  (5.4/24)
disjointTypes (List, List): boolean 100% (1/1)19%  (5/26)30%  (1.5/5)
isAssignable (Type, Type, Warner): boolean 100% (1/1)21%  (14/66)17%  (2.6/15)
asOuterSuper (Type, Symbol): Type 100% (1/1)29%  (12/41)30%  (3/10)
rewriteQuantifiers (Type, boolean, boolean): Type 100% (1/1)31%  (33/107)40%  (8.8/22)
adapt (List, List, ListBuffer, ListBuffer, Map): void 100% (1/1)33%  (9/27)50%  (3/6)
giveWarning (Type, Type): boolean 100% (1/1)36%  (5/14)35%  (0.4/1)
isSubtypeUnchecked (Type, Type, Warner): boolean 100% (1/1)36%  (24/67)52%  (6.2/12)
rank (Type): int 100% (1/1)39%  (43/110)44%  (11/25)
isConvertible (Type, Type, Warner): boolean 100% (1/1)41%  (15/37)67%  (4/6)
containsTypeEquivalent (Type, Type): boolean 100% (1/1)42%  (8/19)42%  (0.4/1)
insert (List, Type): List 100% (1/1)44%  (16/36)40%  (2/5)
adapt (Type, Type, ListBuffer, ListBuffer): void 100% (1/1)49%  (21/43)50%  (6/12)
isCastable (Type, Type, Warner): boolean 100% (1/1)55%  (36/65)75%  (6.7/9)
adaptSelf (Type, ListBuffer, ListBuffer): void 100% (1/1)62%  (10/16)60%  (3/5)
closure (Type): List 100% (1/1)66%  (50/76)74%  (10.4/14)
isSubtype (Type, Type, boolean): boolean 100% (1/1)72%  (34/47)86%  (6.9/8)
memberType (Type, Symbol): Type 100% (1/1)82%  (14/17)82%  (0.8/1)
isSubSignature (Type, Type): boolean 100% (1/1)88%  (14/16)87%  (0.9/1)
<static initializer> 100% (1/1)95%  (20/21)99%  (4/4)
Types (Context): void 100% (1/1)100% (189/189)100% (36/36)
access$200 (Types, Type, boolean, boolean): Type 100% (1/1)100% (6/6)100% (1/1)
access$300 (Types, Type, Type): boolean 100% (1/1)100% (5/5)100% (1/1)
access$600 (Types): Type$Mapping 100% (1/1)100% (3/3)100% (1/1)
asSub (Type, Symbol): Type 100% (1/1)100% (7/7)100% (1/1)
asSuper (Type, Symbol): Type 100% (1/1)100% (7/7)100% (1/1)
classBound (Type): Type 100% (1/1)100% (6/6)100% (1/1)
containsTypeEquivalent (List, List): boolean 100% (1/1)100% (32/32)100% (4/4)
erasure (Type): Type 100% (1/1)100% (12/12)100% (3/3)
hasSameArgs (Type, Type): boolean 100% (1/1)100% (8/8)100% (1/1)
instance (Context): Types 100% (1/1)100% (14/14)100% (4/4)
interfaces (Type): List 100% (1/1)100% (6/6)100% (1/1)
isSameType (Type, Type): boolean 100% (1/1)100% (8/8)100% (1/1)
isSubtype (Type, Type): boolean 100% (1/1)100% (6/6)100% (1/1)
isSubtypeNoCapture (Type, Type): boolean 100% (1/1)100% (6/6)100% (1/1)
lowerBound (Type): Type 100% (1/1)100% (5/5)100% (1/1)
subst (Type, List, List): Type 100% (1/1)100% (9/9)100% (1/1)
supertype (Type): Type 100% (1/1)100% (6/6)100% (1/1)
upperBound (Type): Type 100% (1/1)100% (5/5)100% (1/1)
     
class Types$1100% (1/1)33%  (1/3)19%  (6/31)20%  (1/5)
visitCapturedType (Type$CapturedType, Void): Type 0%   (0/1)0%   (0/5)0%   (0/1)
visitWildcardType (Type$WildcardType, Void): Type 0%   (0/1)0%   (0/20)0%   (0/3)
Types$1 (Types): void 100% (1/1)100% (6/6)100% (1/1)
     
class Types$2100% (1/1)33%  (1/3)25%  (6/24)33%  (1/3)
visitCapturedType (Type$CapturedType, Void): Type 0%   (0/1)0%   (0/5)0%   (0/1)
visitWildcardType (Type$WildcardType, Void): Type 0%   (0/1)0%   (0/13)0%   (0/1)
Types$2 (Types): void 100% (1/1)100% (6/6)100% (1/1)
     
class Types$22100% (1/1)50%  (1/2)29%  (4/14)50%  (1/2)
apply (Type): Type 0%   (0/1)0%   (0/10)0%   (0/1)
Types$22 (String): void 100% (1/1)100% (4/4)100% (1/1)
     
class Types$19100% (1/1)80%  (4/5)29%  (29/99)31%  (5.9/19)
visitTypeVar (Type$TypeVar, Void): List 0%   (0/1)0%   (0/20)0%   (0/5)
visitClassType (Type$ClassType, Void): List 100% (1/1)22%  (14/63)33%  (4/12)
<static initializer> 100% (1/1)88%  (7/8)87%  (0.9/1)
Types$19 (Types): void 100% (1/1)100% (6/6)100% (1/1)
visitType (Type, Void): List 100% (1/1)100% (2/2)100% (1/1)
     
class Types$9100% (1/1)50%  (4/8)30%  (208/685)29%  (27.4/94)
visitArrayType (Type$ArrayType, Type): Boolean 0%   (0/1)0%   (0/70)0%   (0/11)
visitType (Type, Type): Boolean 0%   (0/1)0%   (0/42)0%   (0/8)
visitTypeVar (Type$TypeVar, Type): Boolean 0%   (0/1)0%   (0/48)0%   (0/9)
visitWildcardType (Type$WildcardType, Type): Boolean 0%   (0/1)0%   (0/15)0%   (0/1)
visitClassType (Type$ClassType, Type): Boolean 100% (1/1)39%  (192/493)40%  (25.5/63)
<static initializer> 100% (1/1)88%  (7/8)87%  (0.9/1)
Types$9 (Types): void 100% (1/1)100% (6/6)100% (1/1)
visitErrorType (Type$ErrorType, Type): Boolean 100% (1/1)100% (3/3)100% (1/1)
     
class Types$15100% (1/1)33%  (2/6)31%  (25/81)29%  (5/17)
visitErrorType (Type$ErrorType, Symbol): Type 0%   (0/1)0%   (0/2)0%   (0/1)
visitType (Type, Symbol): Type 0%   (0/1)0%   (0/3)0%   (0/1)
visitTypeVar (Type$TypeVar, Symbol): Type 0%   (0/1)0%   (0/7)0%   (0/1)
visitWildcardType (Type$WildcardType, Symbol): Type 0%   (0/1)0%   (0/9)0%   (0/1)
visitClassType (Type$ClassType, Symbol): Type 100% (1/1)35%  (19/54)33%  (4/12)
Types$15 (Types): void 100% (1/1)100% (6/6)100% (1/1)
     
class Types$21100% (1/1)40%  (2/5)34%  (23/67)25%  (2/8)
visitErrorType (Type$ErrorType, Type): Boolean 0%   (0/1)0%   (0/3)0%   (0/1)
visitForAll (Type$ForAll, Type): Boolean 0%   (0/1)0%   (0/37)0%   (0/4)
visitType (Type, Type): Boolean 0%   (0/1)0%   (0/4)0%   (0/1)
Types$21 (Types): void 100% (1/1)100% (6/6)100% (1/1)
visitMethodType (Type$MethodType, Type): Boolean 100% (1/1)100% (17/17)100% (1/1)
     
class Types$7100% (1/1)50%  (1/2)35%  (7/20)33%  (1/3)
apply (Type): Type 0%   (0/1)0%   (0/13)0%   (0/2)
Types$7 (Types, String): void 100% (1/1)100% (7/7)100% (1/1)
     
class Types$DefaultTypeVisitor100% (1/1)42%  (5/12)40%  (23/58)42%  (5/12)
visitArrayType (Type$ArrayType, Object): Object 0%   (0/1)0%   (0/5)0%   (0/1)
visitCapturedType (Type$CapturedType, Object): Object 0%   (0/1)0%   (0/5)0%   (0/1)
visitForAll (Type$ForAll, Object): Object 0%   (0/1)0%   (0/5)0%   (0/1)
visitPackageType (Type$PackageType, Object): Object 0%   (0/1)0%   (0/5)0%   (0/1)
visitTypeVar (Type$TypeVar, Object): Object 0%   (0/1)0%   (0/5)0%   (0/1)
visitUndetVar (Type$UndetVar, Object): Object 0%   (0/1)0%   (0/5)0%   (0/1)
visitWildcardType (Type$WildcardType, Object): Object 0%   (0/1)0%   (0/5)0%   (0/1)
Types$DefaultTypeVisitor (): void 100% (1/1)100% (3/3)100% (1/1)
visit (Type, Object): Object 100% (1/1)100% (5/5)100% (1/1)
visitClassType (Type$ClassType, Object): Object 100% (1/1)100% (5/5)100% (1/1)
visitErrorType (Type$ErrorType, Object): Object 100% (1/1)100% (5/5)100% (1/1)
visitMethodType (Type$MethodType, Object): Object 100% (1/1)100% (5/5)100% (1/1)
     
class Types$18100% (1/1)67%  (4/6)40%  (48/120)59%  (13/22)
visitArrayType (Type$ArrayType, Void): Type 0%   (0/1)0%   (0/29)0%   (0/3)
visitTypeVar (Type$TypeVar, Void): Type 0%   (0/1)0%   (0/22)0%   (0/3)
visitClassType (Type$ClassType, Void): Type 100% (1/1)64%  (38/59)77%  (10/13)
Types$18 (Types): void 100% (1/1)100% (6/6)100% (1/1)
visitErrorType (Type$ErrorType, Void): Type 100% (1/1)100% (2/2)100% (1/1)
visitType (Type, Void): Type 100% (1/1)100% (2/2)100% (1/1)
     
class Types$4100% (1/1)50%  (2/4)44%  (68/153)47%  (14.4/31)
visitErrorType (Type$ErrorType, Symbol): Type 0%   (0/1)0%   (0/2)0%   (0/1)
visitType (Type, Symbol): Type 0%   (0/1)0%   (0/2)0%   (0/1)
visitClassType (Type$ClassType, Symbol): Type 100% (1/1)43%  (62/143)48%  (13.4/28)
Types$4 (Types): void 100% (1/1)100% (6/6)100% (1/1)
     
class Types$14100% (1/1)33%  (2/6)48%  (44/91)56%  (10/18)
visitArrayType (Type$ArrayType, Symbol): Type 0%   (0/1)0%   (0/12)0%   (0/1)
visitErrorType (Type$ErrorType, Symbol): Type 0%   (0/1)0%   (0/2)0%   (0/1)
visitType (Type, Symbol): Type 0%   (0/1)0%   (0/2)0%   (0/1)
visitTypeVar (Type$TypeVar, Symbol): Type 0%   (0/1)0%   (0/7)0%   (0/1)
visitClassType (Type$ClassType, Symbol): Type 100% (1/1)61%  (38/62)69%  (9/13)
Types$14 (Types): void 100% (1/1)100% (6/6)100% (1/1)
     
class Types$20100% (1/1)60%  (3/5)51%  (20/39)62%  (5/8)
visitErrorType (Type$ErrorType, Void): Type 0%   (0/1)0%   (0/2)0%   (0/1)
visitTypeVar (Type$TypeVar, Void): Type 0%   (0/1)0%   (0/8)0%   (0/1)
visitClassType (Type$ClassType, Void): Type 100% (1/1)57%  (12/21)75%  (3/4)
Types$20 (Types): void 100% (1/1)100% (6/6)100% (1/1)
visitType (Type, Void): Type 100% (1/1)100% (2/2)100% (1/1)
     
class Types$16100% (1/1)50%  (3/6)55%  (22/40)50%  (4/8)
visitErrorType (Type$ErrorType, Void): Type 0%   (0/1)0%   (0/2)0%   (0/1)
visitTypeVar (Type$TypeVar, Void): Type 0%   (0/1)0%   (0/6)0%   (0/1)
visitWildcardType (Type$WildcardType, Void): Type 0%   (0/1)0%   (0/8)0%   (0/1)
visitType (Type, Void): Type 100% (1/1)83%  (10/12)67%  (2/3)
Types$16 (Types): void 100% (1/1)100% (6/6)100% (1/1)
visitClassType (Type$ClassType, Void): Type 100% (1/1)100% (6/6)100% (1/1)
     
class Types$11100% (1/1)50%  (1/2)58%  (7/12)50%  (1/2)
apply (Type): Type 0%   (0/1)0%   (0/5)0%   (0/1)
Types$11 (Types, String): void 100% (1/1)100% (7/7)100% (1/1)
     
class Types$13100% (1/1)50%  (1/2)58%  (7/12)50%  (1/2)
apply (Type): Type 0%   (0/1)0%   (0/5)0%   (0/1)
Types$13 (Types, String): void 100% (1/1)100% (7/7)100% (1/1)
     
class Types$17100% (1/1)100% (2/2)100% (12/12)100% (2/2)
Types$17 (Types, String): void 100% (1/1)100% (7/7)100% (1/1)
apply (Type): Type 100% (1/1)100% (5/5)100% (1/1)
     
class Types$MapVisitor100% (1/1)100% (3/3)100% (11/11)100% (3/3)
Types$MapVisitor (): void 100% (1/1)100% (3/3)100% (1/1)
visit (Type): Type 100% (1/1)100% (6/6)100% (1/1)
visitType (Type, Object): Type 100% (1/1)100% (2/2)100% (1/1)
     
class Types$TypeRelation100% (1/1)100% (1/1)100% (3/3)100% (1/1)
Types$TypeRelation (): void 100% (1/1)100% (3/3)100% (1/1)
     
class Types$UnaryVisitor100% (1/1)100% (2/2)100% (8/8)100% (2/2)
Types$UnaryVisitor (): void 100% (1/1)100% (3/3)100% (1/1)
visit (Type): Object 100% (1/1)100% (5/5)100% (1/1)

1/*
2 * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25 
26package com.sun.tools.javac.code;
27 
28import java.util.*;
29 
30import com.sun.tools.javac.util.*;
31import com.sun.tools.javac.util.List;
32 
33import com.sun.tools.javac.jvm.ClassReader;
34import com.sun.tools.javac.comp.Infer;
35import com.sun.tools.javac.comp.Check;
36 
37import static com.sun.tools.javac.code.Type.*;
38import static com.sun.tools.javac.code.TypeTags.*;
39import static com.sun.tools.javac.code.Symbol.*;
40import static com.sun.tools.javac.code.Flags.*;
41import static com.sun.tools.javac.code.BoundKind.*;
42import static com.sun.tools.javac.util.ListBuffer.lb;
43 
44/**
45 * Utility class containing various operations on types.
46 *
47 * <p>Unless other names are more illustrative, the following naming
48 * conventions should be observed in this file:
49 *
50 * <dl>
51 * <dt>t</dt>
52 * <dd>If the first argument to an operation is a type, it should be named t.</dd>
53 * <dt>s</dt>
54 * <dd>Similarly, if the second argument to an operation is a type, it should be named s.</dd>
55 * <dt>ts</dt>
56 * <dd>If an operations takes a list of types, the first should be named ts.</dd>
57 * <dt>ss</dt>
58 * <dd>A second list of types should be named ss.</dd>
59 * </dl>
60 *
61 * <p><b>This is NOT part of any API supported by Sun Microsystems.
62 * If you write code that depends on this, you do so at your own risk.
63 * This code and its internal interfaces are subject to change or
64 * deletion without notice.</b>
65 */
66public class Types {
67    protected static final Context.Key<Types> typesKey =
68        new Context.Key<Types>();
69 
70    final Symtab syms;
71    final Name.Table names;
72    final boolean allowBoxing;
73    final ClassReader reader;
74    final Source source;
75    final Check chk;
76    List<Warner> warnStack = List.nil();
77    final Name capturedName;
78 
79    // <editor-fold defaultstate="collapsed" desc="Instantiating">
80    public static Types instance(Context context) {
81        Types instance = context.get(typesKey);
82        if (instance == null)
83            instance = new Types(context);
84        return instance;
85    }
86 
87    protected Types(Context context) {
88        context.put(typesKey, this);
89        syms = Symtab.instance(context);
90        names = Name.Table.instance(context);
91        allowBoxing = Source.instance(context).allowBoxing();
92        reader = ClassReader.instance(context);
93        source = Source.instance(context);
94        chk = Check.instance(context);
95        capturedName = names.fromString("<captured wildcard>");
96    }
97    // </editor-fold>
98 
99    // <editor-fold defaultstate="collapsed" desc="upperBound">
100    /**
101     * The "rvalue conversion".<br>
102     * The upper bound of most types is the type
103     * itself.  Wildcards, on the other hand have upper
104     * and lower bounds.
105     * @param t a type
106     * @return the upper bound of the given type
107     */
108    public Type upperBound(Type t) {
109        return upperBound.visit(t);
110    }
111    // where
112        private final MapVisitor<Void> upperBound = new MapVisitor<Void>() {
113 
114            @Override
115            public Type visitWildcardType(WildcardType t, Void ignored) {
116                if (t.isSuperBound())
117                    return t.bound == null ? syms.objectType : t.bound.bound;
118                else
119                    return visit(t.type);
120            }
121 
122            @Override
123            public Type visitCapturedType(CapturedType t, Void ignored) {
124                return visit(t.bound);
125            }
126        };
127    // </editor-fold>
128 
129    // <editor-fold defaultstate="collapsed" desc="lowerBound">
130    /**
131     * The "lvalue conversion".<br>
132     * The lower bound of most types is the type
133     * itself.  Wildcards, on the other hand have upper
134     * and lower bounds.
135     * @param t a type
136     * @return the lower bound of the given type
137     */
138    public Type lowerBound(Type t) {
139        return lowerBound.visit(t);
140    }
141    // where
142        private final MapVisitor<Void> lowerBound = new MapVisitor<Void>() {
143 
144            @Override
145            public Type visitWildcardType(WildcardType t, Void ignored) {
146                return t.isExtendsBound() ? syms.botType : visit(t.type);
147            }
148 
149            @Override
150            public Type visitCapturedType(CapturedType t, Void ignored) {
151                return visit(t.getLowerBound());
152            }
153        };
154    // </editor-fold>
155 
156    // <editor-fold defaultstate="collapsed" desc="isUnbounded">
157    /**
158     * Checks that all the arguments to a class are unbounded
159     * wildcards or something else that doesn't make any restrictions
160     * on the arguments. If a class isUnbounded, a raw super- or
161     * subclass can be cast to it without a warning.
162     * @param t a type
163     * @return true iff the given type is unbounded or raw
164     */
165    public boolean isUnbounded(Type t) {
166        return isUnbounded.visit(t);
167    }
168    // where
169        private final UnaryVisitor<Boolean> isUnbounded = new UnaryVisitor<Boolean>() {
170 
171            public Boolean visitType(Type t, Void ignored) {
172                return true;
173            }
174 
175            @Override
176            public Boolean visitClassType(ClassType t, Void ignored) {
177                List<Type> parms = t.tsym.type.allparams();
178                List<Type> args = t.allparams();
179                while (parms.nonEmpty()) {
180                    WildcardType unb = new WildcardType(syms.objectType,
181                                                        BoundKind.UNBOUND,
182                                                        syms.boundClass,
183                                                        (TypeVar)parms.head);
184                    if (!containsType(args.head, unb))
185                        return false;
186                    parms = parms.tail;
187                    args = args.tail;
188                }
189                return true;
190            }
191        };
192    // </editor-fold>
193 
194    // <editor-fold defaultstate="collapsed" desc="asSub">
195    /**
196     * Return the least specific subtype of t that starts with symbol
197     * sym.  If none exists, return null.  The least specific subtype
198     * is determined as follows:
199     *
200     * <p>If there is exactly one parameterized instance of sym that is a
201     * subtype of t, that parameterized instance is returned.<br>
202     * Otherwise, if the plain type or raw type `sym' is a subtype of
203     * type t, the type `sym' itself is returned.  Otherwise, null is
204     * returned.
205     */
206    public Type asSub(Type t, Symbol sym) {
207        return asSub.visit(t, sym);
208    }
209    // where
210        private final SimpleVisitor<Type,Symbol> asSub = new SimpleVisitor<Type,Symbol>() {
211 
212            public Type visitType(Type t, Symbol sym) {
213                return null;
214            }
215 
216            @Override
217            public Type visitClassType(ClassType t, Symbol sym) {
218                if (t.tsym == sym)
219                    return t;
220                Type base = asSuper(sym.type, t.tsym);
221                if (base == null)
222                    return null;
223                ListBuffer<Type> from = new ListBuffer<Type>();
224                ListBuffer<Type> to = new ListBuffer<Type>();
225                try {
226                    adapt(base, t, from, to);
227                } catch (AdaptFailure ex) {
228                    return null;
229                }
230                Type res = subst(sym.type, from.toList(), to.toList());
231                if (!isSubtype(res, t))
232                    return null;
233                ListBuffer<Type> openVars = new ListBuffer<Type>();
234                for (List<Type> l = sym.type.allparams();
235                     l.nonEmpty(); l = l.tail)
236                    if (res.contains(l.head) && !t.contains(l.head))
237                        openVars.append(l.head);
238                if (openVars.nonEmpty()) {
239                    if (t.isRaw()) {
240                        // The subtype of a raw type is raw
241                        res = erasure(res);
242                    } else {
243                        // Unbound type arguments default to ?
244                        List<Type> opens = openVars.toList();
245                        ListBuffer<Type> qs = new ListBuffer<Type>();
246                        for (List<Type> iter = opens; iter.nonEmpty(); iter = iter.tail) {
247                            qs.append(new WildcardType(syms.objectType, BoundKind.UNBOUND, syms.boundClass, (TypeVar) iter.head));
248                        }
249                        res = subst(res, opens, qs.toList());
250                    }
251                }
252                return res;
253            }
254 
255            @Override
256            public Type visitErrorType(ErrorType t, Symbol sym) {
257                return t;
258            }
259        };
260    // </editor-fold>
261 
262    // <editor-fold defaultstate="collapsed" desc="isConvertible">
263    /**
264     * Is t a subtype of or convertiable via boxing/unboxing
265     * convertions to s?
266     */
267    public boolean isConvertible(Type t, Type s, Warner warn) {
268        boolean tPrimitive = t.isPrimitive();
269        boolean sPrimitive = s.isPrimitive();
270        if (tPrimitive == sPrimitive)
271            return isSubtypeUnchecked(t, s, warn);
272        if (!allowBoxing) return false;
273        return tPrimitive
274            ? isSubtype(boxedClass(t).type, s)
275            : isSubtype(unboxedType(t), s);
276    }
277 
278    /**
279     * Is t a subtype of or convertiable via boxing/unboxing
280     * convertions to s?
281     */
282    public boolean isConvertible(Type t, Type s) {
283        return isConvertible(t, s, Warner.noWarnings);
284    }
285    // </editor-fold>
286 
287    // <editor-fold defaultstate="collapsed" desc="isSubtype">
288    /**
289     * Is t an unchecked subtype of s?
290     */
291    public boolean isSubtypeUnchecked(Type t, Type s) {
292        return isSubtypeUnchecked(t, s, Warner.noWarnings);
293    }
294    /**
295     * Is t an unchecked subtype of s?
296     */
297    public boolean isSubtypeUnchecked(Type t, Type s, Warner warn) {
298        if (t.tag == ARRAY && s.tag == ARRAY) {
299            return (((ArrayType)t).elemtype.tag <= lastBaseTag)
300                ? isSameType(elemtype(t), elemtype(s))
301                : isSubtypeUnchecked(elemtype(t), elemtype(s), warn);
302        } else if (isSubtype(t, s)) {
303            return true;
304        } else if (!s.isRaw()) {
305            Type t2 = asSuper(t, s.tsym);
306            if (t2 != null && t2.isRaw()) {
307                if (isReifiable(s))
308                    warn.silentUnchecked();
309                else
310                    warn.warnUnchecked();
311                return true;
312            }
313        }
314        return false;
315    }
316 
317    /**
318     * Is t a subtype of s?<br>
319     * (not defined for Method and ForAll types)
320     */
321    final public boolean isSubtype(Type t, Type s) {
322        return isSubtype(t, s, true);
323    }
324    final public boolean isSubtypeNoCapture(Type t, Type s) {
325        return isSubtype(t, s, false);
326    }
327    public boolean isSubtype(Type t, Type s, boolean capture) {
328        if (t == s)
329            return true;
330 
331        if (s.tag >= firstPartialTag)
332            return isSuperType(s, t);
333 
334        Type lower = lowerBound(s);
335        if (s != lower)
336            return isSubtype(capture ? capture(t) : t, lower, false);
337 
338        return isSubtype.visit(capture ? capture(t) : t, s);
339    }
340    // where
341        private TypeRelation isSubtype = new TypeRelation()
342        {
343            public Boolean visitType(Type t, Type s) {
344                switch (t.tag) {
345                case BYTE: case CHAR:
346                    return (t.tag == s.tag ||
347                              t.tag + 2 <= s.tag && s.tag <= DOUBLE);
348                case SHORT: case INT: case LONG: case FLOAT: case DOUBLE:
349                    return t.tag <= s.tag && s.tag <= DOUBLE;
350                case BOOLEAN: case VOID:
351                    return t.tag == s.tag;
352                case TYPEVAR:
353                    return isSubtypeNoCapture(t.getUpperBound(), s);
354                case BOT:
355                    return
356                        s.tag == BOT || s.tag == CLASS ||
357                        s.tag == ARRAY || s.tag == TYPEVAR;
358                case NONE:
359                    return false;
360                default:
361                    throw new AssertionError("isSubtype " + t.tag);
362                }
363            }
364 
365            private Set<TypePair> cache = new HashSet<TypePair>();
366 
367            private boolean containsTypeRecursive(Type t, Type s) {
368                TypePair pair = new TypePair(t, s);
369                if (cache.add(pair)) {
370                    try {
371                        return containsType(t.getTypeArguments(),
372                                            s.getTypeArguments());
373                    } finally {
374                        cache.remove(pair);
375                    }
376                } else {
377                    return containsType(t.getTypeArguments(),
378                                        rewriteSupers(s).getTypeArguments());
379                }
380            }
381 
382            private Type rewriteSupers(Type t) {
383                if (!t.isParameterized())
384                    return t;
385                ListBuffer<Type> from = lb();
386                ListBuffer<Type> to = lb();
387                adaptSelf(t, from, to);
388                if (from.isEmpty())
389                    return t;
390                ListBuffer<Type> rewrite = lb();
391                boolean changed = false;
392                for (Type orig : to.toList()) {
393                    Type s = rewriteSupers(orig);
394                    if (s.isSuperBound() && !s.isExtendsBound()) {
395                        s = new WildcardType(syms.objectType,
396                                             BoundKind.UNBOUND,
397                                             syms.boundClass);
398                        changed = true;
399                    } else if (s != orig) {
400                        s = new WildcardType(upperBound(s),
401                                             BoundKind.EXTENDS,
402                                             syms.boundClass);
403                        changed = true;
404                    }
405                    rewrite.append(s);
406                }
407                if (changed)
408                    return subst(t.tsym.type, from.toList(), rewrite.toList());
409                else
410                    return t;
411            }
412 
413            @Override
414            public Boolean visitClassType(ClassType t, Type s) {
415                Type sup = asSuper(t, s.tsym);
416                return sup != null
417                    && sup.tsym == s.tsym
418                    // You're not allowed to write
419                    //     Vector<Object> vec = new Vector<String>();
420                    // But with wildcards you can write
421                    //     Vector<? extends Object> vec = new Vector<String>();
422                    // which means that subtype checking must be done
423                    // here instead of same-type checking (via containsType).
424                    && (!s.isParameterized() || containsTypeRecursive(s, sup))
425                    && isSubtypeNoCapture(sup.getEnclosingType(),
426                                          s.getEnclosingType());
427            }
428 
429            @Override
430            public Boolean visitArrayType(ArrayType t, Type s) {
431                if (s.tag == ARRAY) {
432                    if (t.elemtype.tag <= lastBaseTag)
433                        return isSameType(t.elemtype, elemtype(s));
434                    else
435                        return isSubtypeNoCapture(t.elemtype, elemtype(s));
436                }
437 
438                if (s.tag == CLASS) {
439                    Name sname = s.tsym.getQualifiedName();
440                    return sname == names.java_lang_Object
441                        || sname == names.java_lang_Cloneable
442                        || sname == names.java_io_Serializable;
443                }
444 
445                return false;
446            }
447 
448            @Override
449            public Boolean visitUndetVar(UndetVar t, Type s) {
450                //todo: test against origin needed? or replace with substitution?
451                if (t == s || t.qtype == s || s.tag == ERROR || s.tag == UNKNOWN)
452                    return true;
453 
454                if (t.inst != null)
455                    return isSubtypeNoCapture(t.inst, s); // TODO: ", warn"?
456 
457                t.hibounds = t.hibounds.prepend(s);
458                return true;
459            }
460 
461            @Override
462            public Boolean visitErrorType(ErrorType t, Type s) {
463                return true;
464            }
465        };
466 
467    /**
468     * Is t a subtype of every type in given list `ts'?<br>
469     * (not defined for Method and ForAll types)<br>
470     * Allows unchecked conversions.
471     */
472    public boolean isSubtypeUnchecked(Type t, List<Type> ts, Warner warn) {
473        for (List<Type> l = ts; l.nonEmpty(); l = l.tail)
474            if (!isSubtypeUnchecked(t, l.head, warn))
475                return false;
476        return true;
477    }
478 
479    /**
480     * Are corresponding elements of ts subtypes of ss?  If lists are
481     * of different length, return false.
482     */
483    public boolean isSubtypes(List<Type> ts, List<Type> ss) {
484        while (ts.tail != null && ss.tail != null
485               /*inlined: ts.nonEmpty() && ss.nonEmpty()*/ &&
486               isSubtype(ts.head, ss.head)) {
487            ts = ts.tail;
488            ss = ss.tail;
489        }
490        return ts.tail == null && ss.tail == null;
491        /*inlined: ts.isEmpty() && ss.isEmpty();*/
492    }
493 
494    /**
495     * Are corresponding elements of ts subtypes of ss, allowing
496     * unchecked conversions?  If lists are of different length,
497     * return false.
498     **/
499    public boolean isSubtypesUnchecked(List<Type> ts, List<Type> ss, Warner warn) {
500        while (ts.tail != null && ss.tail != null
501               /*inlined: ts.nonEmpty() && ss.nonEmpty()*/ &&
502               isSubtypeUnchecked(ts.head, ss.head, warn)) {
503            ts = ts.tail;
504            ss = ss.tail;
505        }
506        return ts.tail == null && ss.tail == null;
507        /*inlined: ts.isEmpty() && ss.isEmpty();*/
508    }
509    // </editor-fold>
510 
511    // <editor-fold defaultstate="collapsed" desc="isSuperType">
512    /**
513     * Is t a supertype of s?
514     */
515    public boolean isSuperType(Type t, Type s) {
516        switch (t.tag) {
517        case ERROR:
518            return true;
519        case UNDETVAR: {
520            UndetVar undet = (UndetVar)t;
521            if (t == s ||
522                undet.qtype == s ||
523                s.tag == ERROR ||
524                s.tag == BOT) return true;
525            if (undet.inst != null)
526                return isSubtype(s, undet.inst);
527            undet.lobounds = undet.lobounds.prepend(s);
528            return true;
529        }
530        default:
531            return isSubtype(s, t);
532        }
533    }
534    // </editor-fold>
535 
536    // <editor-fold defaultstate="collapsed" desc="isSameType">
537    /**
538     * Are corresponding elements of the lists the same type?  If
539     * lists are of different length, return false.
540     */
541    public boolean isSameTypes(List<Type> ts, List<Type> ss) {
542        while (ts.tail != null && ss.tail != null
543               /*inlined: ts.nonEmpty() && ss.nonEmpty()*/ &&
544               isSameType(ts.head, ss.head)) {
545            ts = ts.tail;
546            ss = ss.tail;
547        }
548        return ts.tail == null && ss.tail == null;
549        /*inlined: ts.isEmpty() && ss.isEmpty();*/
550    }
551 
552    /**
553     * Is t the same type as s?
554     */
555    public boolean isSameType(Type t, Type s) {
556        return isSameType.visit(t, s);
557    }
558    // where
559        private TypeRelation isSameType = new TypeRelation() {
560 
561            public Boolean visitType(Type t, Type s) {
562                if (t == s)
563                    return true;
564 
565                if (s.tag >= firstPartialTag)
566                    return visit(s, t);
567 
568                switch (t.tag) {
569                case BYTE: case CHAR: case SHORT: case INT: case LONG: case FLOAT:
570                case DOUBLE: case BOOLEAN: case VOID: case BOT: case NONE:
571                    return t.tag == s.tag;
572                case TYPEVAR:
573                    return s.isSuperBound()
574                        && !s.isExtendsBound()
575                        && visit(t, upperBound(s));
576                default:
577                    throw new AssertionError("isSameType " + t.tag);
578                }
579            }
580 
581            @Override
582            public Boolean visitWildcardType(WildcardType t, Type s) {
583                if (s.tag >= firstPartialTag)
584                    return visit(s, t);
585                else
586                    return false;
587            }
588 
589            @Override
590            public Boolean visitClassType(ClassType t, Type s) {
591                if (t == s)
592                    return true;
593 
594                if (s.tag >= firstPartialTag)
595                    return visit(s, t);
596 
597                if (s.isSuperBound() && !s.isExtendsBound())
598                    return visit(t, upperBound(s)) && visit(t, lowerBound(s));
599 
600                if (t.isCompound() && s.isCompound()) {
601                    if (!visit(supertype(t), supertype(s)))
602                        return false;
603 
604                    HashSet<SingletonType> set = new HashSet<SingletonType>();
605                    for (Type x : interfaces(t))
606                        set.add(new SingletonType(x));
607                    for (Type x : interfaces(s)) {
608                        if (!set.remove(new SingletonType(x)))
609                            return false;
610                    }
611                    return (set.size() == 0);
612                }
613                return t.tsym == s.tsym
614                    && visit(t.getEnclosingType(), s.getEnclosingType())
615                    && containsTypeEquivalent(t.getTypeArguments(), s.getTypeArguments());
616            }
617 
618            @Override
619            public Boolean visitArrayType(ArrayType t, Type s) {
620                if (t == s)
621                    return true;
622 
623                if (s.tag >= firstPartialTag)
624                    return visit(s, t);
625 
626                return s.tag == ARRAY
627                    && containsTypeEquivalent(t.elemtype, elemtype(s));
628            }
629 
630            @Override
631            public Boolean visitMethodType(MethodType t, Type s) {
632                // isSameType for methods does not take thrown
633                // exceptions into account!
634                return hasSameArgs(t, s) && visit(t.getReturnType(), s.getReturnType());
635            }
636 
637            @Override
638            public Boolean visitPackageType(PackageType t, Type s) {
639                return t == s;
640            }
641 
642            @Override
643            public Boolean visitForAll(ForAll t, Type s) {
644                if (s.tag != FORALL)
645                    return false;
646 
647                ForAll forAll = (ForAll)s;
648                return hasSameBounds(t, forAll)
649                    && visit(t.qtype, subst(forAll.qtype, forAll.tvars, t.tvars));
650            }
651 
652            @Override
653            public Boolean visitUndetVar(UndetVar t, Type s) {
654                if (s.tag == WILDCARD)
655                    // FIXME, this might be leftovers from before capture conversion
656                    return false;
657 
658                if (t == s || t.qtype == s || s.tag == ERROR || s.tag == UNKNOWN)
659                    return true;
660 
661                if (t.inst != null)
662                    return visit(t.inst, s);
663 
664                t.inst = fromUnknownFun.apply(s);
665                for (List<Type> l = t.lobounds; l.nonEmpty(); l = l.tail) {
666                    if (!isSubtype(l.head, t.inst))
667                        return false;
668                }
669                for (List<Type> l = t.hibounds; l.nonEmpty(); l = l.tail) {
670                    if (!isSubtype(t.inst, l.head))
671                        return false;
672                }
673                return true;
674            }
675 
676            @Override
677            public Boolean visitErrorType(ErrorType t, Type s) {
678                return true;
679            }
680        };
681    // </editor-fold>
682 
683    // <editor-fold defaultstate="collapsed" desc="fromUnknownFun">
684    /**
685     * A mapping that turns all unknown types in this type to fresh
686     * unknown variables.
687     */
688    public Mapping fromUnknownFun = new Mapping("fromUnknownFun") {
689            public Type apply(Type t) {
690                if (t.tag == UNKNOWN) return new UndetVar(t);
691                else return t.map(this);
692            }
693        };
694    // </editor-fold>
695 
696    // <editor-fold defaultstate="collapsed" desc="Contains Type">
697    public boolean containedBy(Type t, Type s) {
698        switch (t.tag) {
699        case UNDETVAR:
700            if (s.tag == WILDCARD) {
701                UndetVar undetvar = (UndetVar)t;
702 
703                // Because of wildcard capture, s must be on the left
704                // hand side of an assignment.  Furthermore, t is an
705                // underconstrained type variable, for example, one
706                // that is only used in the return type of a method.
707                // If the type variable is truly underconstrained, it
708                // cannot have any low bounds:
709                assert undetvar.lobounds.isEmpty() : undetvar;
710 
711                undetvar.inst = glb(upperBound(s), undetvar.inst);
712                return true;
713            } else {
714                return isSameType(t, s);
715            }
716        case ERROR:
717            return true;
718        default:
719            return containsType(s, t);
720        }
721    }
722 
723    boolean containsType(List<Type> ts, List<Type> ss) {
724        while (ts.nonEmpty() && ss.nonEmpty()
725               && containsType(ts.head, ss.head)) {
726            ts = ts.tail;
727            ss = ss.tail;
728        }
729        return ts.isEmpty() && ss.isEmpty();
730    }
731 
732    /**
733     * Check if t contains s.
734     *
735     * <p>T contains S if:
736     *
737     * <p>{@code L(T) <: L(S) && U(S) <: U(T)}
738     *
739     * <p>This relation is only used by ClassType.isSubtype(), that
740     * is,
741     *
742     * <p>{@code C<S> <: C<T> if T contains S.}
743     *
744     * <p>Because of F-bounds, this relation can lead to infinite
745     * recursion.  Thus we must somehow break that recursion.  Notice
746     * that containsType() is only called from ClassType.isSubtype().
747     * Since the arguments have already been checked against their
748     * bounds, we know:
749     *
750     * <p>{@code U(S) <: U(T) if T is "super" bound (U(T) *is* the bound)}
751     *
752     * <p>{@code L(T) <: L(S) if T is "extends" bound (L(T) is bottom)}
753     *
754     * @param t a type
755     * @param s a type
756     */
757    public boolean containsType(Type t, Type s) {
758        return containsType.visit(t, s);
759    }
760    // where
761        private TypeRelation containsType = new TypeRelation() {
762 
763            private Type U(Type t) {
764                while (t.tag == WILDCARD) {
765                    WildcardType w = (WildcardType)t;
766                    if (w.isSuperBound())
767                        return w.bound == null ? syms.objectType : w.bound.bound;
768                    else
769                        t = w.type;
770                }
771                return t;
772            }
773 
774            private Type L(Type t) {
775                while (t.tag == WILDCARD) {
776                    WildcardType w = (WildcardType)t;
777                    if (w.isExtendsBound())
778                        return syms.botType;
779                    else
780                        t = w.type;
781                }
782                return t;
783            }
784 
785            public Boolean visitType(Type t, Type s) {
786                if (s.tag >= firstPartialTag)
787                    return containedBy(s, t);
788                else
789                    return isSameType(t, s);
790            }
791 
792            void debugContainsType(WildcardType t, Type s) {
793                System.err.println();
794                System.err.format(" does %s contain %s?%n", t, s);
795                System.err.format(" %s U(%s) <: U(%s) %s = %s%n",
796                                  upperBound(s), s, t, U(t),
797                                  t.isSuperBound()
798                                  || isSubtypeNoCapture(upperBound(s), U(t)));
799                System.err.format(" %s L(%s) <: L(%s) %s = %s%n",
800                                  L(t), t, s, lowerBound(s),
801                                  t.isExtendsBound()
802                                  || isSubtypeNoCapture(L(t), lowerBound(s)));
803                System.err.println();
804            }
805 
806            @Override
807            public Boolean visitWildcardType(WildcardType t, Type s) {
808                if (s.tag >= firstPartialTag)
809                    return containedBy(s, t);
810                else {
811                    // debugContainsType(t, s);
812                    return isSameWildcard(t, s)
813                        || isCaptureOf(s, t)
814                        || ((t.isExtendsBound() || isSubtypeNoCapture(L(t), lowerBound(s))) &&
815                            (t.isSuperBound() || isSubtypeNoCapture(upperBound(s), U(t))));
816                }
817            }
818 
819            @Override
820            public Boolean visitUndetVar(UndetVar t, Type s) {
821                if (s.tag != WILDCARD)
822                    return isSameType(t, s);
823                else
824                    return false;
825            }
826 
827            @Override
828            public Boolean visitErrorType(ErrorType t, Type s) {
829                return true;
830            }
831        };
832 
833    public boolean isCaptureOf(Type s, WildcardType t) {
834        if (s.tag != TYPEVAR || !(s instanceof CapturedType))
835            return false;
836        return isSameWildcard(t, ((CapturedType)s).wildcard);
837    }
838 
839    public boolean isSameWildcard(WildcardType t, Type s) {
840        if (s.tag != WILDCARD)
841            return false;
842        WildcardType w = (WildcardType)s;
843        return w.kind == t.kind && w.type == t.type;
844    }
845 
846    public boolean containsTypeEquivalent(List<Type> ts, List<Type> ss) {
847        while (ts.nonEmpty() && ss.nonEmpty()
848               && containsTypeEquivalent(ts.head, ss.head)) {
849            ts = ts.tail;
850            ss = ss.tail;
851        }
852        return ts.isEmpty() && ss.isEmpty();
853    }
854    // </editor-fold>
855 
856    // <editor-fold defaultstate="collapsed" desc="isCastable">
857    public boolean isCastable(Type t, Type s) {
858        return isCastable(t, s, Warner.noWarnings);
859    }
860 
861    /**
862     * Is t is castable to s?<br>
863     * s is assumed to be an erased type.<br>
864     * (not defined for Method and ForAll types).
865     */
866    public boolean isCastable(Type t, Type s, Warner warn) {
867        if (t == s)
868            return true;
869 
870        if (t.isPrimitive() != s.isPrimitive())
871            return allowBoxing && isConvertible(t, s, warn);
872 
873        if (warn != warnStack.head) {
874            try {
875                warnStack = warnStack.prepend(warn);
876                return isCastable.visit(t, s);
877            } finally {
878                warnStack = warnStack.tail;
879            }
880        } else {
881            return isCastable.visit(t, s);
882        }
883    }
884    // where
885        private TypeRelation isCastable = new TypeRelation() {
886 
887            public Boolean visitType(Type t, Type s) {
888                if (s.tag == ERROR)
889                    return true;
890 
891                switch (t.tag) {
892                case BYTE: case CHAR: case SHORT: case INT: case LONG: case FLOAT:
893                case DOUBLE:
894                    return s.tag <= DOUBLE;
895                case BOOLEAN:
896                    return s.tag == BOOLEAN;
897                case VOID:
898                    return false;
899                case BOT:
900                    return isSubtype(t, s);
901                default:
902                    throw new AssertionError();
903                }
904            }
905 
906            @Override
907            public Boolean visitWildcardType(WildcardType t, Type s) {
908                return isCastable(upperBound(t), s, warnStack.head);
909            }
910 
911            @Override
912            public Boolean visitClassType(ClassType t, Type s) {
913                if (s.tag == ERROR || s.tag == BOT)
914                    return true;
915 
916                if (s.tag == TYPEVAR) {
917                    if (isCastable(s.getUpperBound(), t, Warner.noWarnings)) {
918                        warnStack.head.warnUnchecked();
919                        return true;
920                    } else {
921                        return false;
922                    }
923                }
924 
925                if (t.isCompound()) {
926                    if (!visit(supertype(t), s))
927                        return false;
928                    for (Type intf : interfaces(t)) {
929                        if (!visit(intf, s))
930                            return false;
931                    }
932                    return true;
933                }
934 
935                if (s.isCompound()) {
936                    // call recursively to reuse the above code
937                    return visitClassType((ClassType)s, t);
938                }
939 
940                if (s.tag == CLASS || s.tag == ARRAY) {
941                    boolean upcast;
942                    if ((upcast = isSubtype(erasure(t), erasure(s)))
943                        || isSubtype(erasure(s), erasure(t))) {
944                        if (!upcast && s.tag == ARRAY) {
945                            if (!isReifiable(s))
946                                warnStack.head.warnUnchecked();
947                            return true;
948                        } else if (s.isRaw()) {
949                            return true;
950                        } else if (t.isRaw()) {
951                            if (!isUnbounded(s))
952                                warnStack.head.warnUnchecked();
953                            return true;
954                        }
955                        // Assume |a| <: |b|
956                        final Type a = upcast ? t : s;
957                        final Type b = upcast ? s : t;
958                        final boolean HIGH = true;
959                        final boolean LOW = false;
960                        final boolean DONT_REWRITE_TYPEVARS = false;
961                        Type aHigh = rewriteQuantifiers(a, HIGH, DONT_REWRITE_TYPEVARS);
962                        Type aLow  = rewriteQuantifiers(a, LOW,  DONT_REWRITE_TYPEVARS);
963                        Type bHigh = rewriteQuantifiers(b, HIGH, DONT_REWRITE_TYPEVARS);
964                        Type bLow  = rewriteQuantifiers(b, LOW,  DONT_REWRITE_TYPEVARS);
965                        Type lowSub = asSub(bLow, aLow.tsym);
966                        Type highSub = (lowSub == null) ? null : asSub(bHigh, aHigh.tsym);
967                        if (highSub == null) {
968                            final boolean REWRITE_TYPEVARS = true;
969                            aHigh = rewriteQuantifiers(a, HIGH, REWRITE_TYPEVARS);
970                            aLow  = rewriteQuantifiers(a, LOW,  REWRITE_TYPEVARS);
971                            bHigh = rewriteQuantifiers(b, HIGH, REWRITE_TYPEVARS);
972                            bLow  = rewriteQuantifiers(b, LOW,  REWRITE_TYPEVARS);
973                            lowSub = asSub(bLow, aLow.tsym);
974                            highSub = (lowSub == null) ? null : asSub(bHigh, aHigh.tsym);
975                        }
976                        if (highSub != null) {
977                            assert a.tsym == highSub.tsym && a.tsym == lowSub.tsym
978                                : a.tsym + " != " + highSub.tsym + " != " + lowSub.tsym;
979                            if (!disjointTypes(aHigh.getTypeArguments(), highSub.getTypeArguments())
980                                && !disjointTypes(aHigh.getTypeArguments(), lowSub.getTypeArguments())
981                                && !disjointTypes(aLow.getTypeArguments(), highSub.getTypeArguments())
982                                && !disjointTypes(aLow.getTypeArguments(), lowSub.getTypeArguments())) {
983                                if (upcast ? giveWarning(a, highSub) || giveWarning(a, lowSub)
984                                           : giveWarning(highSub, a) || giveWarning(lowSub, a))
985                                    warnStack.head.warnUnchecked();
986                                return true;
987                            }
988                        }
989                        if (isReifiable(s))
990                            return isSubtypeUnchecked(a, b);
991                        else
992                            return isSubtypeUnchecked(a, b, warnStack.head);
993                    }
994 
995                    // Sidecast
996                    if (s.tag == CLASS) {
997                        if ((s.tsym.flags() & INTERFACE) != 0) {
998                            return ((t.tsym.flags() & FINAL) == 0)
999                                ? sideCast(t, s, warnStack.head)
1000                                : sideCastFinal(t, s, warnStack.head);
1001                        } else if ((t.tsym.flags() & INTERFACE) != 0) {
1002                            return ((s.tsym.flags() & FINAL) == 0)
1003                                ? sideCast(t, s, warnStack.head)
1004                                : sideCastFinal(t, s, warnStack.head);
1005                        } else {
1006                            // unrelated class types
1007                            return false;
1008                        }
1009                    }
1010                }
1011                return false;
1012            }
1013 
1014            @Override
1015            public Boolean visitArrayType(ArrayType t, Type s) {
1016                switch (s.tag) {
1017                case ERROR:
1018                case BOT:
1019                    return true;
1020                case TYPEVAR:
1021                    if (isCastable(s, t, Warner.noWarnings)) {
1022                        warnStack.head.warnUnchecked();
1023                        return true;
1024                    } else {
1025                        return false;
1026                    }
1027                case CLASS:
1028                    return isSubtype(t, s);
1029                case ARRAY:
1030                    if (elemtype(t).tag <= lastBaseTag) {
1031                        return elemtype(t).tag == elemtype(s).tag;
1032                    } else {
1033                        return visit(elemtype(t), elemtype(s));
1034                    }
1035                default:
1036                    return false;
1037                }
1038            }
1039 
1040            @Override
1041            public Boolean visitTypeVar(TypeVar t, Type s) {
1042                switch (s.tag) {
1043                case ERROR:
1044                case BOT:
1045                    return true;
1046                case TYPEVAR:
1047                    if (isSubtype(t, s)) {
1048                        return true;
1049                    } else if (isCastable(t.bound, s, Warner.noWarnings)) {
1050                        warnStack.head.warnUnchecked();
1051                        return true;
1052                    } else {
1053                        return false;
1054                    }
1055                default:
1056                    return isCastable(t.bound, s, warnStack.head);
1057                }
1058            }
1059 
1060            @Override
1061            public Boolean visitErrorType(ErrorType t, Type s) {
1062                return true;
1063            }
1064        };
1065    // </editor-fold>
1066 
1067    // <editor-fold defaultstate="collapsed" desc="disjointTypes">
1068    public boolean disjointTypes(List<Type> ts, List<Type> ss) {
1069        while (ts.tail != null && ss.tail != null) {
1070            if (disjointType(ts.head, ss.head)) return true;
1071            ts = ts.tail;
1072            ss = ss.tail;
1073        }
1074        return false;
1075    }
1076 
1077    /**
1078     * Two types or wildcards are considered disjoint if it can be
1079     * proven that no type can be contained in both. It is
1080     * conservative in that it is allowed to say that two types are
1081     * not disjoint, even though they actually are.
1082     *
1083     * The type C<X> is castable to C<Y> exactly if X and Y are not
1084     * disjoint.
1085     */
1086    public boolean disjointType(Type t, Type s) {
1087        return disjointType.visit(t, s);
1088    }
1089    // where
1090        private TypeRelation disjointType = new TypeRelation() {
1091 
1092            private Set<TypePair> cache = new HashSet<TypePair>();
1093 
1094            public Boolean visitType(Type t, Type s) {
1095                if (s.tag == WILDCARD)
1096                    return visit(s, t);
1097                else
1098                    return notSoftSubtypeRecursive(t, s) || notSoftSubtypeRecursive(s, t);
1099            }
1100 
1101            private boolean isCastableRecursive(Type t, Type s) {
1102                TypePair pair = new TypePair(t, s);
1103                if (cache.add(pair)) {
1104                    try {
1105                        return Types.this.isCastable(t, s);
1106                    } finally {
1107                        cache.remove(pair);
1108                    }
1109                } else {
1110                    return true;
1111                }
1112            }
1113 
1114            private boolean notSoftSubtypeRecursive(Type t, Type s) {
1115                TypePair pair = new TypePair(t, s);
1116                if (cache.add(pair)) {
1117                    try {
1118                        return Types.this.notSoftSubtype(t, s);
1119                    } finally {
1120                        cache.remove(pair);
1121                    }
1122                } else {
1123                    return false;
1124                }
1125            }
1126 
1127            @Override
1128            public Boolean visitWildcardType(WildcardType t, Type s) {
1129                if (t.isUnbound())
1130                    return false;
1131 
1132                if (s.tag != WILDCARD) {
1133                    if (t.isExtendsBound())
1134                        return notSoftSubtypeRecursive(s, t.type);
1135                    else // isSuperBound()
1136                        return notSoftSubtypeRecursive(t.type, s);
1137                }
1138 
1139                if (s.isUnbound())
1140                    return false;
1141 
1142                if (t.isExtendsBound()) {
1143                    if (s.isExtendsBound())
1144                        return !isCastableRecursive(t.type, upperBound(s));
1145                    else if (s.isSuperBound())
1146                        return notSoftSubtypeRecursive(lowerBound(s), t.type);
1147                } else if (t.isSuperBound()) {
1148                    if (s.isExtendsBound())
1149                        return notSoftSubtypeRecursive(t.type, upperBound(s));
1150                }
1151                return false;
1152            }
1153        };
1154    // </editor-fold>
1155 
1156    // <editor-fold defaultstate="collapsed" desc="lowerBoundArgtypes">
1157    /**
1158     * Returns the lower bounds of the formals of a method.
1159     */
1160    public List<Type> lowerBoundArgtypes(Type t) {
1161        return map(t.getParameterTypes(), lowerBoundMapping);
1162    }
1163    private final Mapping lowerBoundMapping = new Mapping("lowerBound") {
1164            public Type apply(Type t) {
1165                return lowerBound(t);
1166            }
1167        };
1168    // </editor-fold>
1169 
1170    // <editor-fold defaultstate="collapsed" desc="notSoftSubtype">
1171    /**
1172     * This relation answers the question: is impossible that
1173     * something of type `t' can be a subtype of `s'? This is
1174     * different from the question "is `t' not a subtype of `s'?"
1175     * when type variables are involved: Integer is not a subtype of T
1176     * where <T extends Number> but it is not true that Integer cannot
1177     * possibly be a subtype of T.
1178     */
1179    public boolean notSoftSubtype(Type t, Type s) {
1180        if (t == s) return false;
1181        if (t.tag == TYPEVAR) {
1182            TypeVar tv = (TypeVar) t;
1183            if (s.tag == TYPEVAR)
1184                s = s.getUpperBound();
1185            return !isCastable(tv.bound,
1186                               s,
1187                               Warner.noWarnings);
1188        }
1189        if (s.tag != WILDCARD)
1190            s = upperBound(s);
1191        if (s.tag == TYPEVAR)
1192            s = s.getUpperBound();
1193        return !isSubtype(t, s);
1194    }
1195    // </editor-fold>
1196 
1197    // <editor-fold defaultstate="collapsed" desc="isReifiable">
1198    public boolean isReifiable(Type t) {
1199        return isReifiable.visit(t);
1200    }
1201    // where
1202        private UnaryVisitor<Boolean> isReifiable = new UnaryVisitor<Boolean>() {
1203 
1204            public Boolean visitType(Type t, Void ignored) {
1205                return true;
1206            }
1207 
1208            @Override
1209            public Boolean visitClassType(ClassType t, Void ignored) {
1210                if (!t.isParameterized())
1211                    return true;
1212 
1213                for (Type param : t.allparams()) {
1214                    if (!param.isUnbound())
1215                        return false;
1216                }
1217                return true;
1218            }
1219 
1220            @Override
1221            public Boolean visitArrayType(ArrayType t, Void ignored) {
1222                return visit(t.elemtype);
1223            }
1224 
1225            @Override
1226            public Boolean visitTypeVar(TypeVar t, Void ignored) {
1227                return false;
1228            }
1229        };
1230    // </editor-fold>
1231 
1232    // <editor-fold defaultstate="collapsed" desc="Array Utils">
1233    public boolean isArray(Type t) {
1234        while (t.tag == WILDCARD)
1235            t = upperBound(t);
1236        return t.tag == ARRAY;
1237    }
1238 
1239    /**
1240     * The element type of an array.
1241     */
1242    public Type elemtype(Type t) {
1243        switch (t.tag) {
1244        case WILDCARD:
1245            return elemtype(upperBound(t));
1246        case ARRAY:
1247            return ((ArrayType)t).elemtype;
1248        case FORALL:
1249            return elemtype(((ForAll)t).qtype);
1250        case ERROR:
1251            return t;
1252        default:
1253            return null;
1254        }
1255    }
1256 
1257    /**
1258     * Mapping to take element type of an arraytype
1259     */
1260    private Mapping elemTypeFun = new Mapping ("elemTypeFun") {
1261        public Type apply(Type t) { return elemtype(t); }
1262    };
1263 
1264    /**
1265     * The number of dimensions of an array type.
1266     */
1267    public int dimensions(Type t) {
1268        int result = 0;
1269        while (t.tag == ARRAY) {
1270            result++;
1271            t = elemtype(t);
1272        }
1273        return result;
1274    }
1275    // </editor-fold>
1276 
1277    // <editor-fold defaultstate="collapsed" desc="asSuper">
1278    /**
1279     * Return the (most specific) base type of t that starts with the
1280     * given symbol.  If none exists, return null.
1281     *
1282     * @param t a type
1283     * @param sym a symbol
1284     */
1285    public Type asSuper(Type t, Symbol sym) {
1286        return asSuper.visit(t, sym);
1287    }
1288    // where
1289        private SimpleVisitor<Type,Symbol> asSuper = new SimpleVisitor<Type,Symbol>() {
1290 
1291            public Type visitType(Type t, Symbol sym) {
1292                return null;
1293            }
1294 
1295            @Override
1296            public Type visitClassType(ClassType t, Symbol sym) {
1297                if (t.tsym == sym)
1298                    return t;
1299 
1300                Type st = supertype(t);
1301                if (st.tag == CLASS || st.tag == ERROR) {
1302                    Type x = asSuper(st, sym);
1303                    if (x != null)
1304                        return x;
1305                }
1306                if ((sym.flags() & INTERFACE) != 0) {
1307                    for (List<Type> l = interfaces(t); l.nonEmpty(); l = l.tail) {
1308                        Type x = asSuper(l.head, sym);
1309                        if (x != null)
1310                            return x;
1311                    }
1312                }
1313                return null;
1314            }
1315 
1316            @Override
1317            public Type visitArrayType(ArrayType t, Symbol sym) {
1318                return isSubtype(t, sym.type) ? sym.type : null;
1319            }
1320 
1321            @Override
1322            public Type visitTypeVar(TypeVar t, Symbol sym) {
1323                return asSuper(t.bound, sym);
1324            }
1325 
1326            @Override
1327            public Type visitErrorType(ErrorType t, Symbol sym) {
1328                return t;
1329            }
1330        };
1331 
1332    /**
1333     * Return the base type of t or any of its outer types that starts
1334     * with the given symbol.  If none exists, return null.
1335     *
1336     * @param t a type
1337     * @param sym a symbol
1338     */
1339    public Type asOuterSuper(Type t, Symbol sym) {
1340        switch (t.tag) {
1341        case CLASS:
1342            do {
1343                Type s = asSuper(t, sym);
1344                if (s != null) return s;
1345                t = t.getEnclosingType();
1346            } while (t.tag == CLASS);
1347            return null;
1348        case ARRAY:
1349            return isSubtype(t, sym.type) ? sym.type : null;
1350        case TYPEVAR:
1351            return asSuper(t, sym);
1352        case ERROR:
1353            return t;
1354        default:
1355            return null;
1356        }
1357    }
1358 
1359    /**
1360     * Return the base type of t or any of its enclosing types that
1361     * starts with the given symbol.  If none exists, return null.
1362     *
1363     * @param t a type
1364     * @param sym a symbol
1365     */
1366    public Type asEnclosingSuper(Type t, Symbol sym) {
1367        switch (t.tag) {
1368        case CLASS:
1369            do {
1370                Type s = asSuper(t, sym);
1371                if (s != null) return s;
1372                Type outer = t.getEnclosingType();
1373                t = (outer.tag == CLASS) ? outer :
1374                    (t.tsym.owner.enclClass() != null) ? t.tsym.owner.enclClass().type :
1375                    Type.noType;
1376            } while (t.tag == CLASS);
1377            return null;
1378        case ARRAY:
1379            return isSubtype(t, sym.type) ? sym.type : null;
1380        case TYPEVAR:
1381            return asSuper(t, sym);
1382        case ERROR:
1383            return t;
1384        default:
1385            return null;
1386        }
1387    }
1388    // </editor-fold>
1389 
1390    // <editor-fold defaultstate="collapsed" desc="memberType">
1391    /**
1392     * The type of given symbol, seen as a member of t.
1393     *
1394     * @param t a type
1395     * @param sym a symbol
1396     */
1397    public Type memberType(Type t, Symbol sym) {
1398        return (sym.flags() & STATIC) != 0
1399            ? sym.type
1400            : memberType.visit(t, sym);
1401    }
1402    // where
1403        private SimpleVisitor<Type,Symbol> memberType = new SimpleVisitor<Type,Symbol>() {
1404 
1405            public Type visitType(Type t, Symbol sym) {
1406                return sym.type;
1407            }
1408 
1409            @Override
1410            public Type visitWildcardType(WildcardType t, Symbol sym) {
1411                return memberType(upperBound(t), sym);
1412            }
1413 
1414            @Override
1415            public Type visitClassType(ClassType t, Symbol sym) {
1416                Symbol owner = sym.owner;
1417                long flags = sym.flags();
1418                if (((flags & STATIC) == 0) && owner.type.isParameterized()) {
1419                    Type base = asOuterSuper(t, owner);
1420                    if (base != null) {
1421                        List<Type> ownerParams = owner.type.allparams();
1422                        List<Type> baseParams = base.allparams();
1423                        if (ownerParams.nonEmpty()) {
1424                            if (baseParams.isEmpty()) {
1425                                // then base is a raw type
1426                                return erasure(sym.type);
1427                            } else {
1428                                return subst(sym.type, ownerParams, baseParams);
1429                            }
1430                        }
1431                    }
1432                }
1433                return sym.type;
1434            }
1435 
1436            @Override
1437            public Type visitTypeVar(TypeVar t, Symbol sym) {
1438                return memberType(t.bound, sym);
1439            }
1440 
1441            @Override
1442            public Type visitErrorType(ErrorType t, Symbol sym) {
1443                return t;
1444            }
1445        };
1446    // </editor-fold>
1447 
1448    // <editor-fold defaultstate="collapsed" desc="isAssignable">
1449    public boolean isAssignable(Type t, Type s) {
1450        return isAssignable(t, s, Warner.noWarnings);
1451    }
1452 
1453    /**
1454     * Is t assignable to s?<br>
1455     * Equivalent to subtype except for constant values and raw
1456     * types.<br>
1457     * (not defined for Method and ForAll types)
1458     */
1459    public boolean isAssignable(Type t, Type s, Warner warn) {
1460        if (t.tag == ERROR)
1461            return true;
1462        if (t.tag <= INT && t.constValue() != null) {
1463            int value = ((Number)t.constValue()).intValue();
1464            switch (s.tag) {
1465            case BYTE:
1466                if (Byte.MIN_VALUE <= value && value <= Byte.MAX_VALUE)
1467                    return true;
1468                break;
1469            case CHAR:
1470                if (Character.MIN_VALUE <= value && value <= Character.MAX_VALUE)
1471                    return true;
1472                break;
1473            case SHORT:
1474                if (Short.MIN_VALUE <= value && value <= Short.MAX_VALUE)
1475                    return true;
1476                break;
1477            case INT:
1478                return true;
1479            case CLASS:
1480                switch (unboxedType(s).tag) {
1481                case BYTE:
1482                case CHAR:
1483                case SHORT:
1484                    return isAssignable(t, unboxedType(s), warn);
1485                }
1486                break;
1487            }
1488        }
1489        return isConvertible(t, s, warn);
1490    }
1491    // </editor-fold>
1492 
1493    // <editor-fold defaultstate="collapsed" desc="erasure">
1494    /**
1495     * The erasure of t {@code |t|} -- the type that results when all
1496     * type parameters in t are deleted.
1497     */
1498    public Type erasure(Type t) {
1499        if (t.tag <= lastBaseTag)
1500            return t; /* fast special case */
1501        else
1502            return erasure.visit(t);
1503    }
1504    // where
1505        private UnaryVisitor<Type> erasure = new UnaryVisitor<Type>() {
1506            public Type visitType(Type t, Void ignored) {
1507                if (t.tag <= lastBaseTag)
1508                    return t; /*fast special case*/
1509                else
1510                    return t.map(erasureFun);
1511            }
1512 
1513            @Override
1514            public Type visitWildcardType(WildcardType t, Void ignored) {
1515                return erasure(upperBound(t));
1516            }
1517 
1518            @Override
1519            public Type visitClassType(ClassType t, Void ignored) {
1520                return t.tsym.erasure(Types.this);
1521            }
1522 
1523            @Override
1524            public Type visitTypeVar(TypeVar t, Void ignored) {
1525                return erasure(t.bound);
1526            }
1527 
1528            @Override
1529            public Type visitErrorType(ErrorType t, Void ignored) {
1530                return t;
1531            }
1532        };
1533    private Mapping erasureFun = new Mapping ("erasure") {
1534            public Type apply(Type t) { return erasure(t); }
1535        };
1536 
1537    public List<Type> erasure(List<Type> ts) {
1538        return Type.map(ts, erasureFun);
1539    }
1540    // </editor-fold>
1541 
1542    // <editor-fold defaultstate="collapsed" desc="makeCompoundType">
1543    /**
1544     * Make a compound type from non-empty list of types
1545     *
1546     * @param bounds            the types from which the compound type is formed
1547     * @param supertype         is objectType if all bounds are interfaces,
1548     *                          null otherwise.
1549     */
1550    public Type makeCompoundType(List<Type> bounds,
1551                                 Type supertype) {
1552        ClassSymbol bc =
1553            new ClassSymbol(ABSTRACT|PUBLIC|SYNTHETIC|COMPOUND|ACYCLIC,
1554                            Type.moreInfo
1555                                ? names.fromString(bounds.toString())
1556                                : names.empty,
1557                            syms.noSymbol);
1558        if (bounds.head.tag == TYPEVAR)
1559            // error condition, recover
1560            bc.erasure_field = syms.objectType;
1561        else
1562            bc.erasure_field = erasure(bounds.head);
1563        bc.members_field = new Scope(bc);
1564        ClassType bt = (ClassType)bc.type;
1565        bt.allparams_field = List.nil();
1566        if (supertype != null) {
1567            bt.supertype_field = supertype;
1568            bt.interfaces_field = bounds;
1569        } else {
1570            bt.supertype_field = bounds.head;
1571            bt.interfaces_field = bounds.tail;
1572        }
1573        assert bt.supertype_field.tsym.completer != null
1574            || !bt.supertype_field.isInterface()
1575            : bt.supertype_field;
1576        return bt;
1577    }
1578 
1579    /**
1580     * Same as {@link #makeCompoundType(List,Type)}, except that the
1581     * second parameter is computed directly. Note that this might
1582     * cause a symbol completion.  Hence, this version of
1583     * makeCompoundType may not be called during a classfile read.
1584     */
1585    public Type makeCompoundType(List<Type> bounds) {
1586        Type supertype = (bounds.head.tsym.flags() & INTERFACE) != 0 ?
1587            supertype(bounds.head) : null;
1588        return makeCompoundType(bounds, supertype);
1589    }
1590 
1591    /**
1592     * A convenience wrapper for {@link #makeCompoundType(List)}; the
1593     * arguments are converted to a list and passed to the other
1594     * method.  Note that this might cause a symbol completion.
1595     * Hence, this version of makeCompoundType may not be called
1596     * during a classfile read.
1597     */
1598    public Type makeCompoundType(Type bound1, Type bound2) {
1599        return makeCompoundType(List.of(bound1, bound2));
1600    }
1601    // </editor-fold>
1602 
1603    // <editor-fold defaultstate="collapsed" desc="supertype">
1604    public Type supertype(Type t) {
1605        return supertype.visit(t);
1606    }
1607    // where
1608        private UnaryVisitor<Type> supertype = new UnaryVisitor<Type>() {
1609 
1610            public Type visitType(Type t, Void ignored) {
1611                // A note on wildcards: there is no good way to
1612                // determine a supertype for a super bounded wildcard.
1613                return null;
1614            }
1615 
1616            @Override
1617            public Type visitClassType(ClassType t, Void ignored) {
1618                if (t.supertype_field == null) {
1619                    Type supertype = ((ClassSymbol)t.tsym).getSuperclass();
1620                    // An interface has no superclass; its supertype is Object.
1621                    if (t.isInterface())
1622                        supertype = ((ClassType)t.tsym.type).supertype_field;
1623                    if (t.supertype_field == null) {
1624                        List<Type> actuals = classBound(t).allparams();
1625                        List<Type> formals = t.tsym.type.allparams();
1626                        if (actuals.isEmpty()) {
1627                            if (formals.isEmpty())
1628                                // Should not happen.  See comments below in interfaces
1629                                t.supertype_field = supertype;
1630                            else
1631                                t.supertype_field = erasure(supertype);
1632                        } else {
1633                            t.supertype_field = subst(supertype, formals, actuals);
1634                        }
1635                    }
1636                }
1637                return t.supertype_field;
1638            }
1639 
1640            /**
1641             * The supertype is always a class type. If the type
1642             * variable's bounds start with a class type, this is also
1643             * the supertype.  Otherwise, the supertype is
1644             * java.lang.Object.
1645             */
1646            @Override
1647            public Type visitTypeVar(TypeVar t, Void ignored) {
1648                if (t.bound.tag == TYPEVAR ||
1649                    (!t.bound.isCompound() && !t.bound.isInterface())) {
1650                    return t.bound;
1651                } else {
1652                    return supertype(t.bound);
1653                }
1654            }
1655 
1656            @Override
1657            public Type visitArrayType(ArrayType t, Void ignored) {
1658                if (t.elemtype.isPrimitive() || isSameType(t.elemtype, syms.objectType))
1659                    return arraySuperType();
1660                else
1661                    return new ArrayType(supertype(t.elemtype), t.tsym);
1662            }
1663 
1664            @Override
1665            public Type visitErrorType(ErrorType t, Void ignored) {
1666                return t;
1667            }
1668        };
1669    // </editor-fold>
1670 
1671    // <editor-fold defaultstate="collapsed" desc="interfaces">
1672    /**
1673     * Return the interfaces implemented by this class.
1674     */
1675    public List<Type> interfaces(Type t) {
1676        return interfaces.visit(t);
1677    }
1678    // where
1679        private UnaryVisitor<List<Type>> interfaces = new UnaryVisitor<List<Type>>() {
1680 
1681            public List<Type> visitType(Type t, Void ignored) {
1682                return List.nil();
1683            }
1684 
1685            @Override
1686            public List<Type> visitClassType(ClassType t, Void ignored) {
1687                if (t.interfaces_field == null) {
1688                    List<Type> interfaces = ((ClassSymbol)t.tsym).getInterfaces();
1689                    if (t.interfaces_field == null) {
1690                        // If t.interfaces_field is null, then t must
1691                        // be a parameterized type (not to be confused
1692                        // with a generic type declaration).
1693                        // Terminology:
1694                        //    Parameterized type: List<String>
1695                        //    Generic type declaration: class List<E> { ... }
1696                        // So t corresponds to List<String> and
1697                        // t.tsym.type corresponds to List<E>.
1698                        // The reason t must be parameterized type is
1699                        // that completion will happen as a side
1700                        // effect of calling
1701                        // ClassSymbol.getInterfaces.  Since
1702                        // t.interfaces_field is null after
1703                        // completion, we can assume that t is not the
1704                        // type of a class/interface declaration.
1705                        assert t != t.tsym.type : t.toString();
1706                        List<Type> actuals = t.allparams();
1707                        List<Type> formals = t.tsym.type.allparams();
1708                        if (actuals.isEmpty()) {
1709                            if (formals.isEmpty()) {
1710                                // In this case t is not generic (nor raw).
1711                                // So this should not happen.
1712                                t.interfaces_field = interfaces;
1713                            } else {
1714                                t.interfaces_field = erasure(interfaces);
1715                            }
1716                        } else {
1717                            t.interfaces_field =
1718                                upperBounds(subst(interfaces, formals, actuals));
1719                        }
1720                    }
1721                }
1722                return t.interfaces_field;
1723            }
1724 
1725            @Override
1726            public List<Type> visitTypeVar(TypeVar t, Void ignored) {
1727                if (t.bound.isCompound())
1728                    return interfaces(t.bound);
1729 
1730                if (t.bound.isInterface())
1731                    return List.of(t.bound);
1732 
1733                return List.nil();
1734            }
1735        };
1736    // </editor-fold>
1737 
1738    // <editor-fold defaultstate="collapsed" desc="isDerivedRaw">
1739    Map<Type,Boolean> isDerivedRawCache = new HashMap<Type,Boolean>();
1740 
1741    public boolean isDerivedRaw(Type t) {
1742        Boolean result = isDerivedRawCache.get(t);
1743        if (result == null) {
1744            result = isDerivedRawInternal(t);
1745            isDerivedRawCache.put(t, result);
1746        }
1747        return result;
1748    }
1749 
1750    public boolean isDerivedRawInternal(Type t) {
1751        if (t.isErroneous())
1752            return false;
1753        return
1754            t.isRaw() ||
1755            supertype(t) != null && isDerivedRaw(supertype(t)) ||
1756            isDerivedRaw(interfaces(t));
1757    }
1758 
1759    public boolean isDerivedRaw(List<Type> ts) {
1760        List<Type> l = ts;
1761        while (l.nonEmpty() && !isDerivedRaw(l.head)) l = l.tail;
1762        return l.nonEmpty();
1763    }
1764    // </editor-fold>
1765 
1766    // <editor-fold defaultstate="collapsed" desc="setBounds">
1767    /**
1768     * Set the bounds field of the given type variable to reflect a
1769     * (possibly multiple) list of bounds.
1770     * @param t                 a type variable
1771     * @param bounds            the bounds, must be nonempty
1772     * @param supertype         is objectType if all bounds are interfaces,
1773     *                          null otherwise.
1774     */
1775    public void setBounds(TypeVar t, List<Type> bounds, Type supertype) {
1776        if (bounds.tail.isEmpty())
1777            t.bound = bounds.head;
1778        else
1779            t.bound = makeCompoundType(bounds, supertype);
1780        t.rank_field = -1;
1781    }
1782 
1783    /**
1784     * Same as {@link #setBounds(Type.TypeVar,List,Type)}, except that
1785     * third parameter is computed directly.  Note that this test
1786     * might cause a symbol completion.  Hence, this version of
1787     * setBounds may not be called during a classfile read.
1788     */
1789    public void setBounds(TypeVar t, List<Type> bounds) {
1790        Type supertype = (bounds.head.tsym.flags() & INTERFACE) != 0 ?
1791            supertype(bounds.head) : null;
1792        setBounds(t, bounds, supertype);
1793        t.rank_field = -1;
1794    }
1795    // </editor-fold>
1796 
1797    // <editor-fold defaultstate="collapsed" desc="getBounds">
1798    /**
1799     * Return list of bounds of the given type variable.
1800     */
1801    public List<Type> getBounds(TypeVar t) {
1802        if (t.bound.isErroneous() || !t.bound.isCompound())
1803            return List.of(t.bound);
1804        else if ((erasure(t).tsym.flags() & INTERFACE) == 0)
1805            return interfaces(t).prepend(supertype(t));
1806        else
1807            // No superclass was given in bounds.
1808            // In this case, supertype is Object, erasure is first interface.
1809            return interfaces(t);
1810    }
1811    // </editor-fold>
1812 
1813    // <editor-fold defaultstate="collapsed" desc="classBound">
1814    /**
1815     * If the given type is a (possibly selected) type variable,
1816     * return the bounding class of this type, otherwise return the
1817     * type itself.
1818     */
1819    public Type classBound(Type t) {
1820        return classBound.visit(t);
1821    }
1822    // where
1823        private UnaryVisitor<Type> classBound = new UnaryVisitor<Type>() {
1824 
1825            public Type visitType(Type t, Void ignored) {
1826                return t;
1827            }
1828 
1829            @Override
1830            public Type visitClassType(ClassType t, Void ignored) {
1831                Type outer1 = classBound(t.getEnclosingType());
1832                if (outer1 != t.getEnclosingType())
1833                    return new ClassType(outer1, t.getTypeArguments(), t.tsym);
1834                else
1835                    return t;
1836            }
1837 
1838            @Override
1839            public Type visitTypeVar(TypeVar t, Void ignored) {
1840                return classBound(supertype(t));
1841            }
1842 
1843            @Override
1844            public Type visitErrorType(ErrorType t, Void ignored) {
1845                return t;
1846            }
1847        };
1848    // </editor-fold>
1849 
1850    // <editor-fold defaultstate="collapsed" desc="sub signature / override equivalence">
1851    /**
1852     * Returns true iff the first signature is a <em>sub
1853     * signature</em> of the other.  This is <b>not</b> an equivalence
1854     * relation.
1855     *
1856     * @see "The Java Language Specification, Third Ed. (8.4.2)."
1857     * @see #overrideEquivalent(Type t, Type s)
1858     * @param t first signature (possibly raw).
1859     * @param s second signature (could be subjected to erasure).
1860     * @return true if t is a sub signature of s.
1861     */
1862    public boolean isSubSignature(Type t, Type s) {
1863        return hasSameArgs(t, s) || hasSameArgs(t, erasure(s));
1864    }
1865 
1866    /**
1867     * Returns true iff these signatures are related by <em>override
1868     * equivalence</em>.  This is the natural extension of
1869     * isSubSignature to an equivalence relation.
1870     *
1871     * @see "The Java Language Specification, Third Ed. (8.4.2)."
1872     * @see #isSubSignature(Type t, Type s)
1873     * @param t a signature (possible raw, could be subjected to
1874     * erasure).
1875     * @param s a signature (possible raw, could be subjected to
1876     * erasure).
1877     * @return true if either argument is a sub signature of the other.
1878     */
1879    public boolean overrideEquivalent(Type t, Type s) {
1880        return hasSameArgs(t, s) ||
1881            hasSameArgs(t, erasure(s)) || hasSameArgs(erasure(t), s);
1882    }
1883 
1884    /**
1885     * Does t have the same arguments as s?  It is assumed that both
1886     * types are (possibly polymorphic) method types.  Monomorphic
1887     * method types "have the same arguments", if their argument lists
1888     * are equal.  Polymorphic method types "have the same arguments",
1889     * if they have the same arguments after renaming all type
1890     * variables of one to corresponding type variables in the other,
1891     * where correspondence is by position in the type parameter list.
1892     */
1893    public boolean hasSameArgs(Type t, Type s) {
1894        return hasSameArgs.visit(t, s);
1895    }
1896    // where
1897        private TypeRelation hasSameArgs = new TypeRelation() {
1898 
1899            public Boolean visitType(Type t, Type s) {
1900                throw new AssertionError();
1901            }
1902 
1903            @Override
1904            public Boolean visitMethodType(MethodType t, Type s) {
1905                return s.tag == METHOD
1906                    && containsTypeEquivalent(t.argtypes, s.getParameterTypes());
1907            }
1908 
1909            @Override
1910            public Boolean visitForAll(ForAll t, Type s) {
1911                if (s.tag != FORALL)
1912                    return false;
1913 
1914                ForAll forAll = (ForAll)s;
1915                return hasSameBounds(t, forAll)
1916                    && visit(t.qtype, subst(forAll.qtype, forAll.tvars, t.tvars));
1917            }
1918 
1919            @Override
1920            public Boolean visitErrorType(ErrorType t, Type s) {
1921                return false;
1922            }
1923        };
1924    // </editor-fold>
1925 
1926    // <editor-fold defaultstate="collapsed" desc="subst">
1927    public List<Type> subst(List<Type> ts,
1928                            List<Type> from,
1929                            List<Type> to) {
1930        return new Subst(from, to).subst(ts);
1931    }
1932 
1933    /**
1934     * Substitute all occurrences of a type in `from' with the
1935     * corresponding type in `to' in 't'. Match lists `from' and `to'
1936     * from the right: If lists have different length, discard leading
1937     * elements of the longer list.
1938     */
1939    public Type subst(Type t, List<Type> from, List<Type> to) {
1940        return new Subst(from, to).subst(t);
1941    }
1942 
1943    private class Subst extends UnaryVisitor<Type> {
1944        List<Type> from;
1945        List<Type> to;
1946 
1947        public Subst(List<Type> from, List<Type> to) {
1948            int fromLength = from.length();
1949            int toLength = to.length();
1950            while (fromLength > toLength) {
1951                fromLength--;
1952                from = from.tail;
1953            }
1954            while (fromLength < toLength) {
1955                toLength--;
1956                to = to.tail;
1957            }
1958            this.from = from;
1959            this.to = to;
1960        }
1961 
1962        Type subst(Type t) {
1963            if (from.tail == null)
1964                return t;
1965            else
1966                return visit(t);
1967        }
1968 
1969        List<Type> subst(List<Type> ts) {
1970            if (from.tail == null)
1971                return ts;
1972            boolean wild = false;
1973            if (ts.nonEmpty() && from.nonEmpty()) {
1974                Type head1 = subst(ts.head);
1975                List<Type> tail1 = subst(ts.tail);
1976                if (head1 != ts.head || tail1 != ts.tail)
1977                    return tail1.prepend(head1);
1978            }
1979            return ts;
1980        }
1981 
1982        public Type visitType(Type t, Void ignored) {
1983            return t;
1984        }
1985 
1986        @Override
1987        public Type visitMethodType(MethodType t, Void ignored) {
1988            List<Type> argtypes = subst(t.argtypes);
1989            Type restype = subst(t.restype);
1990            List<Type> thrown = subst(t.thrown);
1991            if (argtypes == t.argtypes &&
1992                restype == t.restype &&
1993                thrown == t.thrown)
1994                return t;
1995            else
1996                return new MethodType(argtypes, restype, thrown, t.tsym);
1997        }
1998 
1999        @Override
2000        public Type visitTypeVar(TypeVar t, Void ignored) {
2001            for (List<Type> from = this.from, to = this.to;
2002                 from.nonEmpty();
2003                 from = from.tail, to = to.tail) {
2004                if (t == from.head) {
2005                    return to.head.withTypeVar(t);
2006                }
2007            }
2008            return t;
2009        }
2010 
2011        @Override
2012        public Type visitClassType(ClassType t, Void ignored) {
2013            if (!t.isCompound()) {
2014                List<Type> typarams = t.getTypeArguments();
2015                List<Type> typarams1 = subst(typarams);
2016                Type outer = t.getEnclosingType();
2017                Type outer1 = subst(outer);
2018                if (typarams1 == typarams && outer1 == outer)
2019                    return t;
2020                else
2021                    return new ClassType(outer1, typarams1, t.tsym);
2022            } else {
2023                Type st = subst(supertype(t));
2024                List<Type> is = upperBounds(subst(interfaces(t)));
2025                if (st == supertype(t) && is == interfaces(t))
2026                    return t;
2027                else
2028                    return makeCompoundType(is.prepend(st));
2029            }
2030        }
2031 
2032        @Override
2033        public Type visitWildcardType(WildcardType t, Void ignored) {
2034            Type bound = t.type;
2035            if (t.kind != BoundKind.UNBOUND)
2036                bound = subst(bound);
2037            if (bound == t.type) {
2038                return t;
2039            } else {
2040                if (t.isExtendsBound() && bound.isExtendsBound())
2041                    bound = upperBound(bound);
2042                return new WildcardType(bound, t.kind, syms.boundClass, t.bound);
2043            }
2044        }
2045 
2046        @Override
2047        public Type visitArrayType(ArrayType t, Void ignored) {
2048            Type elemtype = subst(t.elemtype);
2049            if (elemtype == t.elemtype)
2050                return t;
2051            else
2052                return new ArrayType(upperBound(elemtype), t.tsym);
2053        }
2054 
2055        @Override
2056        public Type visitForAll(ForAll t, Void ignored) {
2057            List<Type> tvars1 = substBounds(t.tvars, from, to);
2058            Type qtype1 = subst(t.qtype);
2059            if (tvars1 == t.tvars && qtype1 == t.qtype) {
2060                return t;
2061            } else if (tvars1 == t.tvars) {
2062                return new ForAll(tvars1, qtype1);
2063            } else {
2064                return new ForAll(tvars1, Types.this.subst(qtype1, t.tvars, tvars1));
2065            }
2066        }
2067 
2068        @Override
2069        public Type visitErrorType(ErrorType t, Void ignored) {
2070            return t;
2071        }
2072    }
2073 
2074    public List<Type> substBounds(List<Type> tvars,
2075                                  List<Type> from,
2076                                  List<Type> to) {
2077        if (tvars.isEmpty())
2078            return tvars;
2079        if (tvars.tail.isEmpty())
2080            // fast common case
2081            return List.<Type>of(substBound((TypeVar)tvars.head, from, to));
2082        ListBuffer<Type> newBoundsBuf = lb();
2083        boolean changed = false;
2084        // calculate new bounds
2085        for (Type t : tvars) {
2086            TypeVar tv = (TypeVar) t;
2087            Type bound = subst(tv.bound, from, to);
2088            if (bound != tv.bound)
2089                changed = true;
2090            newBoundsBuf.append(bound);
2091        }
2092        if (!changed)
2093            return tvars;
2094        ListBuffer<Type> newTvars = lb();
2095        // create new type variables without bounds
2096        for (Type t : tvars) {
2097            newTvars.append(new TypeVar(t.tsym, null, syms.botType));
2098        }
2099        // the new bounds should use the new type variables in place
2100        // of the old
2101        List<Type> newBounds = newBoundsBuf.toList();
2102        from = tvars;
2103        to = newTvars.toList();
2104        for (; !newBounds.isEmpty(); newBounds = newBounds.tail) {
2105            newBounds.head = subst(newBounds.head, from, to);
2106        }
2107        newBounds = newBoundsBuf.toList();
2108        // set the bounds of new type variables to the new bounds
2109        for (Type t : newTvars.toList()) {
2110            TypeVar tv = (TypeVar) t;
2111            tv.bound = newBounds.head;
2112            newBounds = newBounds.tail;
2113        }
2114        return newTvars.toList();
2115    }
2116 
2117    public TypeVar substBound(TypeVar t, List<Type> from, List<Type> to) {
2118        Type bound1 = subst(t.bound, from, to);
2119        if (bound1 == t.bound)
2120            return t;
2121        else
2122            return new TypeVar(t.tsym, bound1, syms.botType);
2123    }
2124    // </editor-fold>
2125 
2126    // <editor-fold defaultstate="collapsed" desc="hasSameBounds">
2127    /**
2128     * Does t have the same bounds for quantified variables as s?
2129     */
2130    boolean hasSameBounds(ForAll t, ForAll s) {
2131        List<Type> l1 = t.tvars;
2132        List<Type> l2 = s.tvars;
2133        while (l1.nonEmpty() && l2.nonEmpty() &&
2134               isSameType(l1.head.getUpperBound(),
2135                          subst(l2.head.getUpperBound(),
2136                                s.tvars,
2137                                t.tvars))) {
2138            l1 = l1.tail;
2139            l2 = l2.tail;
2140        }
2141        return l1.isEmpty() && l2.isEmpty();
2142    }
2143    // </editor-fold>
2144 
2145    // <editor-fold defaultstate="collapsed" desc="newInstances">
2146    /** Create new vector of type variables from list of variables
2147     *  changing all recursive bounds from old to new list.
2148     */
2149    public List<Type> newInstances(List<Type> tvars) {
2150        List<Type> tvars1 = Type.map(tvars, newInstanceFun);
2151        for (List<Type> l = tvars1; l.nonEmpty(); l = l.tail) {
2152            TypeVar tv = (TypeVar) l.head;
2153            tv.bound = subst(tv.bound, tvars, tvars1);
2154        }
2155        return tvars1;
2156    }
2157    static private Mapping newInstanceFun = new Mapping("newInstanceFun") {
2158            public Type apply(Type t) { return new TypeVar(t.tsym, t.getUpperBound(), t.getLowerBound()); }
2159        };
2160    // </editor-fold>
2161 
2162    // <editor-fold defaultstate="collapsed" desc="rank">
2163    /**
2164     * The rank of a class is the length of the longest path between
2165     * the class and java.lang.Object in the class inheritance
2166     * graph. Undefined for all but reference types.
2167     */
2168    public int rank(Type t) {
2169        switch(t.tag) {
2170        case CLASS: {
2171            ClassType cls = (ClassType)t;
2172            if (cls.rank_field < 0) {
2173                Name fullname = cls.tsym.getQualifiedName();
2174                if (fullname == fullname.table.java_lang_Object)
2175                    cls.rank_field = 0;
2176                else {
2177                    int r = rank(supertype(cls));
2178                    for (List<Type> l = interfaces(cls);
2179                         l.nonEmpty();
2180                         l = l.tail) {
2181                        if (rank(l.head) > r)
2182                            r = rank(l.head);
2183                    }
2184                    cls.rank_field = r + 1;
2185                }
2186            }
2187            return cls.rank_field;
2188        }
2189        case TYPEVAR: {
2190            TypeVar tvar = (TypeVar)t;
2191            if (tvar.rank_field < 0) {
2192                int r = rank(supertype(tvar));
2193                for (List<Type> l = interfaces(tvar);
2194                     l.nonEmpty();
2195                     l = l.tail) {
2196                    if (rank(l.head) > r) r = rank(l.head);
2197                }
2198                tvar.rank_field = r + 1;
2199            }
2200            return tvar.rank_field;
2201        }
2202        case ERROR:
2203            return 0;
2204        default:
2205            throw new AssertionError();
2206        }
2207    }
2208    // </editor-fold>
2209 
2210    // <editor-fold defaultstate="collapsed" desc="toString">
2211    /**
2212     * This toString is slightly more descriptive than the one on Type.
2213     */
2214    public String toString(Type t) {
2215        if (t.tag == FORALL) {
2216            ForAll forAll = (ForAll)t;
2217            return typaramsString(forAll.tvars) + forAll.qtype;
2218        }
2219        return "" + t;
2220    }
2221    // where
2222        private String typaramsString(List<Type> tvars) {
2223            StringBuffer s = new StringBuffer();
2224            s.append('<');
2225            boolean first = true;
2226            for (Type t : tvars) {
2227                if (!first) s.append(", ");
2228                first = false;
2229                appendTyparamString(((TypeVar)t), s);
2230            }
2231            s.append('>');
2232            return s.toString();
2233        }
2234        private void appendTyparamString(TypeVar t, StringBuffer buf) {
2235            buf.append(t);
2236            if (t.bound == null ||
2237                t.bound.tsym.getQualifiedName() == names.java_lang_Object)
2238                return;
2239            buf.append(" extends "); // Java syntax; no need for i18n
2240            Type bound = t.bound;
2241            if (!bound.isCompound()) {
2242                buf.append(bound);
2243            } else if ((erasure(t).tsym.flags() & INTERFACE) == 0) {
2244                buf.append(supertype(t));
2245                for (Type intf : interfaces(t)) {
2246                    buf.append('&');
2247                    buf.append(intf);
2248                }
2249            } else {
2250                // No superclass was given in bounds.
2251                // In this case, supertype is Object, erasure is first interface.
2252                boolean first = true;
2253                for (Type intf : interfaces(t)) {
2254                    if (!first) buf.append('&');
2255                    first = false;
2256                    buf.append(intf);
2257                }
2258            }
2259        }
2260    // </editor-fold>
2261 
2262    // <editor-fold defaultstate="collapsed" desc="Determining least upper bounds of types">
2263    /**
2264     * A cache for closures.
2265     *
2266     * <p>A closure is a list of all the supertypes and interfaces of
2267     * a class or interface type, ordered by ClassSymbol.precedes
2268     * (that is, subclasses come first, arbitrary but fixed
2269     * otherwise).
2270     */
2271    private Map<Type,List<Type>> closureCache = new HashMap<Type,List<Type>>();
2272 
2273    /**
2274     * Returns the closure of a class or interface type.
2275     */
2276    public List<Type> closure(Type t) {
2277        List<Type> cl = closureCache.get(t);
2278        if (cl == null) {
2279            Type st = supertype(t);
2280            if (!t.isCompound()) {
2281                if (st.tag == CLASS) {
2282                    cl = insert(closure(st), t);
2283                } else if (st.tag == TYPEVAR) {
2284                    cl = closure(st).prepend(t);
2285                } else {
2286                    cl = List.of(t);
2287                }
2288            } else {
2289                cl = closure(supertype(t));
2290            }
2291            for (List<Type> l = interfaces(t); l.nonEmpty(); l = l.tail)
2292                cl = union(cl, closure(l.head));
2293            closureCache.put(t, cl);
2294        }
2295        return cl;
2296    }
2297 
2298    /**
2299     * Insert a type in a closure
2300     */
2301    public List<Type> insert(List<Type> cl, Type t) {
2302        if (cl.isEmpty() || t.tsym.precedes(cl.head.tsym, this)) {
2303            return cl.prepend(t);
2304        } else if (cl.head.tsym.precedes(t.tsym, this)) {
2305            return insert(cl.tail, t).prepend(cl.head);
2306        } else {
2307            return cl;
2308        }
2309    }
2310 
2311    /**
2312     * Form the union of two closures
2313     */
2314    public List<Type> union(List<Type> cl1, List<Type> cl2) {
2315        if (cl1.isEmpty()) {
2316            return cl2;
2317        } else if (cl2.isEmpty()) {
2318            return cl1;
2319        } else if (cl1.head.tsym.precedes(cl2.head.tsym, this)) {
2320            return union(cl1.tail, cl2).prepend(cl1.head);
2321        } else if (cl2.head.tsym.precedes(cl1.head.tsym, this)) {
2322            return union(cl1, cl2.tail).prepend(cl2.head);
2323        } else {
2324            return union(cl1.tail, cl2.tail).prepend(cl1.head);
2325        }
2326    }
2327 
2328    /**
2329     * Intersect two closures
2330     */
2331    public List<Type> intersect(List<Type> cl1, List<Type> cl2) {
2332        if (cl1 == cl2)
2333            return cl1;
2334        if (cl1.isEmpty() || cl2.isEmpty())
2335            return List.nil();
2336        if (cl1.head.tsym.precedes(cl2.head.tsym, this))
2337            return intersect(cl1.tail, cl2);
2338        if (cl2.head.tsym.precedes(cl1.head.tsym, this))
2339            return intersect(cl1, cl2.tail);
2340        if (isSameType(cl1.head, cl2.head))
2341            return intersect(cl1.tail, cl2.tail).prepend(cl1.head);
2342        if (cl1.head.tsym == cl2.head.tsym &&
2343            cl1.head.tag == CLASS && cl2.head.tag == CLASS) {
2344            if (cl1.head.isParameterized() && cl2.head.isParameterized()) {
2345                Type merge = merge(cl1.head,cl2.head);
2346                return intersect(cl1.tail, cl2.tail).prepend(merge);
2347            }
2348            if (cl1.head.isRaw() || cl2.head.isRaw())
2349                return intersect(cl1.tail, cl2.tail).prepend(erasure(cl1.head));
2350        }
2351        return intersect(cl1.tail, cl2.tail);
2352    }
2353    // where
2354        class TypePair {
2355            final Type t1;
2356            final Type t2;
2357            TypePair(Type t1, Type t2) {
2358                this.t1 = t1;
2359                this.t2 = t2;
2360            }
2361            @Override
2362            public int hashCode() {
2363                return 127 * Types.this.hashCode(t1) + Types.this.hashCode(t2);
2364            }
2365            @Override
2366            public boolean equals(Object obj) {
2367                if (!(obj instanceof TypePair))
2368                    return false;
2369                TypePair typePair = (TypePair)obj;
2370                return isSameType(t1, typePair.t1)
2371                    && isSameType(t2, typePair.t2);
2372            }
2373        }
2374        Set<TypePair> mergeCache = new HashSet<TypePair>();
2375        private Type merge(Type c1, Type c2) {
2376            ClassType class1 = (ClassType) c1;
2377            List<Type> act1 = class1.getTypeArguments();
2378            ClassType class2 = (ClassType) c2;
2379            List<Type> act2 = class2.getTypeArguments();
2380            ListBuffer<Type> merged = new ListBuffer<Type>();
2381            List<Type> typarams = class1.tsym.type.getTypeArguments();
2382 
2383            while (act1.nonEmpty() && act2.nonEmpty() && typarams.nonEmpty()) {
2384                if (containsType(act1.head, act2.head)) {
2385                    merged.append(act1.head);
2386                } else if (containsType(act2.head, act1.head)) {
2387                    merged.append(act2.head);
2388                } else {
2389                    TypePair pair = new TypePair(c1, c2);
2390                    Type m;
2391                    if (mergeCache.add(pair)) {
2392                        m = new WildcardType(lub(upperBound(act1.head),
2393                                                 upperBound(act2.head)),
2394                                             BoundKind.EXTENDS,
2395                                             syms.boundClass);
2396                        mergeCache.remove(pair);
2397                    } else {
2398                        m = new WildcardType(syms.objectType,
2399                                             BoundKind.UNBOUND,
2400                                             syms.boundClass);
2401                    }
2402                    merged.append(m.withTypeVar(typarams.head));
2403                }
2404                act1 = act1.tail;
2405                act2 = act2.tail;
2406                typarams = typarams.tail;
2407            }
2408            assert(act1.isEmpty() && act2.isEmpty() && typarams.isEmpty());
2409            return new ClassType(class1.getEnclosingType(), merged.toList(), class1.tsym);
2410        }
2411 
2412    /**
2413     * Return the minimum type of a closure, a compound type if no
2414     * unique minimum exists.
2415     */
2416    private Type compoundMin(List<Type> cl) {
2417        if (cl.isEmpty()) return syms.objectType;
2418        List<Type> compound = closureMin(cl);
2419        if (compound.isEmpty())
2420            return null;
2421        else if (compound.tail.isEmpty())
2422            return compound.head;
2423        else
2424            return makeCompoundType(compound);
2425    }
2426 
2427    /**
2428     * Return the minimum types of a closure, suitable for computing
2429     * compoundMin or glb.
2430     */
2431    private List<Type> closureMin(List<Type> cl) {
2432        ListBuffer<Type> classes = lb();
2433        ListBuffer<Type> interfaces = lb();
2434        while (!cl.isEmpty()) {
2435            Type current = cl.head;
2436            if (current.isInterface())
2437                interfaces.append(current);
2438            else
2439                classes.append(current);
2440            ListBuffer<Type> candidates = lb();
2441            for (Type t : cl.tail) {
2442                if (!isSubtypeNoCapture(current, t))
2443                    candidates.append(t);
2444            }
2445            cl = candidates.toList();
2446        }
2447        return classes.appendList(interfaces).toList();
2448    }
2449 
2450    /**
2451     * Return the least upper bound of pair of types.  if the lub does
2452     * not exist return null.
2453     */
2454    public Type lub(Type t1, Type t2) {
2455        return lub(List.of(t1, t2));
2456    }
2457 
2458    /**
2459     * Return the least upper bound (lub) of set of types.  If the lub
2460     * does not exist return the type of null (bottom).
2461     */
2462    public Type lub(List<Type> ts) {
2463        final int ARRAY_BOUND = 1;
2464        final int CLASS_BOUND = 2;
2465        int boundkind = 0;
2466        for (Type t : ts) {
2467            switch (t.tag) {
2468            case CLASS:
2469                boundkind |= CLASS_BOUND;
2470                break;
2471            case ARRAY:
2472                boundkind |= ARRAY_BOUND;
2473                break;
2474            case  TYPEVAR:
2475                do {
2476                    t = t.getUpperBound();
2477                } while (t.tag == TYPEVAR);
2478                if (t.tag == ARRAY) {
2479                    boundkind |= ARRAY_BOUND;
2480                } else {
2481                    boundkind |= CLASS_BOUND;
2482                }
2483                break;
2484            default:
2485                if (t.isPrimitive())
2486                    return syms.botType;
2487            }
2488        }
2489        switch (boundkind) {
2490        case 0:
2491            return syms.botType;
2492 
2493        case ARRAY_BOUND:
2494            // calculate lub(A[], B[])
2495            List<Type> elements = Type.map(ts, elemTypeFun);
2496            for (Type t : elements) {
2497                if (t.isPrimitive()) {
2498                    // if a primitive type is found, then return
2499                    // arraySuperType unless all the types are the
2500                    // same
2501                    Type first = ts.head;
2502                    for (Type s : ts.tail) {
2503                        if (!isSameType(first, s)) {
2504                             // lub(int[], B[]) is Cloneable & Serializable
2505                            return arraySuperType();
2506                        }
2507                    }
2508                    // all the array types are the same, return one
2509                    // lub(int[], int[]) is int[]
2510                    return first;
2511                }
2512            }
2513            // lub(A[], B[]) is lub(A, B)[]
2514            return new ArrayType(lub(elements), syms.arrayClass);
2515 
2516        case CLASS_BOUND:
2517            // calculate lub(A, B)
2518            while (ts.head.tag != CLASS && ts.head.tag != TYPEVAR)
2519                ts = ts.tail;
2520            assert !ts.isEmpty();
2521            List<Type> cl = closure(ts.head);
2522            for (Type t : ts.tail) {
2523                if (t.tag == CLASS || t.tag == TYPEVAR)
2524                    cl = intersect(cl, closure(t));
2525            }
2526            return compoundMin(cl);
2527 
2528        default:
2529            // calculate lub(A, B[])
2530            List<Type> classes = List.of(arraySuperType());
2531            for (Type t : ts) {
2532                if (t.tag != ARRAY) // Filter out any arrays
2533                    classes = classes.prepend(t);
2534            }
2535            // lub(A, B[]) is lub(A, arraySuperType)
2536            return lub(classes);
2537        }
2538    }
2539    // where
2540        private Type arraySuperType = null;
2541        private Type arraySuperType() {
2542            // initialized lazily to avoid problems during compiler startup
2543            if (arraySuperType == null) {
2544                synchronized (this) {
2545                    if (arraySuperType == null) {
2546                        // JLS 10.8: all arrays implement Cloneable and Serializable.
2547                        arraySuperType = makeCompoundType(List.of(syms.serializableType,
2548                                                                  syms.cloneableType),
2549                                                          syms.objectType);
2550                    }
2551                }
2552            }
2553            return arraySuperType;
2554        }
2555    // </editor-fold>
2556 
2557    // <editor-fold defaultstate="collapsed" desc="Greatest lower bound">
2558    public Type glb(Type t, Type s) {
2559        if (s == null)
2560            return t;
2561        else if (isSubtypeNoCapture(t, s))
2562            return t;
2563        else if (isSubtypeNoCapture(s, t))
2564            return s;
2565 
2566        List<Type> closure = union(closure(t), closure(s));
2567        List<Type> bounds = closureMin(closure);
2568 
2569        if (bounds.isEmpty()) {             // length == 0
2570            return syms.objectType;
2571        } else if (bounds.tail.isEmpty()) { // length == 1
2572            return bounds.head;
2573        } else {                            // length > 1
2574            int classCount = 0;
2575            for (Type bound : bounds)
2576                if (!bound.isInterface())
2577                    classCount++;
2578            if (classCount > 1)
2579                return syms.errType;
2580        }
2581        return makeCompoundType(bounds);
2582    }
2583    // </editor-fold>
2584 
2585    // <editor-fold defaultstate="collapsed" desc="hashCode">
2586    /**
2587     * Compute a hash code on a type.
2588     */
2589    public static int hashCode(Type t) {
2590        return hashCode.visit(t);
2591    }
2592    // where
2593        private static final UnaryVisitor<Integer> hashCode = new UnaryVisitor<Integer>() {
2594 
2595            public Integer visitType(Type t, Void ignored) {
2596                return t.tag;
2597            }
2598 
2599            @Override
2600            public Integer visitClassType(ClassType t, Void ignored) {
2601                int result = visit(t.getEnclosingType());
2602                result *= 127;
2603                result += t.tsym.flatName().hashCode();
2604                for (Type s : t.getTypeArguments()) {
2605                    result *= 127;
2606                    result += visit(s);
2607                }
2608                return result;
2609            }
2610 
2611            @Override
2612            public Integer visitWildcardType(WildcardType t, Void ignored) {
2613                int result = t.kind.hashCode();
2614                if (t.type != null) {
2615                    result *= 127;
2616                    result += visit(t.type);
2617                }
2618                return result;
2619            }
2620 
2621            @Override
2622            public Integer visitArrayType(ArrayType t, Void ignored) {
2623                return visit(t.elemtype) + 12;
2624            }
2625 
2626            @Override
2627            public Integer visitTypeVar(TypeVar t, Void ignored) {
2628                return System.identityHashCode(t.tsym);
2629            }
2630 
2631            @Override
2632            public Integer visitUndetVar(UndetVar t, Void ignored) {
2633                return System.identityHashCode(t);
2634            }
2635 
2636            @Override
2637            public Integer visitErrorType(ErrorType t, Void ignored) {
2638                return 0;
2639            }
2640        };
2641    // </editor-fold>
2642 
2643    // <editor-fold defaultstate="collapsed" desc="Return-Type-Substitutable">
2644    /**
2645     * Does t have a result that is a subtype of the result type of s,
2646     * suitable for covariant returns?  It is assumed that both types
2647     * are (possibly polymorphic) method types.  Monomorphic method
2648     * types are handled in the obvious way.  Polymorphic method types
2649     * require renaming all type variables of one to corresponding
2650     * type variables in the other, where correspondence is by
2651     * position in the type parameter list. */
2652    public boolean resultSubtype(Type t, Type s, Warner warner) {
2653        List<Type> tvars = t.getTypeArguments();
2654        List<Type> svars = s.getTypeArguments();
2655        Type tres = t.getReturnType();
2656        Type sres = subst(s.getReturnType(), svars, tvars);
2657        return covariantReturnType(tres, sres, warner);
2658    }
2659 
2660    /**
2661     * Return-Type-Substitutable.
2662     * @see <a href="http://java.sun.com/docs/books/jls/">The Java
2663     * Language Specification, Third Ed. (8.4.5)</a>
2664     */
2665    public boolean returnTypeSubstitutable(Type r1, Type r2) {
2666        if (hasSameArgs(r1, r2))
2667            return resultSubtype(r1, r2, Warner.noWarnings);
2668        else
2669            return covariantReturnType(r1.getReturnType(),
2670                                       erasure(r2.getReturnType()),
2671                                       Warner.noWarnings);
2672    }
2673 
2674    public boolean returnTypeSubstitutable(Type r1,
2675                                           Type r2, Type r2res,
2676                                           Warner warner) {
2677        if (isSameType(r1.getReturnType(), r2res))
2678            return true;
2679        if (r1.getReturnType().isPrimitive() || r2res.isPrimitive())
2680            return false;
2681 
2682        if (hasSameArgs(r1, r2))
2683            return covariantReturnType(r1.getReturnType(), r2res, warner);
2684        if (!source.allowCovariantReturns())
2685            return false;
2686        if (isSubtypeUnchecked(r1.getReturnType(), r2res, warner))
2687            return true;
2688        if (!isSubtype(r1.getReturnType(), erasure(r2res)))
2689            return false;
2690        warner.warnUnchecked();
2691        return true;
2692    }
2693 
2694    /**
2695     * Is t an appropriate return type in an overrider for a
2696     * method that returns s?
2697     */
2698    public boolean covariantReturnType(Type t, Type s, Warner warner) {
2699        return
2700            isSameType(t, s) ||
2701            source.allowCovariantReturns() &&
2702            !t.isPrimitive() &&
2703            !s.isPrimitive() &&
2704            isAssignable(t, s, warner);
2705    }
2706    // </editor-fold>
2707 
2708    // <editor-fold defaultstate="collapsed" desc="Box/unbox support">
2709    /**
2710     * Return the class that boxes the given primitive.
2711     */
2712    public ClassSymbol boxedClass(Type t) {
2713        return reader.enterClass(syms.boxedName[t.tag]);
2714    }
2715 
2716    /**
2717     * Return the primitive type corresponding to a boxed type.
2718     */
2719    public Type unboxedType(Type t) {
2720        if (allowBoxing) {
2721            for (int i=0; i<syms.boxedName.length; i++) {
2722                Name box = syms.boxedName[i];
2723                if (box != null &&
2724                    asSuper(t, reader.enterClass(box)) != null)
2725                    return syms.typeOfTag[i];
2726            }
2727        }
2728        return Type.noType;
2729    }
2730    // </editor-fold>
2731 
2732    // <editor-fold defaultstate="collapsed" desc="Capture conversion">
2733    /*
2734     * JLS 3rd Ed. 5.1.10 Capture Conversion:
2735     *
2736     * Let G name a generic type declaration with n formal type
2737     * parameters A1 ... An with corresponding bounds U1 ... Un. There
2738     * exists a capture conversion from G<T1 ... Tn> to G<S1 ... Sn>,
2739     * where, for 1 <= i <= n:
2740     *
2741     * + If Ti is a wildcard type argument (4.5.1) of the form ? then
2742     *   Si is a fresh type variable whose upper bound is
2743     *   Ui[A1 := S1, ..., An := Sn] and whose lower bound is the null
2744     *   type.
2745     *
2746     * + If Ti is a wildcard type argument of the form ? extends Bi,
2747     *   then Si is a fresh type variable whose upper bound is
2748     *   glb(Bi, Ui[A1 := S1, ..., An := Sn]) and whose lower bound is
2749     *   the null type, where glb(V1,... ,Vm) is V1 & ... & Vm. It is
2750     *   a compile-time error if for any two classes (not interfaces)
2751     *   Vi and Vj,Vi is not a subclass of Vj or vice versa.
2752     *
2753     * + If Ti is a wildcard type argument of the form ? super Bi,
2754     *   then Si is a fresh type variable whose upper bound is
2755     *   Ui[A1 := S1, ..., An := Sn] and whose lower bound is Bi.
2756     *
2757     * + Otherwise, Si = Ti.
2758     *
2759     * Capture conversion on any type other than a parameterized type
2760     * (4.5) acts as an identity conversion (5.1.1). Capture
2761     * conversions never require a special action at run time and
2762     * therefore never throw an exception at run time.
2763     *
2764     * Capture conversion is not applied recursively.
2765     */
2766    /**
2767     * Capture conversion as specified by JLS 3rd Ed.
2768     */
2769    public Type capture(Type t) {
2770        if (t.tag != CLASS)
2771            return t;
2772        ClassType cls = (ClassType)t;
2773        if (cls.isRaw() || !cls.isParameterized())
2774            return cls;
2775 
2776        ClassType G = (ClassType)cls.asElement().asType();
2777        List<Type> A = G.getTypeArguments();
2778        List<Type> T = cls.getTypeArguments();
2779        List<Type> S = freshTypeVariables(T);
2780 
2781        List<Type> currentA = A;
2782        List<Type> currentT = T;
2783        List<Type> currentS = S;
2784        boolean captured = false;
2785        while (!currentA.isEmpty() &&
2786               !currentT.isEmpty() &&
2787               !currentS.isEmpty()) {
2788            if (currentS.head != currentT.head) {
2789                captured = true;
2790                WildcardType Ti = (WildcardType)currentT.head;
2791                Type Ui = currentA.head.getUpperBound();
2792                CapturedType Si = (CapturedType)currentS.head;
2793                if (Ui == null)
2794                    Ui = syms.objectType;
2795                switch (Ti.kind) {
2796                case UNBOUND:
2797                    Si.bound = subst(Ui, A, S);
2798                    Si.lower = syms.botType;
2799                    break;
2800                case EXTENDS:
2801                    Si.bound = glb(Ti.getExtendsBound(), subst(Ui, A, S));
2802                    Si.lower = syms.botType;
2803                    break;
2804                case SUPER:
2805                    Si.bound = subst(Ui, A, S);
2806                    Si.lower = Ti.getSuperBound();
2807                    break;
2808                }
2809                if (Si.bound == Si.lower)
2810                    currentS.head = Si.bound;
2811            }
2812            currentA = currentA.tail;
2813            currentT = currentT.tail;
2814            currentS = currentS.tail;
2815        }
2816        if (!currentA.isEmpty() || !currentT.isEmpty() || !currentS.isEmpty())
2817            return erasure(t); // some "rare" type involved
2818 
2819        if (captured)
2820            return new ClassType(cls.getEnclosingType(), S, cls.tsym);
2821        else
2822            return t;
2823    }
2824    // where
2825        private List<Type> freshTypeVariables(List<Type> types) {
2826            ListBuffer<Type> result = lb();
2827            for (Type t : types) {
2828                if (t.tag == WILDCARD) {
2829                    Type bound = ((WildcardType)t).getExtendsBound();
2830                    if (bound == null)
2831                        bound = syms.objectType;
2832                    result.append(new CapturedType(capturedName,
2833                                                   syms.noSymbol,
2834                                                   bound,
2835                                                   syms.botType,
2836                                                   (WildcardType)t));
2837                } else {
2838                    result.append(t);
2839                }
2840            }
2841            return result.toList();
2842        }
2843    // </editor-fold>
2844 
2845    // <editor-fold defaultstate="collapsed" desc="Internal utility methods">
2846    private List<Type> upperBounds(List<Type> ss) {
2847        if (ss.isEmpty()) return ss;
2848        Type head = upperBound(ss.head);
2849        List<Type> tail = upperBounds(ss.tail);
2850        if (head != ss.head || tail != ss.tail)
2851            return tail.prepend(head);
2852        else
2853            return ss;
2854    }
2855 
2856    private boolean sideCast(Type from, Type to, Warner warn) {
2857        // We are casting from type $from$ to type $to$, which are
2858        // non-final unrelated types.  This method
2859        // tries to reject a cast by transferring type parameters
2860        // from $to$ to $from$ by common superinterfaces.
2861        boolean reverse = false;
2862        Type target = to;
2863        if ((to.tsym.flags() & INTERFACE) == 0) {
2864            assert (from.tsym.flags() & INTERFACE) != 0;
2865            reverse = true;
2866            to = from;
2867            from = target;
2868        }
2869        List<Type> commonSupers = superClosure(to, erasure(from));
2870        boolean giveWarning = commonSupers.isEmpty();
2871        // The arguments to the supers could be unified here to
2872        // get a more accurate analysis
2873        while (commonSupers.nonEmpty()) {
2874            Type t1 = asSuper(from, commonSupers.head.tsym);
2875            Type t2 = commonSupers.head; // same as asSuper(to, commonSupers.head.tsym);
2876            if (disjointTypes(t1.getTypeArguments(), t2.getTypeArguments()))
2877                return false;
2878            giveWarning = giveWarning || (reverse ? giveWarning(t2, t1) : giveWarning(t1, t2));
2879            commonSupers = commonSupers.tail;
2880        }
2881        if (giveWarning && !isReifiable(to))
2882            warn.warnUnchecked();
2883        if (!source.allowCovariantReturns())
2884            // reject if there is a common method signature with
2885            // incompatible return types.
2886            chk.checkCompatibleAbstracts(warn.pos(), from, to);
2887        return true;
2888    }
2889 
2890    private boolean sideCastFinal(Type from, Type to, Warner warn) {
2891        // We are casting from type $from$ to type $to$, which are
2892        // unrelated types one of which is final and the other of
2893        // which is an interface.  This method
2894        // tries to reject a cast by transferring type parameters
2895        // from the final class to the interface.
2896        boolean reverse = false;
2897        Type target = to;
2898        if ((to.tsym.flags() & INTERFACE) == 0) {
2899            assert (from.tsym.flags() & INTERFACE) != 0;
2900            reverse = true;
2901            to = from;
2902            from = target;
2903        }
2904        assert (from.tsym.flags() & FINAL) != 0;
2905        Type t1 = asSuper(from, to.tsym);
2906        if (t1 == null) return false;
2907        Type t2 = to;
2908        if (disjointTypes(t1.getTypeArguments(), t2.getTypeArguments()))
2909            return false;
2910        if (!source.allowCovariantReturns())
2911            // reject if there is a common method signature with
2912            // incompatible return types.
2913            chk.checkCompatibleAbstracts(warn.pos(), from, to);
2914        if (!isReifiable(target) &&
2915            (reverse ? giveWarning(t2, t1) : giveWarning(t1, t2)))
2916            warn.warnUnchecked();
2917        return true;
2918    }
2919 
2920    private boolean giveWarning(Type from, Type to) {
2921        // To and from are (possibly different) parameterizations
2922        // of the same class or interface
2923        return to.isParameterized() && !containsType(to.getTypeArguments(), from.getTypeArguments());
2924    }
2925 
2926    private List<Type> superClosure(Type t, Type s) {
2927        List<Type> cl = List.nil();
2928        for (List<Type> l = interfaces(t); l.nonEmpty(); l = l.tail) {
2929            if (isSubtype(s, erasure(l.head))) {
2930                cl = insert(cl, l.head);
2931            } else {
2932                cl = union(cl, superClosure(l.head, s));
2933            }
2934        }
2935        return cl;
2936    }
2937 
2938    private boolean containsTypeEquivalent(Type t, Type s) {
2939        return
2940            isSameType(t, s) || // shortcut
2941            containsType(t, s) && containsType(s, t);
2942    }
2943 
2944    /**
2945     * Adapt a type by computing a substitution which maps a source
2946     * type to a target type.
2947     *
2948     * @param source    the source type
2949     * @param target    the target type
2950     * @param from      the type variables of the computed substitution
2951     * @param to        the types of the computed substitution.
2952     */
2953    public void adapt(Type source,
2954                       Type target,
2955                       ListBuffer<Type> from,
2956                       ListBuffer<Type> to) throws AdaptFailure {
2957        Map<Symbol,Type> mapping = new HashMap<Symbol,Type>();
2958        adaptRecursive(source, target, from, to, mapping);
2959        List<Type> fromList = from.toList();
2960        List<Type> toList = to.toList();
2961        while (!fromList.isEmpty()) {
2962            Type val = mapping.get(fromList.head.tsym);
2963            if (toList.head != val)
2964                toList.head = val;
2965            fromList = fromList.tail;
2966            toList = toList.tail;
2967        }
2968    }
2969    // where
2970        private void adaptRecursive(Type source,
2971                                    Type target,
2972                                    ListBuffer<Type> from,
2973                                    ListBuffer<Type> to,
2974                                    Map<Symbol,Type> mapping) throws AdaptFailure {
2975            if (source.tag == TYPEVAR) {
2976                // Check to see if there is
2977                // already a mapping for $source$, in which case
2978                // the old mapping will be merged with the new
2979                Type val = mapping.get(source.tsym);
2980                if (val != null) {
2981                    if (val.isSuperBound() && target.isSuperBound()) {
2982                        val = isSubtype(lowerBound(val), lowerBound(target))
2983                            ? target : val;
2984                    } else if (val.isExtendsBound() && target.isExtendsBound()) {
2985                        val = isSubtype(upperBound(val), upperBound(target))
2986                            ? val : target;
2987                    } else if (!isSameType(val, target)) {
2988                        throw new AdaptFailure();
2989                    }
2990                } else {
2991                    val = target;
2992                    from.append(source);
2993                    to.append(target);
2994                }
2995                mapping.put(source.tsym, val);
2996            } else if (source.tag == target.tag) {
2997                switch (source.tag) {
2998                    case CLASS:
2999                        adapt(source.allparams(), target.allparams(),
3000                              from, to, mapping);
3001                        break;
3002                    case ARRAY:
3003                        adaptRecursive(elemtype(source), elemtype(target),
3004                                       from, to, mapping);
3005                        break;
3006                    case WILDCARD:
3007                        if (source.isExtendsBound()) {
3008                            adaptRecursive(upperBound(source), upperBound(target),
3009                                           from, to, mapping);
3010                        } else if (source.isSuperBound()) {
3011                            adaptRecursive(lowerBound(source), lowerBound(target),
3012                                           from, to, mapping);
3013                        }
3014                        break;
3015                }
3016            }
3017        }
3018        public static class AdaptFailure extends Exception {
3019            static final long serialVersionUID = -7490231548272701566L;
3020        }
3021 
3022    /**
3023     * Adapt a type by computing a substitution which maps a list of
3024     * source types to a list of target types.
3025     *
3026     * @param source    the source type
3027     * @param target    the target type
3028     * @param from      the type variables of the computed substitution
3029     * @param to        the types of the computed substitution.
3030     */
3031    private void adapt(List<Type> source,
3032                       List<Type> target,
3033                       ListBuffer<Type> from,
3034                       ListBuffer<Type> to,
3035                       Map<Symbol,Type> mapping) throws AdaptFailure {
3036        if (source.length() == target.length()) {
3037            while (source.nonEmpty()) {
3038                adaptRecursive(source.head, target.head, from, to, mapping);
3039                source = source.tail;
3040                target = target.tail;
3041            }
3042        }
3043    }
3044 
3045    private void adaptSelf(Type t,
3046                           ListBuffer<Type> from,
3047                           ListBuffer<Type> to) {
3048        try {
3049            //if (t.tsym.type != t)
3050                adapt(t.tsym.type, t, from, to);
3051        } catch (AdaptFailure ex) {
3052            // Adapt should never fail calculating a mapping from
3053            // t.tsym.type to t as there can be no merge problem.
3054            throw new AssertionError(ex);
3055        }
3056    }
3057 
3058    /**
3059     * Rewrite all type variables (universal quantifiers) in the given
3060     * type to wildcards (existential quantifiers).  This is used to
3061     * determine if a cast is allowed.  For example, if high is true
3062     * and {@code T <: Number}, then {@code List<T>} is rewritten to
3063     * {@code List<?  extends Number>}.  Since {@code List<Integer> <:
3064     * List<? extends Number>} a {@code List<T>} can be cast to {@code
3065     * List<Integer>} with a warning.
3066     * @param t a type
3067     * @param high if true return an upper bound; otherwise a lower
3068     * bound
3069     * @param rewriteTypeVars only rewrite captured wildcards if false;
3070     * otherwise rewrite all type variables
3071     * @return the type rewritten with wildcards (existential
3072     * quantifiers) only
3073     */
3074    private Type rewriteQuantifiers(Type t, boolean high, boolean rewriteTypeVars) {
3075        ListBuffer<Type> from = new ListBuffer<Type>();
3076        ListBuffer<Type> to = new ListBuffer<Type>();
3077        adaptSelf(t, from, to);
3078        ListBuffer<Type> rewritten = new ListBuffer<Type>();
3079        List<Type> formals = from.toList();
3080        boolean changed = false;
3081        for (Type arg : to.toList()) {
3082            Type bound;
3083            if (rewriteTypeVars && arg.tag == TYPEVAR) {
3084                TypeVar tv = (TypeVar)arg;
3085                bound = high ? tv.bound : syms.botType;
3086            } else {
3087                bound = high ? upperBound(arg) : lowerBound(arg);
3088            }
3089            Type newarg = bound;
3090            if (arg != bound) {
3091                changed = true;
3092                newarg = high ? makeExtendsWildcard(bound, (TypeVar)formals.head)
3093                              : makeSuperWildcard(bound, (TypeVar)formals.head);
3094            }
3095            rewritten.append(newarg);
3096            formals = formals.tail;
3097        }
3098        if (changed)
3099            return subst(t.tsym.type, from.toList(), rewritten.toList());
3100        else
3101            return t;
3102    }
3103 
3104    /**
3105     * Create a wildcard with the given upper (extends) bound; create
3106     * an unbounded wildcard if bound is Object.
3107     *
3108     * @param bound the upper bound
3109     * @param formal the formal type parameter that will be
3110     * substituted by the wildcard
3111     */
3112    private WildcardType makeExtendsWildcard(Type bound, TypeVar formal) {
3113        if (bound == syms.objectType) {
3114            return new WildcardType(syms.objectType,
3115                                    BoundKind.UNBOUND,
3116                                    syms.boundClass,
3117                                    formal);
3118        } else {
3119            return new WildcardType(bound,
3120                                    BoundKind.EXTENDS,
3121                                    syms.boundClass,
3122                                    formal);
3123        }
3124    }
3125 
3126    /**
3127     * Create a wildcard with the given lower (super) bound; create an
3128     * unbounded wildcard if bound is bottom (type of {@code null}).
3129     *
3130     * @param bound the lower bound
3131     * @param formal the formal type parameter that will be
3132     * substituted by the wildcard
3133     */
3134    private WildcardType makeSuperWildcard(Type bound, TypeVar formal) {
3135        if (bound.tag == BOT) {
3136            return new WildcardType(syms.objectType,
3137                                    BoundKind.UNBOUND,
3138                                    syms.boundClass,
3139                                    formal);
3140        } else {
3141            return new WildcardType(bound,
3142                                    BoundKind.SUPER,
3143                                    syms.boundClass,
3144                                    formal);
3145        }
3146    }
3147 
3148    /**
3149     * A wrapper for a type that allows use in sets.
3150     */
3151    class SingletonType {
3152        final Type t;
3153        SingletonType(Type t) {
3154            this.t = t;
3155        }
3156        public int hashCode() {
3157            return Types.this.hashCode(t);
3158        }
3159        public boolean equals(Object obj) {
3160            return (obj instanceof SingletonType) &&
3161                isSameType(t, ((SingletonType)obj).t);
3162        }
3163        public String toString() {
3164            return t.toString();
3165        }
3166    }
3167    // </editor-fold>
3168 
3169    // <editor-fold defaultstate="collapsed" desc="Visitors">
3170    /**
3171     * A default visitor for types.  All visitor methods except
3172     * visitType are implemented by delegating to visitType.  Concrete
3173     * subclasses must provide an implementation of visitType and can
3174     * override other methods as needed.
3175     *
3176     * @param <R> the return type of the operation implemented by this
3177     * visitor; use Void if no return type is needed.
3178     * @param <S> the type of the second argument (the first being the
3179     * type itself) of the operation implemented by this visitor; use
3180     * Void if a second argument is not needed.
3181     */
3182    public static abstract class DefaultTypeVisitor<R,S> implements Type.Visitor<R,S> {
3183        final public R visit(Type t, S s)               { return t.accept(this, s); }
3184        public R visitClassType(ClassType t, S s)       { return visitType(t, s); }
3185        public R visitWildcardType(WildcardType t, S s) { return visitType(t, s); }
3186        public R visitArrayType(ArrayType t, S s)       { return visitType(t, s); }
3187        public R visitMethodType(MethodType t, S s)     { return visitType(t, s); }
3188        public R visitPackageType(PackageType t, S s)   { return visitType(t, s); }
3189        public R visitTypeVar(TypeVar t, S s)           { return visitType(t, s); }
3190        public R visitCapturedType(CapturedType t, S s) { return visitType(t, s); }
3191        public R visitForAll(ForAll t, S s)             { return visitType(t, s); }
3192        public R visitUndetVar(UndetVar t, S s)         { return visitType(t, s); }
3193        public R visitErrorType(ErrorType t, S s)       { return visitType(t, s); }
3194    }
3195 
3196    /**
3197     * A <em>simple</em> visitor for types.  This visitor is simple as
3198     * captured wildcards, for-all types (generic methods), and
3199     * undetermined type variables (part of inference) are hidden.
3200     * Captured wildcards are hidden by treating them as type
3201     * variables and the rest are hidden by visiting their qtypes.
3202     *
3203     * @param <R> the return type of the operation implemented by this
3204     * visitor; use Void if no return type is needed.
3205     * @param <S> the type of the second argument (the first being the
3206     * type itself) of the operation implemented by this visitor; use
3207     * Void if a second argument is not needed.
3208     */
3209    public static abstract class SimpleVisitor<R,S> extends DefaultTypeVisitor<R,S> {
3210        @Override
3211        public R visitCapturedType(CapturedType t, S s) {
3212            return visitTypeVar(t, s);
3213        }
3214        @Override
3215        public R visitForAll(ForAll t, S s) {
3216            return visit(t.qtype, s);
3217        }
3218        @Override
3219        public R visitUndetVar(UndetVar t, S s) {
3220            return visit(t.qtype, s);
3221        }
3222    }
3223 
3224    /**
3225     * A plain relation on types.  That is a 2-ary function on the
3226     * form Type&nbsp;&times;&nbsp;Type&nbsp;&rarr;&nbsp;Boolean.
3227     * <!-- In plain text: Type x Type -> Boolean -->
3228     */
3229    public static abstract class TypeRelation extends SimpleVisitor<Boolean,Type> {}
3230 
3231    /**
3232     * A convenience visitor for implementing operations that only
3233     * require one argument (the type itself), that is, unary
3234     * operations.
3235     *
3236     * @param <R> the return type of the operation implemented by this
3237     * visitor; use Void if no return type is needed.
3238     */
3239    public static abstract class UnaryVisitor<R> extends SimpleVisitor<R,Void> {
3240        final public R visit(Type t) { return t.accept(this, null); }
3241    }
3242 
3243    /**
3244     * A visitor for implementing a mapping from types to types.  The
3245     * default behavior of this class is to implement the identity
3246     * mapping (mapping a type to itself).  This can be overridden in
3247     * subclasses.
3248     *
3249     * @param <S> the type of the second argument (the first being the
3250     * type itself) of this mapping; use Void if a second argument is
3251     * not needed.
3252     */
3253    public static class MapVisitor<S> extends DefaultTypeVisitor<Type,S> {
3254        final public Type visit(Type t) { return t.accept(this, null); }
3255        public Type visitType(Type t, S s) { return t; }
3256    }
3257    // </editor-fold>
3258}

[all classes][com.sun.tools.javac.code]
EMMA 2.0.5312 (C) Vladimir Roubtsov