@@ -1122,6 +1122,9 @@ module MakeWithSplitting<
11221122 /** Gets the scope of this node. */
11231123 CfgScope getScope ( ) { result = getNodeCfgScope ( this ) }
11241124
1125+ /** Gets the enclosing callable of this node. */
1126+ CfgScope getEnclosingCallable ( ) { result = this .getScope ( ) }
1127+
11251128 /** Gets a successor node of a given type, if any. */
11261129 Node getASuccessor ( SuccessorType t ) { result = getASuccessor ( this , t ) }
11271130
@@ -1310,160 +1313,19 @@ module MakeWithSplitting<
13101313 }
13111314 }
13121315
1313- /** A node to be included in the output of `TestOutput`. */
1314- signature class RelevantNodeSig extends Node ;
1315-
1316- /**
1317- * Import this module into a `.ql` file to output a CFG. The
1318- * graph is restricted to nodes from `RelevantNode`.
1319- */
1320- module TestOutput< RelevantNodeSig RelevantNode> {
1321- /** Holds if `pred -> succ` is an edge in the CFG. */
1322- query predicate edges ( RelevantNode pred , RelevantNode succ , string label ) {
1323- label =
1324- strictconcat ( SuccessorType t , string s |
1325- succ = getASuccessor ( pred , t ) and
1326- if t instanceof DirectSuccessor then s = "" else s = t .toString ( )
1327- |
1328- s , ", " order by s
1329- )
1330- }
1331-
1332- /**
1333- * Provides logic for representing a CFG as a [Mermaid diagram](https://mermaid.js.org/).
1334- */
1335- module Mermaid {
1336- private string nodeId ( RelevantNode n ) {
1337- result =
1338- any ( int i |
1339- n =
1340- rank [ i ] ( RelevantNode p , string filePath , int startLine , int startColumn , int endLine ,
1341- int endColumn |
1342- p .getLocation ( )
1343- .hasLocationInfo ( filePath , startLine , startColumn , endLine , endColumn )
1344- |
1345- p order by filePath , startLine , startColumn , endLine , endColumn , p .toString ( )
1346- )
1347- ) .toString ( )
1348- }
1349-
1350- private string nodes ( ) {
1351- result =
1352- concat ( RelevantNode n , string id , string text |
1353- id = nodeId ( n ) and
1354- text = n .toString ( )
1355- |
1356- id + "[\"" + text + "\"]" , "\n" order by id
1357- )
1358- }
1316+ private import PrintGraph as Pp
13591317
1360- private string edge ( RelevantNode pred , RelevantNode succ ) {
1361- edges ( pred , succ , _) and
1362- exists ( string label |
1363- edges ( pred , succ , label ) and
1364- if label = ""
1365- then result = nodeId ( pred ) + " --> " + nodeId ( succ )
1366- else result = nodeId ( pred ) + " -- " + label + " --> " + nodeId ( succ )
1367- )
1368- }
1318+ private module PrintGraphInput implements Pp:: InputSig< Location > {
1319+ class Callable = CfgScope ;
13691320
1370- private string edges ( ) {
1371- result =
1372- concat ( RelevantNode pred , RelevantNode succ , string edge , string filePath , int startLine ,
1373- int startColumn , int endLine , int endColumn |
1374- edge = edge ( pred , succ ) and
1375- pred .getLocation ( ) .hasLocationInfo ( filePath , startLine , startColumn , endLine , endColumn )
1376- |
1377- edge , "\n"
1378- order by
1379- filePath , startLine , startColumn , endLine , endColumn , pred .toString ( )
1380- )
1381- }
1321+ class ControlFlowNode = Node ;
13821322
1383- /** Holds if the Mermaid representation is `s`. */
1384- query predicate mermaid ( string s ) { s = "flowchart TD\n" + nodes ( ) + "\n\n" + edges ( ) }
1323+ ControlFlowNode getASuccessor ( ControlFlowNode n , SuccessorType t ) {
1324+ result = n . getASuccessor ( t )
13851325 }
13861326 }
13871327
1388- /** Provides the input to `ViewCfgQuery`. */
1389- signature module ViewCfgQueryInputSig< FileSig File> {
1390- /** The source file selected in the IDE. Should be an `external` predicate. */
1391- string selectedSourceFile ( ) ;
1392-
1393- /** The source line selected in the IDE. Should be an `external` predicate. */
1394- int selectedSourceLine ( ) ;
1395-
1396- /** The source column selected in the IDE. Should be an `external` predicate. */
1397- int selectedSourceColumn ( ) ;
1398-
1399- /**
1400- * Holds if CFG scope `scope` spans column `startColumn` of line `startLine` to
1401- * column `endColumn` of line `endLine` in `file`.
1402- */
1403- predicate cfgScopeSpan (
1404- CfgScope scope , File file , int startLine , int startColumn , int endLine , int endColumn
1405- ) ;
1406- }
1407-
1408- /**
1409- * Provides an implementation for a `View CFG` query.
1410- *
1411- * Import this module into a `.ql` that looks like
1412- *
1413- * ```ql
1414- * @name Print CFG
1415- * @description Produces a representation of a file's Control Flow Graph.
1416- * This query is used by the VS Code extension.
1417- * @id <lang>/print-cfg
1418- * @kind graph
1419- * @tags ide-contextual-queries/print-cfg
1420- * ```
1421- */
1422- module ViewCfgQuery< FileSig File, ViewCfgQueryInputSig< File > ViewCfgQueryInput> {
1423- private import ViewCfgQueryInput
1424-
1425- bindingset [ file, line, column]
1426- private CfgScope smallestEnclosingScope ( File file , int line , int column ) {
1427- result =
1428- min ( CfgScope scope , int startLine , int startColumn , int endLine , int endColumn |
1429- cfgScopeSpan ( scope , file , startLine , startColumn , endLine , endColumn ) and
1430- (
1431- startLine < line
1432- or
1433- startLine = line and startColumn <= column
1434- ) and
1435- (
1436- endLine > line
1437- or
1438- endLine = line and endColumn >= column
1439- )
1440- |
1441- scope order by startLine desc , startColumn desc , endLine , endColumn
1442- )
1443- }
1444-
1445- private import IdeContextual< File >
1446-
1447- private class RelevantNode extends Node {
1448- RelevantNode ( ) {
1449- this .getScope ( ) =
1450- smallestEnclosingScope ( getFileBySourceArchiveName ( selectedSourceFile ( ) ) ,
1451- selectedSourceLine ( ) , selectedSourceColumn ( ) )
1452- }
1453-
1454- string getOrderDisambiguation ( ) { result = "" }
1455- }
1456-
1457- private module Output = TestOutput< RelevantNode > ;
1458-
1459- import Output:: Mermaid
1460-
1461- /** Holds if `pred` -> `succ` is an edge in the CFG. */
1462- query predicate edges ( RelevantNode pred , RelevantNode succ , string attr , string val ) {
1463- attr = "semmle.label" and
1464- Output:: edges ( pred , succ , val )
1465- }
1466- }
1328+ import Pp:: PrintGraph< Location , PrintGraphInput >
14671329
14681330 /** Provides a set of consistency queries. */
14691331 module Consistency {
0 commit comments