diff --git a/shared/namebinding/codeql/namebinding/LocalNameBinding.qll b/shared/namebinding/codeql/namebinding/LocalNameBinding.qll index a467568f983..9aa265f161a 100644 --- a/shared/namebinding/codeql/namebinding/LocalNameBinding.qll +++ b/shared/namebinding/codeql/namebinding/LocalNameBinding.qll @@ -296,6 +296,31 @@ module LocalNameBinding ) } + /** Holds if `node` should be included in the debug tree. */ + private signature predicate relevantNodeSig(AstNode node); + + module DebugScopeGraph { + private string getANodeAnnotation(AstNode node) { + result = + "[scope=" + + strictconcat(string name | + declInScope(_, name, node) or implicitDeclInScope(name, node) + | + name, "," + ) + "]" + } + + query predicate nodes(AstNode node, string key, string value) { + relevantNode(node) and + key = "semmle.label" and + value = node.toString() + concat(getANodeAnnotation(node)) + } + + query predicate edges(AstNode node1, AstNode node2) { + relevantNode(node2) and node2 = getParentForScoping(node1) + } + } + /** Gets the immediately enclosing variable scope of `n`. */ private Scope getEnclosingScope(AstNode n) { result = getParentForScoping(n) diff --git a/unified/ql/lib/codeql/unified/internal/dev/debugScopeGraph.ql b/unified/ql/lib/codeql/unified/internal/dev/debugScopeGraph.ql new file mode 100644 index 00000000000..2f9376b1732 --- /dev/null +++ b/unified/ql/lib/codeql/unified/internal/dev/debugScopeGraph.ql @@ -0,0 +1,19 @@ +/** + * @name Debug scope graph + * @description Renders the graph used to perform local variable lookups + * @kind graph + * @id unified/debug-scope-graph + */ + +private import unified +private import codeql.unified.internal.Variables + +/** + * Holds if `node` should be shown in the graph. + */ +predicate relevantNode(AstNode node) { + // Match an ancestor node by location so its whole subtree is shown. + node.getParent*().getLocation().toString().matches("%test.swift@227:%") +} + +import LocalNameBindingOutput::DebugScopeGraph