@@ -223,16 +223,53 @@ module Impl implements RegexTreeViewSig {
223223 */
224224 Location getLocation ( ) { result = re .getLocation ( ) }
225225
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+
226254 /** Holds if this term is found at the specified location offsets. */
227255 predicate hasLocationInfo (
228256 string filepath , int startline , int startcolumn , int endline , int endcolumn
229257 ) {
258+ not exists ( this .getPart ( _) ) and
230259 exists ( int re_start , int prefix_len | prefix_len = re .getPrefix ( ) .length ( ) |
231260 re .getLocation ( ) .hasLocationInfo ( filepath , startline , re_start , endline , _) and
232261 startcolumn = re_start + start + prefix_len and
233262 endcolumn = re_start + end + prefix_len - 1
234263 /* inclusive vs exclusive */
235264 )
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+ )
236273 }
237274
238275 /** Gets the file in which this term is found. */
0 commit comments