@@ -224,25 +224,17 @@ signature module InputSig1<LocationSig Location> {
224224
225225module Make1< LocationSig Location, InputSig1< Location > Input1> {
226226 private import Input1
227+ private import codeql.util.UnboundList as UnboundListImpl
227228
228- private module TypeParameter {
229- private import codeql.util.DenseRank
229+ private module UnboundListInput implements UnboundListImpl :: InputSig < Location > {
230+ class Element = TypeParameter ;
230231
231- private module DenseRankInput implements DenseRankInputSig {
232- class Ranked = TypeParameter ;
232+ predicate getId = getTypeParameterId / 1 ;
233233
234- predicate getRank = getTypeParameterId / 1 ;
235- }
236-
237- int getRank ( TypeParameter tp ) { tp = DenseRank< DenseRankInput > :: denseRank ( result ) }
238-
239- string encode ( TypeParameter tp ) { result = getRank ( tp ) .toString ( ) }
240-
241- bindingset [ s]
242- TypeParameter decode ( string s ) { encode ( result ) = s }
234+ predicate getLengthLimit = getTypePathLimit / 0 ;
243235 }
244236
245- final private class String = string ;
237+ private import UnboundListImpl :: Make < Location , UnboundListInput >
246238
247239 /**
248240 * A path into a type.
@@ -274,101 +266,10 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
274266 * implementation uses unique type parameter identifiers, in order to not mix
275267 * up type parameters from different types.
276268 */
277- class TypePath extends String {
278- bindingset [ this ]
279- TypePath ( ) { exists ( this ) }
280-
281- bindingset [ this ]
282- private TypeParameter getTypeParameter ( int i ) {
283- result = TypeParameter:: decode ( this .splitAt ( "." , i ) )
284- }
285-
286- /** Gets a textual representation of this type path. */
287- bindingset [ this ]
288- string toString ( ) {
289- result =
290- concat ( int i , TypeParameter tp |
291- tp = this .getTypeParameter ( i )
292- |
293- tp .toString ( ) , "." order by i
294- )
295- }
296-
297- /** Holds if this type path is empty. */
298- predicate isEmpty ( ) { this = "" }
299-
300- /** Gets the length of this path. */
301- bindingset [ this ]
302- pragma [ inline_late]
303- int length ( ) {
304- // Same as
305- // `result = count(this.indexOf("."))`
306- // but performs better because it doesn't use an aggregate
307- result = this .regexpReplaceAll ( "[0-9]+" , "" ) .length ( )
308- }
309-
310- /** Gets the path obtained by appending `suffix` onto this path. */
311- bindingset [ this , suffix]
312- TypePath append ( TypePath suffix ) {
313- result = this + suffix and
314- (
315- not exists ( getTypePathLimit ( ) )
316- or
317- result .length ( ) <= getTypePathLimit ( )
318- )
319- }
320-
321- /**
322- * Gets the path obtained by appending `suffix` onto this path.
323- *
324- * Unlike `append`, this predicate has `result` in the binding set,
325- * so there is no need to check the length of `result`.
326- */
327- bindingset [ this , result ]
328- TypePath appendInverse ( TypePath suffix ) { suffix = result .stripPrefix ( this ) }
329-
330- /** Gets the path obtained by removing `prefix` from this path. */
331- bindingset [ this , prefix]
332- TypePath stripPrefix ( TypePath prefix ) { this = prefix + result }
333-
334- /** Holds if this path starts with `tp`, followed by `suffix`. */
335- bindingset [ this ]
336- predicate isCons ( TypeParameter tp , TypePath suffix ) {
337- exists ( string regexp | regexp = "([0-9]+)\\.(.*)" |
338- tp = TypeParameter:: decode ( this .regexpCapture ( regexp , 1 ) ) and
339- suffix = this .regexpCapture ( regexp , 2 )
340- )
341- }
342-
343- /** Holds if this path starts with `prefix`, followed by `tp`. */
344- bindingset [ this ]
345- predicate isSnoc ( TypePath prefix , TypeParameter tp ) {
346- exists ( string regexp | regexp = "(|.+\\.)([0-9]+)\\." |
347- prefix = this .regexpCapture ( regexp , 1 ) and
348- tp = TypeParameter:: decode ( this .regexpCapture ( regexp , 2 ) )
349- )
350- }
351-
352- /** Gets the head of this path, if any. */
353- bindingset [ this ]
354- TypeParameter getHead ( ) { result = this .getTypeParameter ( 0 ) }
355- }
269+ class TypePath = UnboundList ;
356270
357271 /** Provides predicates for constructing `TypePath`s. */
358- module TypePath {
359- /** Gets the empty type path. */
360- TypePath nil ( ) { result .isEmpty ( ) }
361-
362- /** Gets the singleton type path `tp`. */
363- TypePath singleton ( TypeParameter tp ) { result = TypeParameter:: encode ( tp ) + "." }
364-
365- /**
366- * Gets the type path obtained by appending the singleton type path `tp`
367- * onto `suffix`.
368- */
369- bindingset [ suffix]
370- TypePath cons ( TypeParameter tp , TypePath suffix ) { result = singleton ( tp ) .append ( suffix ) }
371- }
272+ module TypePath = UnboundList;
372273
373274 /**
374275 * A class that has a type tree associated with it.
@@ -600,11 +501,7 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
600501
601502 private TypeParameter getNthTypeParameter ( TypeAbstraction abs , int i ) {
602503 result =
603- rank [ i + 1 ] ( TypeParameter tp |
604- tp = abs .getATypeParameter ( )
605- |
606- tp order by TypeParameter:: getRank ( tp )
607- )
504+ rank [ i + 1 ] ( TypeParameter tp | tp = abs .getATypeParameter ( ) | tp order by getRank ( tp ) )
608505 }
609506
610507 /**
0 commit comments