@@ -38,27 +38,34 @@ class StringType extends TStringType {
38
38
csvLabel = "nsstring-length"
39
39
or
40
40
this = TStringUtf8 ( ) and
41
- name = "String.utf8 " and
42
- singular = "a String.utf8 " and
41
+ name = "String.UTF8View " and
42
+ singular = "a String.UTF8View " and
43
43
equivClass = this and
44
44
csvLabel = "string-utf8-length"
45
45
or
46
46
this = TStringUtf16 ( ) and
47
- name = "String.utf16 " and
48
- singular = "a String.utf16 " and
47
+ name = "String.UTF16View " and
48
+ singular = "a String.UTF16View " and
49
49
equivClass = TNsString ( ) and
50
50
csvLabel = "string-utf16-length"
51
51
or
52
52
this = TStringUnicodeScalars ( ) and
53
- name = "String.unicodeScalars " and
54
- singular = "a String.unicodeScalars " and
53
+ name = "String.UnicodeScalarView " and
54
+ singular = "a String.UnicodeScalarView " and
55
55
equivClass = this and
56
56
csvLabel = "string-unicodescalars-length"
57
57
}
58
58
59
- /** Gets a textual representation of this string type. */
59
+ /**
60
+ * Gets a textual representation of this string type.
61
+ */
60
62
string toString ( ) { result = name }
61
63
64
+ /**
65
+ * Gets the name of this string type.
66
+ */
67
+ string getName ( ) { result = name }
68
+
62
69
/**
63
70
* Gets the equivalence class for this string type. If these are equal,
64
71
* they should be treated as equivalent.
@@ -142,21 +149,16 @@ private class ExtraStringLengthConflationSource extends StringLengthConflationSo
142
149
StringType stringType ;
143
150
144
151
ExtraStringLengthConflationSource ( ) {
145
- exists ( MemberRefExpr memberRef , string typeName |
152
+ // source is the result of a call to `[stringType].count`.
153
+ exists ( MemberRefExpr memberRef |
146
154
(
147
- // result of a call to `String.utf8.count`
148
- typeName = "String.UTF8View" and
149
155
stringType = TStringUtf8 ( )
150
156
or
151
- // result of a call to `String.utf16.count`
152
- typeName = "String.UTF16View" and
153
157
stringType = TStringUtf16 ( )
154
158
or
155
- // result of a call to `String.unicodeScalars.count`
156
- typeName = "String.UnicodeScalarView" and
157
159
stringType = TStringUnicodeScalars ( )
158
160
) and
159
- memberRef .getBase ( ) .getType ( ) .( NominalType ) .getName ( ) = typeName and
161
+ memberRef .getBase ( ) .getType ( ) .( NominalType ) .getName ( ) = stringType . getName ( ) and
160
162
memberRef .getMember ( ) .( VarDecl ) .getName ( ) = "count" and
161
163
this .asExpr ( ) = memberRef
162
164
)
@@ -180,14 +182,6 @@ private class StringLengthConflationSinks extends SinkModelCsv {
180
182
override predicate row ( string row ) {
181
183
row =
182
184
[
183
- ";Sequence;true;dropFirst(_:);;;Argument[0];string-length" ,
184
- ";Sequence;true;dropLast(_:);;;Argument[0];string-length" ,
185
- ";Sequence;true;prefix(_:);;;Argument[0];string-length" ,
186
- ";Sequence;true;suffix(_:);;;Argument[0];string-length" ,
187
- ";Collection;true;formIndex(_:offsetBy:);;;Argument[0..1];string-length" ,
188
- ";Collection;true;formIndex(_:offsetBy:limitBy:);;;Argument[0..1];string-length" ,
189
- ";Collection;true;removeFirst(_:);;;Argument[0];string-length" ,
190
- ";RangeReplaceableCollection;true;removeLast(_:);;;Argument[0];string-length" ,
191
185
";String;true;index(_:offsetBy:);;;Argument[0..1];string-length" ,
192
186
";String;true;index(_:offsetBy:limitBy:);;;Argument[0..1];string-length" ,
193
187
";String.Index;true;init(encodedOffset:);;;Argument[0];string-length" ,
@@ -203,3 +197,45 @@ private class StringLengthConflationSinks extends SinkModelCsv {
203
197
]
204
198
}
205
199
}
200
+
201
+ /**
202
+ * An extra sink that don't fit into the CSV scheme (because we care about the actual
203
+ * type the method is being called on, not just the type it's declared on).
204
+ */
205
+ private class ExtraStringLengthConflationSink extends StringLengthConflationSink {
206
+ StringType stringType ;
207
+
208
+ ExtraStringLengthConflationSink ( ) {
209
+ // sink is a length or offset argument of a call to `[stringType].[method]`.
210
+ exists ( CallExpr call |
211
+ (
212
+ stringType = TString ( )
213
+ or
214
+ stringType = TStringUtf8 ( )
215
+ or
216
+ stringType = TStringUtf16 ( )
217
+ or
218
+ stringType = TStringUnicodeScalars ( )
219
+ ) and
220
+ (
221
+ call .getQualifier ( ) .getType ( ) .( NominalType ) .getName ( ) = stringType .getName ( ) or
222
+ call .getQualifier ( ) .getType ( ) .( InOutType ) .getObjectType ( ) .( NominalType ) .getName ( ) =
223
+ stringType .getName ( )
224
+ ) and
225
+ (
226
+ call .getStaticTarget ( ) .getName ( ) =
227
+ [
228
+ "dropFirst(_:)" , "dropLast(_:)" , "prefix(_:)" , "suffix(_:)" , "removeFirst(_:)" ,
229
+ "removeLast(_:)"
230
+ ] and
231
+ this .asExpr ( ) = call .getArgument ( 0 ) .getExpr ( )
232
+ or
233
+ call .getStaticTarget ( ) .getName ( ) =
234
+ [ "formIndex(_:offsetBy:)" , "formIndex(_:offsetBy:limitBy:)" ] and
235
+ this .asExpr ( ) = call .getArgument ( [ 0 , 1 ] ) .getExpr ( )
236
+ )
237
+ )
238
+ }
239
+
240
+ override StringType getCorrectStringType ( ) { result = stringType }
241
+ }
0 commit comments