@@ -250,7 +250,7 @@ private module Gvn {
250250
251251 private class LeafType extends Type {
252252 LeafType ( ) {
253- not exists ( this . getAChild ( ) ) and
253+ not this instanceof Unification :: GenericType and
254254 not this instanceof MethodTypeParameter and
255255 not this instanceof DynamicType
256256 }
@@ -267,7 +267,9 @@ private module Gvn {
267267 gvnConstructedCons ( _, _, _, head , tail )
268268 }
269269
270- private ConstructedGvnTypeList gvnConstructed ( Type t , Unification:: CompoundTypeKind k , int i ) {
270+ private ConstructedGvnTypeList gvnConstructed (
271+ Unification:: GenericType t , Unification:: CompoundTypeKind k , int i
272+ ) {
271273 result = TConstructedGvnTypeNil ( k ) and
272274 i = - 1 and
273275 k = Unification:: getTypeKind ( t )
@@ -278,14 +280,17 @@ private module Gvn {
278280 }
279281
280282 pragma [ noinline]
281- private GvnType gvnTypeChild ( Type t , int i ) { result = getGlobalValueNumber ( t .getChild ( i ) ) }
283+ private GvnType gvnTypeChildExt ( Unification:: GenericType t , int i ) {
284+ result = getGlobalValueNumber ( t .getChildExt ( i ) )
285+ }
282286
283287 pragma [ noinline]
284288 private predicate gvnConstructedCons (
285- Type t , Unification:: CompoundTypeKind k , int i , GvnType head , ConstructedGvnTypeList tail
289+ Unification:: GenericType t , Unification:: CompoundTypeKind k , int i , GvnType head ,
290+ ConstructedGvnTypeList tail
286291 ) {
287292 tail = gvnConstructed ( t , k , i - 1 ) and
288- head = gvnTypeChild ( t , i )
293+ head = gvnTypeChildExt ( t , i )
289294 }
290295
291296 /** Gets the global value number for a given type. */
@@ -319,6 +324,8 @@ private module Gvn {
319324 }
320325
321326 private class ConstructedGvnTypeList extends TConstructedGvnTypeList {
327+ Unification:: CompoundTypeKind getKind ( ) { this = gvnConstructed ( _, result , _) }
328+
322329 private int length ( ) {
323330 this = TConstructedGvnTypeNil ( _) and result = - 1
324331 or
@@ -338,17 +345,47 @@ private module Gvn {
338345 )
339346 }
340347
348+ /**
349+ * Gets a textual representation of this constructed type, restricted
350+ * to the prefix `t` of the underlying source declaration type.
351+ *
352+ * The `toString()` calculation needs to be split up into prefixes, in
353+ * order to apply the type arguments correctly. For example, a source
354+ * declaration type `A<>.B.C<,>` applied to types `int, string, bool`
355+ * needs to be printed as `A<int>.B.C<string,bool>`.
356+ */
357+ language [ monotonicAggregates]
358+ private string toStringConstructed ( Unification:: GenericType t ) {
359+ t = this .getKind ( ) .getConstructedSourceDeclaration ( ) .getQualifier * ( ) and
360+ exists ( int offset , int children , string name , string nameArgs |
361+ offset = t .getNumberOfQualifierChildrenExt ( ) and
362+ children = t .getNumberOfChildrenSelf ( ) and
363+ name = Unification:: getQualifiedName ( t ) and
364+ if children = 0
365+ then nameArgs = name
366+ else
367+ exists ( string offsetArgs |
368+ offsetArgs =
369+ concat ( int i |
370+ i in [ offset .. offset + children - 1 ]
371+ |
372+ this .getArg ( i ) .toString ( ) , "," order by i
373+ ) and
374+ nameArgs = name .prefix ( name .length ( ) - children - 1 ) + "<" + offsetArgs + ">"
375+ )
376+ |
377+ offset = 0 and result = nameArgs
378+ or
379+ result = this .toStringConstructed ( t .getQualifier ( ) ) + "." + nameArgs
380+ )
381+ }
382+
341383 language [ monotonicAggregates]
342384 string toString ( ) {
343- exists ( Unification:: CompoundTypeKind k , string args |
344- this = gvnConstructed ( _, k , _) and
345- args =
346- concat ( int i |
347- i in [ 0 .. k .getNumberOfTypeParameters ( ) - 1 ]
348- |
349- this .getArg ( i ) .toString ( ) , "," order by i
350- ) and
351- result = k .toString ( args )
385+ exists ( Unification:: CompoundTypeKind k | k = this .getKind ( ) |
386+ result = k .toStringBuiltin ( this .getArg ( 0 ) .toString ( ) )
387+ or
388+ result = this .toStringConstructed ( k .getConstructedSourceDeclaration ( ) )
352389 )
353390 }
354391
0 commit comments