Add go/print-cfg

This commit is contained in:
Owen Mansel-Chan
2026-05-13 14:34:35 +01:00
parent 0b769abdb5
commit 2d46e22b37
3 changed files with 58 additions and 1 deletions

53
go/ql/lib/printCfg.ql Normal file
View File

@@ -0,0 +1,53 @@
/**
* @name Print CFG
* @description Produces a representation of a file's Control Flow Graph.
* This query is used by the VS Code extension.
* @id go/print-cfg
* @kind graph
* @tags ide-contextual-queries/print-cfg
*/
import go
import semmle.go.controlflow.ControlFlowGraph
private import semmle.go.controlflow.ControlFlowGraphShared
external string selectedSourceFile();
private predicate selectedSourceFileAlias = selectedSourceFile/0;
external int selectedSourceLine();
private predicate selectedSourceLineAlias = selectedSourceLine/0;
external int selectedSourceColumn();
private predicate selectedSourceColumnAlias = selectedSourceColumn/0;
module ViewCfgQueryInput implements GoCfg::ControlFlow::ViewCfgQueryInputSig<File> {
predicate selectedSourceFile = selectedSourceFileAlias/0;
predicate selectedSourceLine = selectedSourceLineAlias/0;
predicate selectedSourceColumn = selectedSourceColumnAlias/0;
predicate cfgScopeSpan(
CfgScope scope, File file, int startLine, int startColumn, int endLine, int endColumn
) {
file = scope.getFile() and
scope.getLocation().getStartLine() = startLine and
scope.getLocation().getStartColumn() = startColumn and
exists(Location loc |
loc.getEndLine() = endLine and
loc.getEndColumn() = endColumn and
loc = scope.(FuncDef).getBody().getLocation()
)
or
file = scope.(File) and
startLine = 1 and
startColumn = 1 and
endLine = file.getNumberOfLines() and
endColumn = 999999
}
}
import GoCfg::ControlFlow::ViewCfgQuery<File, ViewCfgQueryInput>

View File

@@ -366,4 +366,6 @@ module ControlFlow {
class ControlFlowNode = ControlFlow::Node;
class CfgScope = GoCfg::CfgScope;
class Write = ControlFlow::WriteNode;

View File

@@ -26,6 +26,8 @@ module GoCfg {
private import Cfg2
import Public
class CfgScope = Ast::Callable;
/** Holds if `e` has an implicit field selection at `index` for `implicitField`. */
predicate implicitFieldSelection(Go::AstNode e, int index, Go::Field implicitField) {
Input::implicitFieldSelection(e, index, implicitField)
@@ -206,7 +208,7 @@ module GoCfg {
class Case extends AstNode {
Case() { none() }
AstNode getAPattern() { none() }
AstNode getPattern(int index) { none() }
Expr getGuard() { none() }