@@ -223,16 +223,53 @@ module Impl implements RegexTreeViewSig {
223
223
*/
224
224
Location getLocation ( ) { result = re .getLocation ( ) }
225
225
226
+ /** Gets the accumulated length of string parts with lower index than `index`, if any. */
227
+ private int getPartOffset ( int index ) {
228
+ index = 0 and result = 0
229
+ or
230
+ index > 0 and
231
+ exists ( int previousOffset | previousOffset = this .getPartOffset ( index - 1 ) |
232
+ result =
233
+ previousOffset + re .( StrConst ) .getImplicitlyConcatenatedPart ( index - 1 ) .getContentLenght ( )
234
+ )
235
+ }
236
+
237
+ /**
238
+ * Gets the `StringPart` in which this `RegExpTerm` resides, if any.
239
+ * `localOffset` will be the offset of this `RegExpTerm` inside `result`.
240
+ */
241
+ StringPart getPart ( int localOffset ) {
242
+ exists ( int index , int prefixLength | index = max ( int i | this .getPartOffset ( i ) < start ) |
243
+ result = re .( StrConst ) .getImplicitlyConcatenatedPart ( index ) and
244
+ exists ( string prefix | result .context ( prefix , _) | prefixLength = prefix .length ( ) ) and
245
+ // Example:
246
+ // re.compile('...' r"""...this..""")
247
+ // - `start` is the offset from `(` to `this` as counted after concatenating all parts.
248
+ // - we subtract the lenght of the previous `StringPart`s, `'...'`, to know how far into this `StringPart` we go.
249
+ // - as the prefix 'r"""' is part of the `StringPart`, `this` is found that much further in.
250
+ localOffset = start - this .getPartOffset ( index ) + prefixLength
251
+ )
252
+ }
253
+
226
254
/** Holds if this term is found at the specified location offsets. */
227
255
predicate hasLocationInfo (
228
256
string filepath , int startline , int startcolumn , int endline , int endcolumn
229
257
) {
258
+ not exists ( this .getPart ( _) ) and
230
259
exists ( int re_start , int prefix_len | prefix_len = re .getPrefix ( ) .length ( ) |
231
260
re .getLocation ( ) .hasLocationInfo ( filepath , startline , re_start , endline , _) and
232
261
startcolumn = re_start + start + prefix_len and
233
262
endcolumn = re_start + end + prefix_len - 1
234
263
/* inclusive vs exclusive */
235
264
)
265
+ or
266
+ exists ( StringPart part , int localOffset | part = this .getPart ( localOffset ) |
267
+ filepath = part .getLocation ( ) .getFile ( ) .getAbsolutePath ( ) and
268
+ startline = part .getLocation ( ) .getStartLine ( ) and
269
+ startcolumn = part .getLocation ( ) .getStartColumn ( ) + localOffset and
270
+ endline = startline and
271
+ endcolumn = ( end - start ) + startcolumn
272
+ )
236
273
}
237
274
238
275
/** Gets the file in which this term is found. */
0 commit comments