@@ -243,3 +243,85 @@ module MakeWithState<StateConfigSig Config> implements DataFlowSig {
243
243
244
244
import Impl< C >
245
245
}
246
+
247
+ signature class PathNodeSig {
248
+ /** Gets a textual representation of this element. */
249
+ string toString ( ) ;
250
+
251
+ /**
252
+ * Holds if this element is at the specified location.
253
+ * The location spans column `startcolumn` of line `startline` to
254
+ * column `endcolumn` of line `endline` in file `filepath`.
255
+ * For more information, see
256
+ * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
257
+ */
258
+ predicate hasLocationInfo (
259
+ string filepath , int startline , int startcolumn , int endline , int endcolumn
260
+ ) ;
261
+
262
+ /** Gets the underlying `Node`. */
263
+ Node getNode ( ) ;
264
+ }
265
+
266
+ signature module PathGraphSig< PathNodeSig PathNode> {
267
+ /** Holds if `(a,b)` is an edge in the graph of data flow path explanations. */
268
+ predicate edges ( PathNode a , PathNode b ) ;
269
+
270
+ /** Holds if `n` is a node in the graph of data flow path explanations. */
271
+ predicate nodes ( PathNode n , string key , string val ) ;
272
+
273
+ /**
274
+ * Holds if `(arg, par, ret, out)` forms a subpath-tuple, that is, flow through
275
+ * a subpath between `par` and `ret` with the connecting edges `arg -> par` and
276
+ * `ret -> out` is summarized as the edge `arg -> out`.
277
+ */
278
+ predicate subpaths ( PathNode arg , PathNode par , PathNode ret , PathNode out ) ;
279
+ }
280
+
281
+ module MergePathGraph<
282
+ PathNodeSig PathNode1, PathNodeSig PathNode2, PathGraphSig< PathNode1 > Graph1,
283
+ PathGraphSig< PathNode2 > Graph2> {
284
+ private newtype TPathNode =
285
+ TPathNode1 ( PathNode1 p ) or
286
+ TPathNode2 ( PathNode2 p )
287
+
288
+ class PathNode extends TPathNode {
289
+ PathNode1 asPathNode1 ( ) { this = TPathNode1 ( result ) }
290
+
291
+ PathNode2 asPathNode2 ( ) { this = TPathNode2 ( result ) }
292
+
293
+ string toString ( ) {
294
+ result = this .asPathNode1 ( ) .toString ( ) or
295
+ result = this .asPathNode2 ( ) .toString ( )
296
+ }
297
+
298
+ predicate hasLocationInfo (
299
+ string filepath , int startline , int startcolumn , int endline , int endcolumn
300
+ ) {
301
+ this .asPathNode1 ( ) .hasLocationInfo ( filepath , startline , startcolumn , endline , endcolumn ) or
302
+ this .asPathNode2 ( ) .hasLocationInfo ( filepath , startline , startcolumn , endline , endcolumn )
303
+ }
304
+
305
+ Node getNode ( ) {
306
+ result = this .asPathNode1 ( ) .getNode ( ) or
307
+ result = this .asPathNode2 ( ) .getNode ( )
308
+ }
309
+ }
310
+
311
+ module PathGraph implements PathGraphSig< PathNode > {
312
+ query predicate edges ( PathNode a , PathNode b ) {
313
+ Graph1:: edges ( a .asPathNode1 ( ) , b .asPathNode1 ( ) ) or
314
+ Graph2:: edges ( a .asPathNode2 ( ) , b .asPathNode2 ( ) )
315
+ }
316
+
317
+ query predicate nodes ( PathNode n , string key , string val ) {
318
+ Graph1:: nodes ( n .asPathNode1 ( ) , key , val ) or
319
+ Graph2:: nodes ( n .asPathNode2 ( ) , key , val )
320
+ }
321
+
322
+ query predicate subpaths ( PathNode arg , PathNode par , PathNode ret , PathNode out ) {
323
+ Graph1:: subpaths ( arg .asPathNode1 ( ) , par .asPathNode1 ( ) , ret .asPathNode1 ( ) , out .asPathNode1 ( ) ) or
324
+ Graph2:: subpaths ( arg .asPathNode2 ( ) , par .asPathNode2 ( ) , ret .asPathNode2 ( ) , out .asPathNode2 ( ) )
325
+ }
326
+ }
327
+ }
0 commit comments