@@ -181,18 +181,29 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
181
181
/** Holds if this type path is empty. */
182
182
predicate isEmpty ( ) { this = "" }
183
183
184
+ /** Gets the length of this path, assuming the length is at least 2. */
185
+ bindingset [ this ]
186
+ pragma [ inline_late]
187
+ private int length2 ( ) {
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
+
184
194
/** Gets the length of this path. */
185
195
bindingset [ this ]
186
196
pragma [ inline_late]
187
197
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 .length2 ( )
191
204
}
192
205
193
206
/** Gets the path obtained by appending `suffix` onto this path. */
194
- bindingset [ suffix, result ]
195
- bindingset [ this , result ]
196
207
bindingset [ this , suffix]
197
208
TypePath append ( TypePath suffix ) {
198
209
if this .isEmpty ( )
@@ -202,22 +213,37 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
202
213
then result = this
203
214
else (
204
215
result = this + "." + suffix and
205
- not result .length ( ) > getTypePathLimit ( )
216
+ (
217
+ not exists ( getTypePathLimit ( ) )
218
+ or
219
+ result .length2 ( ) <= getTypePathLimit ( )
220
+ )
221
+ )
222
+ }
223
+
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 ) {
232
+ if result .isEmpty ( )
233
+ then this .isEmpty ( ) and suffix .isEmpty ( )
234
+ else
235
+ if this .isEmpty ( )
236
+ then suffix = result
237
+ else (
238
+ result = this and suffix .isEmpty ( )
239
+ or
240
+ result = this + "." + suffix
206
241
)
207
242
}
208
243
209
244
/** Holds if this path starts with `tp`, followed by `suffix`. */
210
245
bindingset [ this ]
211
- 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
- )
220
- }
246
+ predicate isCons ( TypeParameter tp , TypePath suffix ) { this = TypePath:: consInverse ( tp , suffix ) }
221
247
}
222
248
223
249
/** Provides predicates for constructing `TypePath`s. */
@@ -232,9 +258,17 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
232
258
* Gets the type path obtained by appending the singleton type path `tp`
233
259
* onto `suffix`.
234
260
*/
235
- bindingset [ result ]
236
261
bindingset [ suffix]
237
262
TypePath cons ( TypeParameter tp , TypePath suffix ) { result = singleton ( tp ) .append ( suffix ) }
263
+
264
+ /**
265
+ * Gets the type path obtained by appending the singleton type path `tp`
266
+ * onto `suffix`.
267
+ */
268
+ bindingset [ result ]
269
+ TypePath consInverse ( TypeParameter tp , TypePath suffix ) {
270
+ result = singleton ( tp ) .appendInverse ( suffix )
271
+ }
238
272
}
239
273
240
274
/**
@@ -556,7 +590,7 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
556
590
TypeMention tm1 , TypeMention tm2 , TypeParameter tp , TypePath path , Type t
557
591
) {
558
592
exists ( TypePath prefix |
559
- tm2 .resolveTypeAt ( prefix ) = tp and t = tm1 .resolveTypeAt ( prefix .append ( path ) )
593
+ tm2 .resolveTypeAt ( prefix ) = tp and t = tm1 .resolveTypeAt ( prefix .appendInverse ( path ) )
560
594
)
561
595
}
562
596
@@ -899,7 +933,7 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
899
933
exists ( AccessPosition apos , DeclarationPosition dpos , TypePath pathToTypeParam |
900
934
tp = target .getDeclaredType ( dpos , pathToTypeParam ) and
901
935
accessDeclarationPositionMatch ( apos , dpos ) and
902
- adjustedAccessType ( a , apos , target , pathToTypeParam .append ( path ) , t )
936
+ adjustedAccessType ( a , apos , target , pathToTypeParam .appendInverse ( path ) , t )
903
937
)
904
938
}
905
939
@@ -998,7 +1032,9 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
998
1032
999
1033
RelevantAccess ( ) { this = MkRelevantAccess ( a , apos , path ) }
1000
1034
1001
- Type getTypeAt ( TypePath suffix ) { a .getInferredType ( apos , path .append ( suffix ) ) = result }
1035
+ Type getTypeAt ( TypePath suffix ) {
1036
+ a .getInferredType ( apos , path .appendInverse ( suffix ) ) = result
1037
+ }
1002
1038
1003
1039
/** Holds if this relevant access has the type `type` and should satisfy `constraint`. */
1004
1040
predicate hasTypeConstraint ( Type type , Type constraint ) {
@@ -1077,7 +1113,7 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
1077
1113
t0 = abs .getATypeParameter ( ) and
1078
1114
exists ( TypePath path3 , TypePath suffix |
1079
1115
sub .resolveTypeAt ( path3 ) = t0 and
1080
- at .getTypeAt ( path3 .append ( suffix ) ) = t and
1116
+ at .getTypeAt ( path3 .appendInverse ( suffix ) ) = t and
1081
1117
path = prefix0 .append ( suffix )
1082
1118
)
1083
1119
)
@@ -1149,7 +1185,7 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
1149
1185
not exists ( getTypeArgument ( a , target , tp , _) ) and
1150
1186
target = a .getTarget ( ) and
1151
1187
exists ( AccessPosition apos , DeclarationPosition dpos , Type base , TypePath pathToTypeParam |
1152
- accessBaseType ( a , apos , base , pathToTypeParam .append ( path ) , t ) and
1188
+ accessBaseType ( a , apos , base , pathToTypeParam .appendInverse ( path ) , t ) and
1153
1189
declarationBaseType ( target , dpos , base , pathToTypeParam , tp ) and
1154
1190
accessDeclarationPositionMatch ( apos , dpos )
1155
1191
)
@@ -1217,7 +1253,7 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
1217
1253
typeParameterConstraintHasTypeParameter ( target , dpos , pathToTp2 , _, constraint , pathToTp ,
1218
1254
tp ) and
1219
1255
AccessConstraint:: satisfiesConstraintTypeMention ( a , apos , pathToTp2 , constraint ,
1220
- pathToTp .append ( path ) , t )
1256
+ pathToTp .appendInverse ( path ) , t )
1221
1257
)
1222
1258
}
1223
1259
0 commit comments