[[PageOutline]] = Module and Function Dependencies = == Concerning terminology == We say that module ''A'' depends on module ''B'' (''A -> B'') if there is at least one function call from ''A'' to ''B''. There is a ''cyclic dependency'', if ''B'' also depends directly (''B -> A'') or indirectly (e.g. ''B -> C -> A'') on ''A''. Apparently, dependency can be defined on the function level as well. For instance, in our previous example, function level cycle is only present if ''A:foo'' calls ''B:foo'' and ''B:foo'' calls ''A:foo''. Note that it is possible to have a cyclic dependency among modules while having no cyclic dependencies among their functions. For example, function calls from ''A:foo'' to ''B:foo'' and from ''B:foo2'' to ''A:foo2'' imply a cyclic dependency on the module level, but no one on the function level. == Possible Analysis == There are different kind of examinations that can be run considering dependencies. \\ First of all, the possibility of ''checking for cycles'' on RefactorErl database. This means that the program is going to look for loops on the given level, and returns with the path of the cycles. \\ If one wants to have a more visual view of the dependencies, there is the ''draw'' option. This will generate a ''.dot'' file, which latter can be converted to a desired image file format. The following picture will show us an example on function level: [[Image(dep_fun_before.png, 700px)]] This illustration shows the functions with their modules and the function calls made from one function to another. With red edges, it is easy to spot the cycles. Using tooltips more information can be gained. Everything related to the representation is explained later, in the wiki:Dependency/Functions#Representation section. Since in the case of a vast database, the generated picture of dependencies can be very complex and hard to figure out, there are different options how the user can narrow down the result, and get a more easier understandable view. For instance, it is possible just to receive an image of the graph which contains only the cycles, or to exclude the OTP modules from the result. \\ In every dependency option there is the opportunity to run the examination from a given function/module or a list of them. \\ Dependency analysis can be done via the following interfaces: * [ErlangShellInterface#Dependencyanalysis Erlang shell] * [WebInterface/DependencyExaminations Web interface] == Representation == === Function Level === Let's take an example to explain the meaning of the representation of dependency graphs, and work with the example shown in the beginning of the page. A {{{#!erlang ri:draw_dep([{level, func}, {type, all}]) }}} call was made, which generated a ''Graphviz dot file''. \\ [[Image(dep_fun_before.png, 700px)]] Explanation of the figure: * ROOT triangle - no actual purpose, functioning as a starting point, only appears in the representation * Rectangle/box nodes (eg.: {{{cycle1, a, test2}}}) - representing modules (colour: ''deep purple'') * Hexagon nodes (eg.: {{{f1/1, apply/3, test2/2}}}) - representing functions (colour: ''black'') * Double octagon nodes - representing opaque nodes (colour: ''black'', label colour: ''gray'') * Solid, continuous edge, normal arrowhead - normal edge indicating the modules from the root, and the modules and their definitions of functions (colour: ''black'') * Dashed edge, normal arrowhead - indicates that a function calls another function ({{{funcall}}}) (colour: ''black'') * Dashed edge, special arrowhead - indicated a function call, but also that it is a cyclic edge (colour: ''red'') The next figure was made after a {{{#!erlang ri:anal_dyn(). }}} was run, which is a dynamic analyser. Due to its work the call graph changes a bit, new types of nodes and edges are introduced. [[Image(dep_fun_after.png, 900px)]] Explanation of figure, new nodes, edges: * Double octagon nodes - representing opaque, -1 arity nodes (colour: ''black'', label colour: ''gray'') * Dotted edge, normal arrowhead - indicates an {{{ambcall, dyncall, may_be edge}}} (colour: ''black'') Every node and edge have tooltips. In the case of nodes it shows the adequate graph node, while considering edges it depicts the type of function call ({{{funcall, may_be, ambcall, dyncall}}}). Static calls are labelled by {{{funcall}}}. {{{Dyncall}}} means unambiguous dynamic calls, when the identifiers of the callee may be defined not at the call but at another program part, and their values are can be calculated by data-flow reaching. {{{Ambcall}}} relation denotes the fact that some of the arguments of the dynamic function call can not be detected statically. If the number of parameters is uncertain, then after the arity of the function will be -1. It is also indicated with a special node. For further details about the dynamic calls and their representation can be found in (wiki:DynamicCallAnalysis). When the applied function or module is uncertain, the tool represents it with an {{{opaque}}} node, and connects the possible functions/modules with {{{may_be}}} edges. The representation in the analysis now follows this, indicating the opaque nodes differently (described in the previous section, concerning drawings). We note here that tooltips may not be shown under certain browsers (for example Mozilla Firefox 7.0.1). If this happens, please try another browser. === Module Level === Similarly, at module level, after calling {{{#!erlang ri:draw_dep([{level, mod}, {type, all}]) }}} an analogous figure can be achieved. \\ [[Image(dep_mod.png, 500px)]] Explanation of figure: * Rectangle/box nodes (eg.: {{{cycle1, erlang, test2}}}) - representing modules (colour: ''deep purple'') * Doubleoctagon nodes (no example on the figure) - representing opaque nodes (colour: ''black'', label colour: ''gray'') * Dotted edge, normal arrowhead - indicates that a module calls another module (colour: ''black'') * Dotted edge, special arrowhead - indicated a module call, but also that it is a cyclic edge (colour: ''red'') The tooltip for edges shows a list the function pair: \\ {{{Call = {callee, called}, Tooltip = [] | [Call | Tooltip]}}} \\ Latter makes a connection between the modules with this call. === Examples for the representation of the results === * {{{#!erlang ri:draw_dep([{level, mod}, {gnode, erlang}]). }}} * {{{#!erlang ri:draw_dep([{level, mod}, {gnode, erlang}, {dot, "/home/working/dot/test.dot" }]). }}} * {{{#!erlang ri:draw_dep([{level, func}, {gnode, "lists:hd/1"}]). }}} * {{{#!erlang ri:draw_dep([{level, mod},{gnode, {'$gn', module, 4}}]). }}} * {{{#!erlang ri:draw_dep([{type, cycles}, {level, func}, {gnode, {'$gn', func, 36}}]). }}}