@@ -38,27 +38,34 @@ class StringType extends TStringType {
3838 csvLabel = "nsstring-length"
3939 or
4040 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
4343 equivClass = this and
4444 csvLabel = "string-utf8-length"
4545 or
4646 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
4949 equivClass = TNsString ( ) and
5050 csvLabel = "string-utf16-length"
5151 or
5252 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
5555 equivClass = this and
5656 csvLabel = "string-unicodescalars-length"
5757 }
5858
59- /** Gets a textual representation of this string type. */
59+ /**
60+ * Gets a textual representation of this string type.
61+ */
6062 string toString ( ) { result = name }
6163
64+ /**
65+ * Gets the name of this string type.
66+ */
67+ string getName ( ) { result = name }
68+
6269 /**
6370 * Gets the equivalence class for this string type. If these are equal,
6471 * they should be treated as equivalent.
@@ -142,21 +149,16 @@ private class ExtraStringLengthConflationSource extends StringLengthConflationSo
142149 StringType stringType ;
143150
144151 ExtraStringLengthConflationSource ( ) {
145- exists ( MemberRefExpr memberRef , string typeName |
152+ // source is the result of a call to `[stringType].count`.
153+ exists ( MemberRefExpr memberRef |
146154 (
147- // result of a call to `String.utf8.count`
148- typeName = "String.UTF8View" and
149155 stringType = TStringUtf8 ( )
150156 or
151- // result of a call to `String.utf16.count`
152- typeName = "String.UTF16View" and
153157 stringType = TStringUtf16 ( )
154158 or
155- // result of a call to `String.unicodeScalars.count`
156- typeName = "String.UnicodeScalarView" and
157159 stringType = TStringUnicodeScalars ( )
158160 ) and
159- memberRef .getBase ( ) .getType ( ) .( NominalType ) .getName ( ) = typeName and
161+ memberRef .getBase ( ) .getType ( ) .( NominalType ) .getName ( ) = stringType . getName ( ) and
160162 memberRef .getMember ( ) .( VarDecl ) .getName ( ) = "count" and
161163 this .asExpr ( ) = memberRef
162164 )
@@ -180,14 +182,6 @@ private class StringLengthConflationSinks extends SinkModelCsv {
180182 override predicate row ( string row ) {
181183 row =
182184 [
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" ,
191185 ";String;true;index(_:offsetBy:);;;Argument[0..1];string-length" ,
192186 ";String;true;index(_:offsetBy:limitBy:);;;Argument[0..1];string-length" ,
193187 ";String.Index;true;init(encodedOffset:);;;Argument[0];string-length" ,
@@ -203,3 +197,45 @@ private class StringLengthConflationSinks extends SinkModelCsv {
203197 ]
204198 }
205199}
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