@@ -259,7 +259,7 @@ private module Gvn {
259259 private newtype TGvnType =
260260 TLeafGvnType ( LeafType t ) or
261261 TMethodTypeParameterGvnType ( int i ) { i = any ( MethodTypeParameter p ) .getIndex ( ) } or
262- TConstructedGvnType ( ConstructedGvnTypeList l )
262+ TConstructedGvnType ( ConstructedGvnTypeList l ) { l . isFullyConstructed ( ) }
263263
264264 private newtype TConstructedGvnTypeList =
265265 TConstructedGvnTypeNil ( Unification:: CompoundTypeKind k ) or
@@ -334,6 +334,10 @@ private module Gvn {
334334 )
335335 }
336336
337+ predicate isFullyConstructed ( ) {
338+ this .getKind ( ) .getNumberOfTypeParameters ( ) - 1 = this .length ( )
339+ }
340+
337341 private GvnType getArg ( int i ) {
338342 exists ( GvnType head , ConstructedGvnTypeList tail |
339343 this = TConstructedGvnTypeCons ( head , tail )
@@ -345,47 +349,71 @@ private module Gvn {
345349 )
346350 }
347351
352+ private Unification:: GenericType getConstructedGenericDeclaringTypeAt ( int i ) {
353+ i = 0 and
354+ result = this .getKind ( ) .getConstructedSourceDeclaration ( )
355+ or
356+ result = this .getConstructedGenericDeclaringTypeAt ( i - 1 ) .getGenericDeclaringType ( )
357+ }
358+
359+ private predicate isDeclaringTypeAt ( int i ) {
360+ exists ( this .getConstructedGenericDeclaringTypeAt ( i - 1 ) )
361+ }
362+
348363 /**
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>`.
364+ * Gets the `j`th `toString()` part of the `i`th nested component of this
365+ * constructed type, if any. The nested components are sorted in reverse
366+ * order, while the individual parts are sorted in normal order.
356367 */
357368 language [ monotonicAggregates]
358- private string toStringConstructed ( Unification:: GenericType t ) {
359- t = this .getKind ( ) .getConstructedSourceDeclaration ( ) .getGenericDeclaringType * ( ) and
360- exists ( int offset , int children , string name , string nameArgs |
361- offset = t .getNumberOfDeclaringArguments ( ) and
362- children = t .getNumberOfArgumentsSelf ( ) and
363- name = Unification:: getNameNested ( 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 + ">"
369+ private string toStringConstructedPart ( int i , int j ) {
370+ this .isFullyConstructed ( ) and
371+ exists ( Unification:: GenericType t |
372+ t = this .getConstructedGenericDeclaringTypeAt ( i ) and
373+ exists ( int offset , int children , string name |
374+ offset = t .getNumberOfDeclaringArguments ( ) and
375+ children = t .getNumberOfArgumentsSelf ( ) and
376+ name = Unification:: getNameNested ( t ) and
377+ if children = 0
378+ then
379+ j = 0 and result = name
380+ or
381+ this .isDeclaringTypeAt ( i ) and j = 1 and result = "."
382+ else (
383+ j = 0 and result = name .prefix ( name .length ( ) - children - 1 ) + "<"
384+ or
385+ j in [ 1 .. 2 * children - 1 ] and
386+ if j % 2 = 0
387+ then result = ","
388+ else result = this .getArg ( ( j + 1 ) / 2 + offset - 1 ) .toString ( )
389+ or
390+ j = 2 * children and
391+ result = ">"
392+ or
393+ this .isDeclaringTypeAt ( i ) and
394+ j = 2 * children + 1 and
395+ result = "."
375396 )
376- |
377- offset = 0 and result = nameArgs
378- or
379- result = this .toStringConstructed ( t .getGenericDeclaringType ( ) ) + "." + nameArgs
397+ )
380398 )
381399 }
382400
383401 language [ monotonicAggregates]
384402 string toString ( ) {
403+ this .isFullyConstructed ( ) and
385404 exists ( Unification:: CompoundTypeKind k | k = this .getKind ( ) |
386405 result = k .toStringBuiltin ( this .getArg ( 0 ) .toString ( ) )
387406 or
388- result = this .toStringConstructed ( k .getConstructedSourceDeclaration ( ) )
407+ result =
408+ strictconcat ( int i , int j |
409+ exists ( Unification:: GenericType t , int children |
410+ t = this .getConstructedGenericDeclaringTypeAt ( i ) and
411+ children = t .getNumberOfArgumentsSelf ( ) and
412+ if children = 0 then j = 0 else j in [ 0 .. 2 * children ]
413+ )
414+ |
415+ this .toStringConstructedPart ( i , j ) order by i desc , j
416+ )
389417 )
390418 }
391419
0 commit comments