diff --git a/javascript/ql/lib/semmle/javascript/ApiGraphs.qll b/javascript/ql/lib/semmle/javascript/ApiGraphs.qll index 842feffad34..112c3d7cf7f 100644 --- a/javascript/ql/lib/semmle/javascript/ApiGraphs.qll +++ b/javascript/ql/lib/semmle/javascript/ApiGraphs.qll @@ -819,7 +819,7 @@ module API { * Holds if `rhs` is the right-hand side of a definition of a node that should have an * incoming edge from `base` labeled `lbl` in the API graph. */ - private predicate rhs(TApiNode base, Label::ApiLabel lbl, DataFlow::Node rhs) { + predicate rhs(TApiNode base, Label::ApiLabel lbl, DataFlow::Node rhs) { hasSemantics(rhs) and ( base = MkRoot() and @@ -1058,7 +1058,7 @@ module API { * Holds if `ref` is a use of a node that should have an incoming edge from `base` labeled * `lbl` in the API graph. */ - private predicate use(TApiNode base, Label::ApiLabel lbl, DataFlow::Node ref) { + predicate use(TApiNode base, Label::ApiLabel lbl, DataFlow::Node ref) { hasSemantics(ref) and ( base = MkRoot() and @@ -1706,6 +1706,43 @@ module API { import Cached + private module Debug { + private module FullInput implements StageInputSig { + pragma[inline] + predicate isAdditionalUseRoot(Node node) { none() } + + pragma[inline] + predicate isAdditionalDefRoot(Node node) { none() } + + bindingset[node] + predicate inScope(DataFlow::Node node) { any() } + } + + private module Full = Stage; + + query predicate missingDefNode(DataFlow::Node node) { + Full::rhs(_, _, node) and + not exists(MkDef(node)) + } + + query predicate missingUseNode(DataFlow::Node node) { + Full::use(_, _, node) and + not exists(MkUse(node)) + } + + query predicate lostEdge(Node pred, Label::ApiLabel lbl, Node succ) { + Full::edge(pred, lbl, succ) and + not Cached::edge(pred, lbl, succ) + } + + query predicate counts(int numEdges, int numOverlayEdges, float ratio) { + numEdges = count(Node pred, Label::ApiLabel lbl, Node succ | Full::edge(pred, lbl, succ)) and + numOverlayEdges = + count(Node pred, Label::ApiLabel lbl, Node succ | Stage2::edge(pred, lbl, succ)) and + ratio = numOverlayEdges / numEdges.(float) + } + } + /** * Holds if there is an edge from `pred` to `succ` in the API graph. */