You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

129 lines
3.7 KiB

/*
* vim: set ft=rust:
* vim: set ft=reason:
*
* Copyright (c) 2009 - 2013 Monoidics ltd.
* Copyright (c) 2013 - present Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
open! Utils;
/** Module for call graphs */
type in_out_calls = {
in_calls: int, /** total number of in calls transitively */
out_calls: int /** total number of out calls transitively */
};
type t; /** the type of a call graph */
/** A call graph consists of a set of nodes (Procname.t), and edges between them.
A node can be defined or undefined (to represent whether we have code for it).
In an edge from [n1] to [n2], indicating that [n1] calls [n2],
[n1] is the parent and [n2] is the child.
Node [n1] is dependent on [n2] if there is a path from [n1] to [n2]
using the child relationship. */
/** [add_edge cg f t] adds an edge from [f] to [t] in the call graph [cg].
The nodes are also added as undefined, unless already present. */
let add_edge: t => Procname.t => Procname.t => unit;
/** Add a node to the call graph as defined */
let add_defined_node: t => Procname.t => unit;
/** Check if [source] recursively calls [dest] */
let calls_recursively: t => Procname.t => Procname.t => bool;
/** Create an empty call graph */
let create: unit => t;
/** [extend cg1 gc2] extends [cg1] in place with nodes and edges from [gc2];
undefined nodes become defined if at least one side is. */
let extend: t => t => unit;
/** Return all the children of [n], whether defined or not */
let get_all_children: t => Procname.t => Procname.Set.t;
/** Compute the ancestors of the node, if not pre-computed already */
let get_ancestors: t => Procname.t => Procname.Set.t;
/** Compute the heirs of the node, if not pre-computed already */
let get_heirs: t => Procname.t => Procname.Set.t;
/** Return the in/out calls of the node */
let get_calls: t => Procname.t => in_out_calls;
/** Return the list of nodes which are defined */
let get_defined_nodes: t => list Procname.t;
/** Return the children of [n] which are defined */
let get_defined_children: t => Procname.t => Procname.Set.t;
/** Return the nodes dependent on [n] */
let get_dependents: t => Procname.t => Procname.Set.t;
/** Return the number of LOC of the source file */
let get_nLOC: t => int;
/** Return the list of nodes with calls */
let get_nodes_and_calls: t => list (Procname.t, in_out_calls);
/** Return all the nodes with their defined children */
let get_nodes_and_defined_children: t => list (Procname.t, Procname.Set.t);
/** Return the list of nodes, with defined flag, and the list of edges */
let get_nodes_and_edges: t => (list (Procname.t, bool), list (Procname.t, Procname.t));
/** Return the children of [n] which are not heirs of [n] and are defined */
let get_nonrecursive_dependents: t => Procname.t => Procname.Set.t;
/** Return the parents of [n] */
let get_parents: t => Procname.t => Procname.Set.t;
/** Return the ancestors of [n] which are also heirs of [n] */
let get_recursive_dependents: t => Procname.t => Procname.Set.t;
/** Return the path of the source file */
let get_source: t => DB.source_file;
/** Load a call graph from a file */
let load_from_file: DB.filename => option t;
/** Returns true if the node is defined */
let node_defined: t => Procname.t => bool;
/** Print the current call graph as a dotty file. If the filename is [None],
use the current file dir inside the DB dir. */
let save_call_graph_dotty: option DB.filename => (Procname.t => list 'a) => t => unit;
/** Save a call graph into a file */
let store_to_file: DB.filename => t => unit;