@@ -181,18 +181,29 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
181181 /** Holds if this type path is empty. */
182182 predicate isEmpty ( ) { this = "" }
183183
184+ /** Gets the length of this path, assuming the length is at least 2. */
185+ bindingset [ this ]
186+ pragma [ inline_late]
187+ private int lengthAtLeast2 ( ) {
188+ // Same as
189+ // `result = strictcount(this.indexOf(".")) + 1`
190+ // but performs better because it doesn't use an aggregate
191+ result = this .regexpReplaceAll ( "[0-9]+" , "" ) .length ( ) + 1
192+ }
193+
184194 /** Gets the length of this path. */
185195 bindingset [ this ]
186196 pragma [ inline_late]
187197 int length ( ) {
188- this .isEmpty ( ) and result = 0
189- or
190- result = strictcount ( this .indexOf ( "." ) ) + 1
198+ if this .isEmpty ( )
199+ then result = 0
200+ else
201+ if exists ( TypeParameter:: decode ( this ) )
202+ then result = 1
203+ else result = this .lengthAtLeast2 ( )
191204 }
192205
193206 /** Gets the path obtained by appending `suffix` onto this path. */
194- bindingset [ suffix, result ]
195- bindingset [ this , result ]
196207 bindingset [ this , suffix]
197208 TypePath append ( TypePath suffix ) {
198209 if this .isEmpty ( )
@@ -202,21 +213,40 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
202213 then result = this
203214 else (
204215 result = this + "." + suffix and
205- not result .length ( ) > getTypePathLimit ( )
216+ (
217+ not exists ( getTypePathLimit ( ) )
218+ or
219+ result .lengthAtLeast2 ( ) <= getTypePathLimit ( )
220+ )
206221 )
207222 }
208223
224+ /**
225+ * Gets the path obtained by appending `suffix` onto this path.
226+ *
227+ * Unlike `append`, this predicate has `result` in the binding set,
228+ * so there is no need to check the length of `result`.
229+ */
230+ bindingset [ this , result ]
231+ TypePath appendInverse ( TypePath suffix ) { suffix = result .stripPrefix ( this ) }
232+
233+ /** Gets the path obtained by removing `prefix` from this path. */
234+ bindingset [ this , prefix]
235+ TypePath stripPrefix ( TypePath prefix ) {
236+ if prefix .isEmpty ( )
237+ then result = this
238+ else (
239+ this = prefix and
240+ result .isEmpty ( )
241+ or
242+ this = prefix + "." + result
243+ )
244+ }
245+
209246 /** Holds if this path starts with `tp`, followed by `suffix`. */
210247 bindingset [ this ]
211248 predicate isCons ( TypeParameter tp , TypePath suffix ) {
212- tp = TypeParameter:: decode ( this ) and
213- suffix .isEmpty ( )
214- or
215- exists ( int first |
216- first = min ( this .indexOf ( "." ) ) and
217- suffix = this .suffix ( first + 1 ) and
218- tp = TypeParameter:: decode ( this .prefix ( first ) )
219- )
249+ suffix = this .stripPrefix ( TypePath:: singleton ( tp ) )
220250 }
221251 }
222252
@@ -232,7 +262,6 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
232262 * Gets the type path obtained by appending the singleton type path `tp`
233263 * onto `suffix`.
234264 */
235- bindingset [ result ]
236265 bindingset [ suffix]
237266 TypePath cons ( TypeParameter tp , TypePath suffix ) { result = singleton ( tp ) .append ( suffix ) }
238267 }
@@ -556,7 +585,7 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
556585 TypeMention tm1 , TypeMention tm2 , TypeParameter tp , TypePath path , Type t
557586 ) {
558587 exists ( TypePath prefix |
559- tm2 .resolveTypeAt ( prefix ) = tp and t = tm1 .resolveTypeAt ( prefix .append ( path ) )
588+ tm2 .resolveTypeAt ( prefix ) = tp and t = tm1 .resolveTypeAt ( prefix .appendInverse ( path ) )
560589 )
561590 }
562591
@@ -899,7 +928,7 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
899928 exists ( AccessPosition apos , DeclarationPosition dpos , TypePath pathToTypeParam |
900929 tp = target .getDeclaredType ( dpos , pathToTypeParam ) and
901930 accessDeclarationPositionMatch ( apos , dpos ) and
902- adjustedAccessType ( a , apos , target , pathToTypeParam .append ( path ) , t )
931+ adjustedAccessType ( a , apos , target , pathToTypeParam .appendInverse ( path ) , t )
903932 )
904933 }
905934
@@ -998,7 +1027,9 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
9981027
9991028 RelevantAccess ( ) { this = MkRelevantAccess ( a , apos , path ) }
10001029
1001- Type getTypeAt ( TypePath suffix ) { a .getInferredType ( apos , path .append ( suffix ) ) = result }
1030+ Type getTypeAt ( TypePath suffix ) {
1031+ a .getInferredType ( apos , path .appendInverse ( suffix ) ) = result
1032+ }
10021033
10031034 /** Holds if this relevant access has the type `type` and should satisfy `constraint`. */
10041035 predicate hasTypeConstraint ( Type type , Type constraint ) {
@@ -1077,7 +1108,7 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
10771108 t0 = abs .getATypeParameter ( ) and
10781109 exists ( TypePath path3 , TypePath suffix |
10791110 sub .resolveTypeAt ( path3 ) = t0 and
1080- at .getTypeAt ( path3 .append ( suffix ) ) = t and
1111+ at .getTypeAt ( path3 .appendInverse ( suffix ) ) = t and
10811112 path = prefix0 .append ( suffix )
10821113 )
10831114 )
@@ -1149,7 +1180,7 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
11491180 not exists ( getTypeArgument ( a , target , tp , _) ) and
11501181 target = a .getTarget ( ) and
11511182 exists ( AccessPosition apos , DeclarationPosition dpos , Type base , TypePath pathToTypeParam |
1152- accessBaseType ( a , apos , base , pathToTypeParam .append ( path ) , t ) and
1183+ accessBaseType ( a , apos , base , pathToTypeParam .appendInverse ( path ) , t ) and
11531184 declarationBaseType ( target , dpos , base , pathToTypeParam , tp ) and
11541185 accessDeclarationPositionMatch ( apos , dpos )
11551186 )
@@ -1217,7 +1248,7 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
12171248 typeParameterConstraintHasTypeParameter ( target , dpos , pathToTp2 , _, constraint , pathToTp ,
12181249 tp ) and
12191250 AccessConstraint:: satisfiesConstraintTypeMention ( a , apos , pathToTp2 , constraint ,
1220- pathToTp .append ( path ) , t )
1251+ pathToTp .appendInverse ( path ) , t )
12211252 )
12221253 }
12231254
0 commit comments