@@ -54,11 +54,28 @@ private predicate implicitConversionNonNull(Type fromType, Type toType) {
54
54
fromType instanceof DynamicType // 6.1.8
55
55
}
56
56
57
- private Type getTypeArgument ( UnboundGenericType ugt , ConstructedType ct , int i , TypeParameter tp ) {
58
- ct .getUnboundGeneric ( ) = ugt and
57
+ /**
58
+ * A generic type. This includes both constructed generic types and unbound
59
+ * generic types (which correspond to constructed generic types where the
60
+ * type arguments equal the type parameters).
61
+ */
62
+ private class GenericType extends Generic , Type {
63
+ /** Gets the `i`th type argument. */
64
+ Type getTypeArgument ( int i ) { result = this .getChild ( i ) }
65
+
66
+ /** Gets the unbound generic type. */
67
+ UnboundGenericType getUnboundGeneric ( ) {
68
+ result = this .( ConstructedType ) .getUnboundGeneric ( )
69
+ or
70
+ result = this
71
+ }
72
+ }
73
+
74
+ private Type getTypeArgument ( UnboundGenericType ugt , GenericType gt , int i , TypeParameter tp ) {
75
+ gt .getUnboundGeneric ( ) = ugt and
59
76
not ugt instanceof AnonymousClass and
60
77
tp = ugt .getTypeParameter ( i ) and
61
- result = ct .getTypeArgument ( i )
78
+ result = gt .getTypeArgument ( i )
62
79
}
63
80
64
81
/** A type that is an element type of an array type. */
@@ -68,7 +85,7 @@ private class ArrayElementType extends Type {
68
85
69
86
/** A type that is an argument in a constructed type. */
70
87
private class TypeArgument extends Type {
71
- TypeArgument ( ) { this = any ( ConstructedType ct ) . getATypeArgument ( ) }
88
+ TypeArgument ( ) { this = any ( GenericType gt ) . getTypeArgument ( _ ) }
72
89
}
73
90
74
91
/**
@@ -95,8 +112,7 @@ private module Identity {
95
112
96
113
private class IdentityConvertibleArrayType extends IdentityConvertibleType , ArrayType { }
97
114
98
- private class IdentityConvertibleConstructedType extends IdentityConvertibleType , ConstructedType {
99
- }
115
+ private class IdentityConvertibleGenericType extends IdentityConvertibleType , GenericType { }
100
116
101
117
/**
102
118
* A type is (strictly) identity convertible if it contains at least one `object`
@@ -109,7 +125,7 @@ private module Identity {
109
125
or
110
126
isIdentityConvertible ( t .( ArrayType ) .getElementType ( ) )
111
127
or
112
- isIdentityConvertible ( t .( ConstructedType ) . getATypeArgument ( ) )
128
+ isIdentityConvertible ( t .( GenericType ) . getTypeArgument ( _ ) )
113
129
}
114
130
115
131
predicate convIdentityStrict ( IdentityConvertibleType fromType , IdentityConvertibleType toType ) {
@@ -119,7 +135,7 @@ private module Identity {
119
135
or
120
136
convIdentityStrictArrayType ( fromType , toType )
121
137
or
122
- convIdentityStrictConstructedType ( fromType , toType )
138
+ convIdentityStrictGenericType ( fromType , toType )
123
139
}
124
140
125
141
private predicate convIdentityObjectDynamic ( ObjectType fromType , DynamicType toType ) { any ( ) }
@@ -151,7 +167,7 @@ private module Identity {
151
167
*/
152
168
private int getTypeArgumentCount ( UnboundGenericType ugt , int i ) {
153
169
result = strictcount ( Type arg |
154
- exists ( IdentityConvertibleConstructedType ct | ct .getUnboundGeneric ( ) = ugt |
170
+ exists ( IdentityConvertibleGenericType ct | ct .getUnboundGeneric ( ) = ugt |
155
171
arg = ct .getTypeArgument ( i )
156
172
)
157
173
)
@@ -162,9 +178,7 @@ private module Identity {
162
178
}
163
179
164
180
/** Gets the 'i'th type argument, ranked by size, of constructed type `t`. */
165
- private Type getTypeArgumentRanked (
166
- UnboundGenericType ugt , IdentityConvertibleConstructedType t , int i
167
- ) {
181
+ private Type getTypeArgumentRanked ( UnboundGenericType ugt , IdentityConvertibleGenericType t , int i ) {
168
182
result = getTypeArgument ( ugt , t , rnk ( ugt , i ) , _)
169
183
}
170
184
@@ -207,8 +221,8 @@ private module Identity {
207
221
208
222
pragma [ nomagic]
209
223
private predicate convIdentitySingle0 (
210
- UnboundGenericType ugt , IdentityConvertibleConstructedType toType ,
211
- TypeArgument fromTypeArgument , TypeArgument toTypeArgument
224
+ UnboundGenericType ugt , IdentityConvertibleGenericType toType , TypeArgument fromTypeArgument ,
225
+ TypeArgument toTypeArgument
212
226
) {
213
227
convTypeArgumentsSameUnbound ( ugt , fromTypeArgument , toTypeArgument , 0 ) and
214
228
toTypeArgument = getTypeArgumentRanked ( ugt , toType , 0 ) and
@@ -220,8 +234,8 @@ private module Identity {
220
234
* convertible, and the number of type arguments is 1.
221
235
*/
222
236
predicate convIdentitySingle (
223
- UnboundGenericType ugt , IdentityConvertibleConstructedType fromType ,
224
- IdentityConvertibleConstructedType toType
237
+ UnboundGenericType ugt , IdentityConvertibleGenericType fromType ,
238
+ IdentityConvertibleGenericType toType
225
239
) {
226
240
exists ( TypeArgument fromTypeArgument , TypeArgument toTypeArgument |
227
241
convIdentitySingle0 ( ugt , toType , fromTypeArgument , toTypeArgument )
@@ -232,8 +246,8 @@ private module Identity {
232
246
233
247
pragma [ nomagic]
234
248
private predicate convIdentityMultiple01Aux0 (
235
- UnboundGenericType ugt , IdentityConvertibleConstructedType toType ,
236
- TypeArgument fromTypeArgument0 , TypeArgument toTypeArgument0 , TypeArgument toTypeArgument1
249
+ UnboundGenericType ugt , IdentityConvertibleGenericType toType , TypeArgument fromTypeArgument0 ,
250
+ TypeArgument toTypeArgument0 , TypeArgument toTypeArgument1
237
251
) {
238
252
convTypeArgumentsSameUnbound ( ugt , fromTypeArgument0 , toTypeArgument0 , 0 ) and
239
253
toTypeArgument0 = getTypeArgumentRanked ( ugt , toType , 0 ) and
@@ -242,8 +256,8 @@ private module Identity {
242
256
243
257
pragma [ nomagic]
244
258
private predicate convIdentityMultiple01Aux1 (
245
- UnboundGenericType ugt , IdentityConvertibleConstructedType fromType ,
246
- TypeArgument fromTypeArgument0 , TypeArgument fromTypeArgument1 , TypeArgument toTypeArgument1
259
+ UnboundGenericType ugt , IdentityConvertibleGenericType fromType , TypeArgument fromTypeArgument0 ,
260
+ TypeArgument fromTypeArgument1 , TypeArgument toTypeArgument1
247
261
) {
248
262
convTypeArgumentsSameUnbound ( ugt , fromTypeArgument1 , toTypeArgument1 , 1 ) and
249
263
fromTypeArgument0 = getTypeArgumentRanked ( ugt , fromType , 0 ) and
@@ -255,8 +269,8 @@ private module Identity {
255
269
* are identity convertible.
256
270
*/
257
271
private predicate convIdentityMultiple01 (
258
- UnboundGenericType ugt , IdentityConvertibleConstructedType fromType ,
259
- IdentityConvertibleConstructedType toType
272
+ UnboundGenericType ugt , IdentityConvertibleGenericType fromType ,
273
+ IdentityConvertibleGenericType toType
260
274
) {
261
275
exists (
262
276
Type fromTypeArgument0 , Type toTypeArgument0 , Type fromTypeArgument1 , Type toTypeArgument1
@@ -270,7 +284,7 @@ private module Identity {
270
284
271
285
pragma [ nomagic]
272
286
private predicate convIdentityMultiple2Aux (
273
- UnboundGenericType ugt , IdentityConvertibleConstructedType toType , int i ,
287
+ UnboundGenericType ugt , IdentityConvertibleGenericType toType , int i ,
274
288
TypeArgument fromTypeArgument , TypeArgument toTypeArgument
275
289
) {
276
290
convTypeArgumentsSameUnbound ( ugt , fromTypeArgument , toTypeArgument , i ) and
@@ -279,8 +293,8 @@ private module Identity {
279
293
}
280
294
281
295
private predicate convIdentityMultiple2 (
282
- UnboundGenericType ugt , IdentityConvertibleConstructedType fromType ,
283
- IdentityConvertibleConstructedType toType , int i
296
+ UnboundGenericType ugt , IdentityConvertibleGenericType fromType ,
297
+ IdentityConvertibleGenericType toType , int i
284
298
) {
285
299
exists ( TypeArgument fromTypeArgument , TypeArgument toTypeArgument |
286
300
convIdentityMultiple2Aux ( ugt , toType , i , fromTypeArgument , toTypeArgument )
@@ -295,17 +309,17 @@ private module Identity {
295
309
*/
296
310
pragma [ nomagic]
297
311
predicate convIdentityMultiple (
298
- UnboundGenericType ugt , IdentityConvertibleConstructedType fromType ,
299
- IdentityConvertibleConstructedType toType , int i
312
+ UnboundGenericType ugt , IdentityConvertibleGenericType fromType ,
313
+ IdentityConvertibleGenericType toType , int i
300
314
) {
301
315
convIdentityMultiple01 ( ugt , fromType , toType ) and i = 1
302
316
or
303
317
convIdentityMultiple ( ugt , fromType , toType , i - 1 ) and
304
318
convIdentityMultiple2 ( ugt , fromType , toType , i )
305
319
}
306
320
307
- private predicate convIdentityStrictConstructedType (
308
- IdentityConvertibleConstructedType fromType , IdentityConvertibleConstructedType toType
321
+ private predicate convIdentityStrictGenericType (
322
+ IdentityConvertibleGenericType fromType , IdentityConvertibleGenericType toType
309
323
) {
310
324
// Semantically equivalent with
311
325
// ```
@@ -730,7 +744,7 @@ predicate convConversionOperator(Type fromType, Type toType) {
730
744
}
731
745
732
746
/** 13.1.3.2: Variance conversion. */
733
- private predicate convVariance ( ConstructedType fromType , ConstructedType toType ) {
747
+ private predicate convVariance ( GenericType fromType , GenericType toType ) {
734
748
// Semantically equivalent with
735
749
// ```
736
750
// ugt = fromType.getUnboundGeneric()
@@ -758,34 +772,14 @@ private predicate convVariance(ConstructedType fromType, ConstructedType toType)
758
772
}
759
773
760
774
private module Variance {
761
- /**
762
- * Holds if constructed type `ct` is potentially variance convertible to
763
- * or from another constructed type, as a result of the `i`th type
764
- * argument being potentially convertible.
765
- */
766
- private predicate isVarianceConvertible ( ConstructedType ct , int i ) {
767
- exists ( TypeParameter tp , Type t |
768
- tp = ct .getUnboundGeneric ( ) .getTypeParameter ( i ) and
769
- t = ct .getTypeArgument ( i )
770
- |
771
- // Anything that is not a type parameter is potentially convertible
772
- // to/from another type; if the `i`th type parameter is invariant,
773
- // `t` must be strictly identity convertible
774
- not t instanceof TypeParameter and
775
- ( tp .isIn ( ) or tp .isOut ( ) or Identity:: convIdentityStrict ( t , _) )
776
- or
777
- exists ( TypeParameter s | s = t |
778
- // A type parameter with implicit reference conversion
779
- exists ( convTypeParameterBase ( s ) ) and s .isRefType ( ) and tp .isOut ( )
775
+ private class VarianceConvertibleGenericType extends GenericType {
776
+ VarianceConvertibleGenericType ( ) {
777
+ exists ( TypeParameter tp | tp = this .getUnboundGeneric ( ) .getATypeParameter ( ) |
778
+ tp .isIn ( )
780
779
or
781
- // A type parameter convertible from another type parameter
782
- exists ( TypeParameter u | s = convTypeParameterBase ( u ) and u .isRefType ( ) and tp .isIn ( ) )
780
+ tp .isOut ( )
783
781
)
784
- )
785
- }
786
-
787
- private class VarianceConvertibleConstructedType extends ConstructedType {
788
- VarianceConvertibleConstructedType ( ) { isVarianceConvertible ( this , _) }
782
+ }
789
783
}
790
784
791
785
/**
@@ -794,8 +788,8 @@ private module Variance {
794
788
*/
795
789
private int getTypeArgumentCount ( UnboundGenericType ugt , int i ) {
796
790
result = strictcount ( Type arg |
797
- exists ( VarianceConvertibleConstructedType ct | ct .getUnboundGeneric ( ) = ugt |
798
- arg = ct .getTypeArgument ( i )
791
+ exists ( VarianceConvertibleGenericType gt | gt .getUnboundGeneric ( ) = ugt |
792
+ arg = gt .getTypeArgument ( i )
799
793
)
800
794
)
801
795
}
@@ -806,7 +800,7 @@ private module Variance {
806
800
807
801
/** Gets the 'i'th type argument, ranked by size, of constructed type `t`. */
808
802
private Type getTypeArgumentRanked (
809
- UnboundGenericType ugt , VarianceConvertibleConstructedType t , int i , TypeParameter tp
803
+ UnboundGenericType ugt , VarianceConvertibleGenericType t , int i , TypeParameter tp
810
804
) {
811
805
result = getTypeArgument ( ugt , t , rnk ( ugt , i ) , tp )
812
806
}
@@ -889,8 +883,8 @@ private module Variance {
889
883
890
884
pragma [ nomagic]
891
885
private predicate convVarianceSingle0 (
892
- UnboundGenericType ugt , VarianceConvertibleConstructedType toType ,
893
- TypeArgument fromTypeArgument , TypeArgument toTypeArgument
886
+ UnboundGenericType ugt , VarianceConvertibleGenericType toType , TypeArgument fromTypeArgument ,
887
+ TypeArgument toTypeArgument
894
888
) {
895
889
convTypeArgumentsSameUnbound ( ugt , fromTypeArgument , toTypeArgument , 0 ) and
896
890
toTypeArgument = getTypeArgumentRanked ( ugt , toType , 0 , _) and
@@ -902,8 +896,8 @@ private module Variance {
902
896
* convertible, and the number of type arguments is 1.
903
897
*/
904
898
predicate convVarianceSingle (
905
- UnboundGenericType ugt , VarianceConvertibleConstructedType fromType ,
906
- VarianceConvertibleConstructedType toType
899
+ UnboundGenericType ugt , VarianceConvertibleGenericType fromType ,
900
+ VarianceConvertibleGenericType toType
907
901
) {
908
902
exists ( TypeArgument fromTypeArgument , TypeArgument toTypeArgument |
909
903
convVarianceSingle0 ( ugt , toType , fromTypeArgument , toTypeArgument )
@@ -914,8 +908,8 @@ private module Variance {
914
908
915
909
pragma [ nomagic]
916
910
private predicate convVarianceMultiple01Aux0 (
917
- UnboundGenericType ugt , VarianceConvertibleConstructedType toType ,
918
- TypeArgument fromTypeArgument0 , TypeArgument toTypeArgument0 , TypeArgument toTypeArgument1
911
+ UnboundGenericType ugt , VarianceConvertibleGenericType toType , TypeArgument fromTypeArgument0 ,
912
+ TypeArgument toTypeArgument0 , TypeArgument toTypeArgument1
919
913
) {
920
914
convTypeArgumentsSameUnbound ( ugt , fromTypeArgument0 , toTypeArgument0 , 0 ) and
921
915
toTypeArgument0 = getTypeArgumentRanked ( ugt , toType , 0 , _) and
@@ -924,8 +918,8 @@ private module Variance {
924
918
925
919
pragma [ nomagic]
926
920
private predicate convVarianceMultiple01Aux1 (
927
- UnboundGenericType ugt , VarianceConvertibleConstructedType fromType ,
928
- TypeArgument fromTypeArgument0 , TypeArgument fromTypeArgument1 , TypeArgument toTypeArgument1
921
+ UnboundGenericType ugt , VarianceConvertibleGenericType fromType , TypeArgument fromTypeArgument0 ,
922
+ TypeArgument fromTypeArgument1 , TypeArgument toTypeArgument1
929
923
) {
930
924
convTypeArgumentsSameUnbound ( ugt , fromTypeArgument1 , toTypeArgument1 , 1 ) and
931
925
fromTypeArgument0 = getTypeArgumentRanked ( ugt , fromType , 0 , _) and
@@ -937,8 +931,8 @@ private module Variance {
937
931
* are variance convertible.
938
932
*/
939
933
private predicate convVarianceMultiple01 (
940
- UnboundGenericType ugt , VarianceConvertibleConstructedType fromType ,
941
- VarianceConvertibleConstructedType toType
934
+ UnboundGenericType ugt , VarianceConvertibleGenericType fromType ,
935
+ VarianceConvertibleGenericType toType
942
936
) {
943
937
exists (
944
938
TypeArgument fromTypeArgument0 , TypeArgument toTypeArgument0 , TypeArgument fromTypeArgument1 ,
@@ -953,7 +947,7 @@ private module Variance {
953
947
954
948
pragma [ nomagic]
955
949
private predicate convVarianceMultiple2Aux (
956
- UnboundGenericType ugt , VarianceConvertibleConstructedType toType , int i ,
950
+ UnboundGenericType ugt , VarianceConvertibleGenericType toType , int i ,
957
951
TypeArgument fromTypeArgument , TypeArgument toTypeArgument
958
952
) {
959
953
convTypeArgumentsSameUnbound ( ugt , fromTypeArgument , toTypeArgument , i ) and
@@ -962,8 +956,8 @@ private module Variance {
962
956
}
963
957
964
958
private predicate convVarianceMultiple2 (
965
- UnboundGenericType ugt , VarianceConvertibleConstructedType fromType ,
966
- VarianceConvertibleConstructedType toType , int i
959
+ UnboundGenericType ugt , VarianceConvertibleGenericType fromType ,
960
+ VarianceConvertibleGenericType toType , int i
967
961
) {
968
962
exists ( TypeArgument fromTypeArgument , TypeArgument toTypeArgument |
969
963
convVarianceMultiple2Aux ( ugt , toType , i , fromTypeArgument , toTypeArgument )
@@ -978,8 +972,8 @@ private module Variance {
978
972
*/
979
973
pragma [ nomagic]
980
974
predicate convVarianceMultiple (
981
- UnboundGenericType ugt , VarianceConvertibleConstructedType fromType ,
982
- VarianceConvertibleConstructedType toType , int i
975
+ UnboundGenericType ugt , VarianceConvertibleGenericType fromType ,
976
+ VarianceConvertibleGenericType toType , int i
983
977
) {
984
978
convVarianceMultiple01 ( ugt , fromType , toType ) and i = 1
985
979
or
0 commit comments