非常教程

Erlang 20参考手册

tools

xref

xref

模块摘要

交叉参考工具,用于分析函数,模块,应用程序和版本之间的依赖关系。

描述

Xref是一个交叉引用工具,可用于查找函数,模块,应用程序和发布之间的依赖关系。

功能之间的调用或者是本地调用一样f(),或 外部调用类似m:f()。 从BEAM文件中提取的模块数据包括本地功能,导出功能,本地调用和外部调用。默认情况下,对内置函数(BIF)的调用将被忽略,但如果builtins该模块的某些功能所接受的选项设置为true,则也会包含对BIF的调用。分析OTP版本决定哪些功能是BIF。功能对象被假定为被创建的地方(以及其他地方)。 未解决的调用是调用applyspawn具有可变模块,变量函数或可变参数。例子是M:F(a)apply(M, f, [a])spawn(m, f(), Args)。未解决的调用由变量模块已被原子替换的调用表示'$M_EXPR',变量函数已被原子替换'$F_EXPR',并且可变数量的参数已被替换为数字-1。上述实施例是通过调用表示'$M_EXPR':'$F_EXPR'/1'$M_EXPR':f/1,和m:'$F_EXPR'/-1。未解决的调用是外部调用的子集。

警告

未解决的调用使模块数据不完整,这意味着分析结果可能无效。

应用程序是模块的集合。模块的BEAM文件位于ebin应用程序目录的子目录中。应用程序目录的名称决定了应用程序的名称和版本。发行版是位于lib版本目录的子目录中的应用程序的集合。在设计原则书中还有更多关于应用程序和版本的信息。

外部参照服务器由名称标识,在创建新服务器时提供。每个Xref服务器都包含一组发布版本,一组应用程序和一组包含模块数据的模块。外部参照服务器是彼此独立的,并且所有的分析在一个单一的外部参照服务器(例外是功能的上下文进行评估m/1,并d/1其在所有不使用服务器)。Xref服务器的 模式决定在模块添加到服务器时从BEAM文件中提取哪些模块数据。从R7开始,使用该选项编译的BEAM文件debug_info包含所谓的调试信息,它是代码的抽象表示。在functions默认模式下,从调试信息中提取函数调用和行号。在modules模式下,调试信息如果存在则被忽略,但模块之间的依赖关系是从BEAM文件的其他部分提取的。该modules模式比模式显着减少时间和空间消耗functions,但可以完成的分析是有限的。

分析模块是已经用其模块的数据添加到外部参照服务器一起的模块。库模块是位于中提到的一些目录中的模块 库路径。如果库模块的某些导出函数被某些分析模块使用,则称该模块被使用。未知模块是一个模块,其既不是分析模块,也不是一个库模块,但其导出的函数由一些分析模块被使用。未知函数是一个使用的函数,既不是本地的,也不是由任何分析模块导出,也不是由任何库模块导出。未定义功能是一个外部使用的函数,不会被任何分析的模块或库模块导出。有了这个概念,本地函数可以是一个未定义的函数,也就是说,如果它是从某个模块外部使用的。所有未知功能也是未定义的功能;figure用户指南中有一个说明了这种关系。

从R9C开始,模块属性标记deprecated可用于向外部参考通知有关 弃用的功能以及可选地计划删除功能的情况。几个例子显示了这个想法:

-deprecated({f,1})。导出的函数f/1已弃用。没有人会说是否f/1会被删除。-deprecated({f,'_'})。所有导出的函数f/0f/1等等已被弃用。-deprecated(module)。模块中的所有导出函数都被弃用。相当于-deprecated({'_','_'}).-deprecated({g,1,next_version})。该功能g/1已弃用,将在下一版本中删除。-deprecated({g,2,next_major_release})。该功能g/2已弃用,将在下一个主要版本中删除。deprecated({g,3,eventually})。该功能g/3已被弃用,并最终被删除。deprecated({'_','_',eventually})。模块中的所有导出函数都将被弃用,并最终被删除。

在进行任何分析之前,必须设置模块数据。例如,交叉参考和未知函数在所有模块数据已知时计算。需要完整数据的功能(analyzeqvariables)采取自动设置数据的照顾。模块数据需要调用任何的后要设置(再次)addreplaceremoveset_library_pathupdate功能。

设置模块数据的结果是 Call Graph。(有向)图由一组顶点和一组(有向)边组成。边表示 函数,模块,应用程序或版本之间的调用(From,To)。从据说打电话到,并且被据说由From使用。Call Graph的顶点是所有模块数据的功能:分析模块的本地和导出函数; 使用BIF; 使用库模块的导出函数; 和未知的功能。功能module_info/0,1由编译器添加的内容包含在导出的函数中,但仅在从某个模块调用时。边是所有模块数据的函数调用。边的集合的结果是,如果函数在同一行代码上本地或外部多次使用,则只有一个边。

Call Graph由Erlang术语表示(集合是列表),适用于许多分析。但对于查看调用链的分析,列表表示太慢了。而是digraph使用模块提供的表示。Call Graph的列表表示或其子图的翻译digraph并不是免费的,因此用于表达下面将要描述的查询的语言具有用于该任务的特殊操作符并且可以保存该digraph表示进行后续分析。

除Call Graph外,还有一个图形叫做 Inter Call Graph。这是调用(From,To)的图形,以便在调用图中存在从From到To的调用链,并且每个From和To都是导出的函数或未使用的本地函数。顶点与调用图相同。

模块,应用程序和发布之间的调用也是有向图。这些图的顶点和边的 类型是(从最特殊到最一般的):Fun函数; Mod用于模块; App为应用程序; 和Rel发布。以下段落将描述用于选择和分析图的部分的语言的不同结构,从常量开始 :

  • Expression ::= Constants
  • Constants ::= Consts | Consts : Type | RegExpr
  • Consts ::= Constant | [Constant, ...] | {Constant, ...}
  • Constant ::= Call | Const
  • Call ::= FunSpec -> FunSpec | {MFA, MFA} | AtomConst -> AtomConst | {AtomConst, AtomConst}
  • Const ::= AtomConst | FunSpec | MFA
  • AtomConst ::= Application | Module | Release
  • FunSpec ::= Module : Function / Arity
  • MFA ::= {Module, Function, Arity}
  • RegExpr ::= RegString : Type | RegFunc | RegFunc : Type
  • RegFunc ::= RegModule : RegFunction / RegArity
  • RegModule ::= RegAtom
  • RegFunction ::= RegAtom
  • RegArity ::= RegString | Number | _ | -1
  • RegAtom ::= RegString | Atom | _
  • RegString ::= - a regular expression, as described in the re module, enclosed in double quotes -
  • Type ::= Fun | Mod | App | Rel
  • Function ::= Atom
  • Application ::= Atom
  • Module ::= Atom
  • Release ::= Atom
  • Arity ::= Number | -1
  • Atom ::= - same as Erlang atoms -
  • Number ::= - same as non-negative Erlang integers -

常量的例子有:kernelkernel->stdlib[kernel, sasl][pg -> mnesia, {tv, mnesia}] : Mod。如果某个实例Const不匹配任何图的任何顶点,则是错误的。如果有多个顶点匹配一个无类型的实例AtomConst,则选择最常用的类型之一。常量列表被解释为一组常量,全部是相同的类型。常量元组构成一系列调用(可能,但不一定对应某个图的实际调用链)。将类型分配给列表或元组Constant相当于将类型分配给每个元素Constant

正则表达式被用作选择图的一些顶点的手段。甲RegExpr组成的RegString和类型-一个例子"xref_.*" : Mod-被解释为那些模块(或应用或释放,这取决于类型)与表达式匹配的。类似地,a RegFunc被解释为与表达式匹配的Call Graph的顶点。一个例子是"xref_.*":"add_.*"/"(2|3)",它匹配add任何外部参照模块中的两个或三个参数的所有功能。另一个例子,一个匹配arity 10或更多的所有函数的例子:_:_/"[1-9].+"。这_是一个缩写".*",也就是说,匹配任何东西的正则表达式。

变量的语法 很简单:

  • Expression ::=变量
  • Variable ::= - 与Erlang变量相同 -

有两种变量:预定义变量和用户变量。 预定义变量保存设置模块数据,并且不能分配给查询,而只能用于查询。 另一方面,用户变量可以分配给用户,并且在评估查询时通常用于临时结果,并保留用于后续查询的查询结果。预定义变量是(以(*)标记的变量functions仅在模式下可用):

E调用图边(*)。V调用图形顶点(*)。M模块。所有模块:分析模块,使用库模块和未知模块。A应用。R发布。ME模块边缘。所有模块调用。AE应用程序边缘。所有应用程序调用 RE释放边缘。所有发布调用。L本地函数(*)。分析模块的所有本地功能。X导出的函数。分析模块的所有导出功能和所有使用库模块的导出功能。F函数 (*)。B使用BIF。B如果builtins适用false于所有分析的模块,则为空。U未知函数。UU未使用的函数(*)。分析模块的所有本地和导出功能尚未使用。XU外部使用的函数。所有模块的函数 - 包括本地函数 - 已用于某些外部调用。LU本地使用的函数(*)。在某些本地调用中使用的所有模块的函数。OL带有属性标记on_load(*)的函数。LC本地调用(*)。XC外部呼叫(*)。AM分析模块。UM未知模块。LM使用库模块。UC未解决的调用。在modules模式下清空。EE相互调用图边(*)。DF已弃用的函数。所有已弃用的导出函数和所有已使用的已弃用BIF。DF_1已弃用的函数。在下一个版本中将删除所有不推荐使用的函数。DF_2已弃用的函数。在下一个版本或下一个主要版本中将删除所有弃用的函数。DF_3已弃用的函数。在下一个版本,下一个主要版本或更高版本中将删除所有弃用的函数。

这些是关于预定义变量(集合运算符+(联合)和-(差异)以及演算运算符(类型的一些事实,)如下所述):

  • F等于L + X
  • V等于X + L + B + U,其中XLBU是两两不相交(即,没有任何元素常见)。
  • UU等于V - (XU + LU)LU并且XU可能具有共同的元素。换句话说:
  • V等于UU + XU + LU
  • OL是一个子集F
  • E等于LC + XC。请注意,LC并且XC可能具有相同的元素,即如果某个函数是从同一个函数本地和外部使用的。
  • U是一个子集XU
  • B是一个子集XU
  • LU等于range LC
  • XU等于range XC
  • LU是一个子集F
  • UU是一个子集F
  • range UC是一个子集U
  • M等于AM + LM + UM,在哪里AMLM并且UM是成对不相交的。
  • ME等于(Mod) E
  • AE等于(App) E
  • RE等于(Rel) E
  • (Mod) V是一个子集M。如果所有分析的模块都具有一些本地,导出或未知功能,则平等成立。
  • (App) M是一个子集A。如果所有应用程序都有一些模块,则平等成立
  • (Rel) A是一个子集R。如果所有版本都有一些应用程序,则平等成立
  • DF_1是一个子集DF_2
  • DF_2是一个子集DF_3
  • DF_3是一个子集DF
  • DF是一个子集X + B

一个重要的概念是表达式的 转换。强制表达式的语法是:

  • Expression ::= ( Type ) Expression

演员操作符的解释取决于指定的类型Type,类型Expression和解释元素的结构Expression。如果指定的类型等于表达式类型,则不进行转换。否则,转换一次只进行一步; (Fun) (App) RE,例如,相当于(Fun) (Mod) (App) RE。现在假定解释Expression是一组常量(函数,模块,应用程序或版本)。如果命名类型比表达式类型更普遍,比如说ModFun分别,那么对表达式的解释是在解释表达式时提到的至少有一个它们的功能的模块集合。如果指定的类型比表达式类型更特殊,比如说FunMod,则解释是模块的所有功能的集合(在modules模式中,由于本地功能未知,转换是部分的)。应用程序和版本之间的转换类似地工作。例如,(App) "xref_.*" : Mod返回至少包含一个模块的所有应用程序xref_,这些模块是模块名称的前缀。

现在假设解释Expression是一组调用。如果命名类型比表达式类型更普遍,比如说ModFun分别,那么对表达式的解释就是一组调用(M1,M2),这样表达式的解释就包含了从某个函数M1到某些函数的调用M2的功能。如果命名类型比表达式类型比较特殊,说FunMod,然后解释是集合所有的函数调用(F1,F2)这样的,表达的解释包含调用(M1,M2)和F1是一个函数的M1和F2是M2的一个函数(在modules模式中,没有函数调用,所以一个抛出Fun总是产生一个空集)。同样,应用程序和发布版本之间的转换工作也是类似的。

常数和变量的解释是集合,这些集合可以作为集合运算符应用形成新集合的基础 。语法:

  • Expression :: =表达式BinarySetOp表达式
  • BinarySetOp :: = +| *|-

+*-分别被解释为联合,交集和差异:两个集合的联合包含两个集合的元素; 两个集合的交集包含两个集合的共同元素; 并且两组的差别包含第一组中不是第二组成员的元素。两套的要素必须具有相同的结构; 例如,函数调用不能与函数组合。但是如果一个演员操作符可以使元素兼容,那么更一般的元素将转换为较不常用的元素类型。例如,M + F相当于(Fun) M + FE - AE相当于E - (Fun) AE。再举一个例子:X * xref : Mod被解释为模块输出的一组函数xref;xref : Mod被转换为更特殊的类型XFun也就是)产生所有函数xref,并且与X(被分析的模块和库模块导出的所有函数)的交集被解释为由某些模块函数导出的那些函数xref

还有一元集合运算符:

  • Expression ::= UnarySetOp Expression
  • UnarySetOp ::= domain | range | strict

回想一下,一个调用是一对 (From, To)。domain应用于一组调用被解释为所有顶点的集合From,并且range作为所有顶点To的集合。strict操作符的解释是删除窗体(A,A)上所有调用的操作数。

限制运算符的解释 是第一个操作数的一个子集,即一组调用。第二个操作数(一组顶点)被转换为第一个操作数的类型。限制运算符的语法:

  • Expression ::= Expression RestrOp Expression
  • RestrOp ::= |
  • RestrOp ::= ||
  • RestrOp ::= |||

这三位经营者的详细解释:

|来自任何顶点的调用的子集。||调用任何顶点的子集。|||调用往返于任何顶点的子集。对于所有的调用集CS和所有顶点集VSCS ||| VS 相当于CS | VS * CS || VS

如果两个函数(模块,应用程序和版本)直接互相呼叫(in),则它们属于同一强连接组件。components操作符的解释是一组调用的强连通组件。的condensation一组呼叫的是一组新的强连通分量,使得在这两个部件之间的边缘之间的呼叫,如果有一些恒定调用所述第二组分的一些恒定的第一组分。

of运算符的解释是第二个操作数(一组调用)的调用链,它按给定的顺序抛出第一个操作数(常量的一个元组)的所有顶点。第二个操作数转换为第一个操作数的类型。例如,of运算符可用于查明函数是否间接调用另一个函数,并且调用链演示如何。图分析操作符的语法:

  • Expression ::= Expression BinaryGraphOp Expression
  • Expression ::= UnaryGraphOp Expression
  • UnaryGraphOp ::= components | condensation
  • BinaryGraphOp ::= of

如前所述,图表分析对图的表示进行操作digraph。默认情况下,digraph表示在需要时创建(并在不再使用时删除),但也可以使用closure运算符显式创建:

  • Expression ::= ClosureOp Expression
  • ClosureOp ::= closure

closure操作符的解释是操作数的传递闭包。

限制操作符也被定义为关闭操作;closure E | xref : Mod被解释为来自xref模块的直接或间接函数调用,而解释E | xref : Mod是来自该模块的直接调用集合xref。如果要在多个图分析中使用某个图,则可以节省时间将图的digraph表示分配给用户变量,然后确保每个图分析对该变量进行操作,而不是对图的列表表示进行操作。

定义函数的行(更精确地说:第一个子句开始的地方)和函数使用的行在functions模式中可用。行号是指定义功能的文件。这也适用于包含在-include-include_lib指令中的文件,这些文件可能会导致明显在同一行中定义的函数。在固网运营商用于向功能分配行号和到函数调用分配组的行号。该语法与cast操作符的语法类似:

  • Expression ::= ( LineOp) Expression
  • Expression ::= ( XLineOp) Expression
  • LineOp ::= Lin | ELin | LLin | XLin
  • XLineOp ::= XXL

Lin应用于一组函数的操作符的解释会为每个函数分配函数定义的行号。库模块的未知功能和功能分配的编号为0。

应用于一组函数调用的某个LineOp运算符的解释会为每个调用分配第一个函数调用第二个函数的行号集。并非所有呼叫都由所有操作员分配了行号:

  • Lin操作者为调用图形边缘限定;
  • LLin运营商是为本地呼叫定义的。
  • XLin运营商的外部呼叫定义。
  • ELin运算符被定义为Inter Call Graph Edges。

LinLLinXLin)操作者指定其中调用(本地调用,外部调用)由行。的ELin操作者分配给每个呼叫(From, To),它被定义为其中,每个线L,使得在调用链从从到要开始与线L的呼叫

XXL操作者对任何应用到一组函数调用LineOp运营商的解释定义。结果是用函数调用行代替了函数调用,也就是说,调用的两个函数中的每一个都被一对函数和函数定义的行代替。该效果XXL操作员可以通过LineOp运营商被撤销。例如,(Lin) (XXL) (Lin) E相当于(Lin) E

如果操作数是兼容的+,那么-*#操作符是为行号表达式定义的。LineOp操作符也为模块,应用程序和发行版定义;操作数被隐式转换为函数。类似地,演员操作符被定义为解释LineOp操作符。

计数算子的解释 是一组元素的数量。操作员未定义关闭。的+-并且*在应用到运营商的数字被解释为明显的算术运算符。计数算子的语法:

  • Expression ::= CountOp Expression
  • CountOp ::= #

所有二元运算符都是关联的; 例如,A | B || C相当于(A | B) || C。以下是所有运营商的列表,按优先级顺序 排列

  • +, -
  • *
  • #
  • |, ||, |||
  • of
  • (Type)
  • closure, components, condensation, domain, range, strict

圆括号用于分组,可以使表达式更具可读性或覆盖运算符的默认优先级:

  • Expression ::= ( Expression )

一个 查询是报表的非空序列。语句是用户变量或表达式的赋值。赋值的值是右侧表达式的值。在其他任何地方放置一个简单的表达式,但最后在查询中放置是没有意义的 这些产品总结了查询的语法:

  • Query ::= Statement, ...
  • Statement ::= Assignment | Expression
  • Assignment ::= Variable := Expression | Variable = Expression

除非首先删除,否则不能为变量分配新值。由分配给变量=运营商在查询结束时去除,而被分配到变量:=运营商只能通过调用被删除forget。需要重新设置模块数据时没有用户变量; 如果调用任何需要重新设置模块数据的功能,则所有用户变量都将被遗忘。

类型

application() = atom()
arity() = int() | -1
bool() = true | false
call() = {atom(), atom()} | funcall()
constant() = mfa() | module() | application() | release()
directory() = string()
file() = string()
funcall() = {mfa(), mfa()}
function() = atom()
int() = integer() >= 0
library() = atom()
library_path() = path() | code_path
mfa() = {module(), function(), arity()}
mode() = functions | modules
module() = atom()
release() = atom()
string_position() = int() | at_end
variable() = atom()
xref() = atom() | pid()  

输出

add_application(Xref, Directory [, Options]) -> {ok, application()} | Error

类型

将应用程序,应用程序和module data模块的模块添加到Xref server。这些模块将成为应用程序的成员。默认情况下,使用删除版本作为应用程序名称的目录的基本名称,但可以通过该name选项覆盖此名称。返回应用程序的名称。

如果给定目录有一个名为子目录的子目录ebin,则在该目录中搜索模块(BEAM文件),否则将在给定目录中搜​​索模块。

如果mode外部参照服务器是functionsdebug information则忽略包含no的BEAM文件。

add_directory(Xref, Directory [, Options]) -> {ok, Modules} | Error

类型

将给定目录中找到的模块添加modules' dataXref server。默认不检查子目录,但是如果选项recurse具有该值true,则在所有级别的子目录中以及在给定目录中搜​​索模块。返回已添加模块的名称的已排序列表。

添加的模块不会是任何应用程序的成员。

如果mode外部参照服务器是functionsdebug information则忽略包含no的BEAM文件。

add_module(Xref, File [, Options]) -> {ok, module()} | Error

类型

添加一个模块并将其添加module dataXref server。该模块不会是任何应用程序的成员。返回模块的名称。

如果mode外部参照服务器是functions,并且BEAM文件不包含debug informationno_debug_info则返回错误消息。

add_release(Xref, Directory [, Options]) -> {ok, release()} | Error

类型

将发行版,发行版的应用程序,应用程序module data的模块以及模块添加到Xref server。应用程序将成为发行版的成员,并且这些模块将成为应用程序的成员。默认情况下是使用目录的基本名称作为发布名称,但是这可以被该name选项覆盖。返回发布的名称。

如果给定的目录具有一个名为的子目录lib,那么该目录中的目录被假定为应用程序目录,否则假定给定目录的所有子目录都是应用程序目录。如果某个应用程序有多个版本,则选择最高版本的版本。

如果mode外部参照服务器是functionsdebug information则忽略包含no的BEAM文件。

analyze(Xref, Analysis [, Options]) -> {ok, Answer} | Error

类型

评估预定义的分析。根据选择的分析结果返回一个没有call()或重复的排序列表constant()。对所有操作的预定义分析analyzed modulesfunctionsmode仅用(*)标记的分析仅可用):

undefined_function_calls**(*)返回到的调用列表undefined functionsundefined_functions返回一个列表undefined functionslocals_not_used* *(*)返回本地未使用的本地函数的列表。exports_not_used返回未被外部使用的导出函数列表。deprecated_function_calls**(*)返回外部调用列表deprecated functions{deprecated_function_calls, DeprFlag}* *(*)返回已弃用函数的外部调用列表。如果DeprFlag等于next_version,则返回要在下一版本中删除的函数的调用。如果DeprFlag等于next_major_release,则返回在下一个主要版本中要删除的函数的调用,以及在下一个版本中调用要删除的函数。最后,如果DeprFlag等于eventually,将返回所有对要删除的函数的调用,包括在下一个版本或下一个主要版本中要删除的函数的调用。deprecated_functions返回外部使用的弃用函数列表。{deprecated_functions, DeprFlag}返回外部使用的弃用函数列表。如果DeprFlag等于next_version,则返回要在下一版本中删除的功能。如果DeprFlag等于next_major_release,则将返回要在下一个主版本中删除的函数以及要在下一个版本中删除的函数。最后,如果DeprFlag等于eventually,则返回要删除的所有函数,包括要在下一个版本或下一个主要版本中删除的函数。{call, FuncSpec}**(*)返回一些给定函数调用的函数列表。{use, FuncSpec}* *(*)返回使用某些给定函数的函数列表。{module_call, ModSpec}返回一些给定模块调用的模块列表。{module_use, ModSpec}返回使用某些给定模块的模块列表。{application_call, AppSpec}返回由某些给定应用程序调用的应用程序列表。{application_use, AppSpec}返回使用某些给定应用程序的应用程序列表。{release_call, RelSpec}返回某些给定版本所调用的版本列表。{release_use, RelSpec}返回使用某些给定版本的发布列表。

d(Directory) -> [DebugInfoResult] | [NoDebugInfoResult] | Error

类型

在给定目录中找到的模块将被检查呼叫deprecated functions,呼叫undefined functions和未使用的本地功能。代码路径用作library path

如果发现一些BEAM文件包含debug information,则检查这些模块并返回元组列表。每个元组的第一个元素是以下之一:

  • deprecated,第二个元素是对已弃用函数的调用的排序列表;
  • undefined,第二个元素是未定义函数调用的排序列表;
  • unused,第二个元素是未使用的本地函数的排序列表。

如果没有BEAM文件包含调试信息,则返回元组列表。每个元组的第一个元素是以下之一:

  • deprecated,第二个元素是外部使用的弃用函数的排序列表;
  • undefined,第二个元素是一个未定义函数的排序列表。

forget(Xref) -> okforget(Xref, Variables) -> ok | Error

类型

forget/1forget/2删除所有或一些user variablesxref server

format_error(Error) -> Chars

类型

给定该模块的任何函数返回的错误,该函数format_error返回英文错误的描述性字符串。对于文件错误,该函数format_error/1将在file模块被调用。

get_default(Xref) -> [{Option, Value}]get_default(Xref, Option) -> {ok, Value} | Error

类型

返回一个或多个选项的默认值。

get_library_path(Xref) -> {ok, LibraryPath}

类型

返回library path

info(Xref) -> [Info]info(Xref, Category) -> [{Item, [Info]}]info(Xref, Category, Items) -> [{Item, [Info]}]

类型

info功能在有关国家和一些命令返回的信息作为对列表{标签,期限(1)} module dataXref server

info/1用以下标签返回信息(标有(*)的标签functions仅在模式下可用):

  • library_pathlibrary path
  • modemode
  • no_releases,发布数量;
  • no_applications,(所有版本的)申请总数;
  • no_analyzed_modules,总数analyzed modules
  • no_calls (*),总呼叫数量(在所有模块中),关于一个函数在不同线路中作为独立呼叫进行呼叫的实例;
  • no_function_calls(*)local calls,已解决的总数external callsunresolved calls
  • no_functions (*),本地和导出功能的总数;
  • no_inter_function_calls(*),呼叫总数Inter Call Graph

info/2info/3返回关于Xref服务器的全部或部分分析模块,应用程序,版本或库模块的信息。每个分析模块都会返回以下信息:

  • application,如果模块不属于任何应用程序,则为空列表,否则为应用程序名称的列表;
  • builtins,BIF的呼叫是否包含在模块的数据中;
  • directory,模块的BEAM文件所在的目录;
  • no_calls (*),关于不同线路中一次函数调用实例的调用次数作为独立调用;
  • no_function_calls (*),本地电话数量,已解决的外部调用和未解决的调用;
  • no_functions (*),本地和出口功能的数量;
  • no_inter_function_calls (*),互通呼叫图的呼叫数量;

每个应用程序都会返回以下信息:

  • directory,模块的BEAM文件所在的目录;
  • no_analyzed_modules,分析模块的数量;
  • no_calls (*),应用程序模块的调用次数,将不同行中的一次函数调用实例视为不同的调用次数;
  • no_function_calls (*),本地呼叫的数量,已解决的外部呼叫和应用程序模块的未解析调用;
  • no_functions (*),应用程序模块的本地和导出函数的数量;
  • no_inter_function_calls (*),应用程序模块的Inter Call Graph的调用次数;
  • release如果应用程序不属于任何发行版,则为空列表,否则为发行版名称的列表;
  • version,应用程序的版本作为数字列表。例如,目录“kernel-2.6”导致应用程序名称kernel和应用程序版本2,6; “内核”产生名称kernel和版本[]。

每个版本都会返回以下信息:

  • directory,发布目录;
  • no_analyzed_modules,分析模块的数量;
  • no_applications,申请数量;
  • no_calls (*),发布模块的调用次数,关于不同行中一次函数调用的实例作为独立调用;
  • no_function_calls (*),本地呼叫的数量,已解决的外部呼叫以及版本模块的未解决呼叫;
  • no_functions (*),发布模块的本地和导出功能的数量;
  • no_inter_function_calls (*),发布模块的互调图的调用次数。

每个库模块都会返回以下信息:

  • directorylibrary module'sBEAM文件所在的目录。

For every number of calls, functions etc. returned by the no_ tags, there is a query returning the same number. Listed below are examples of such queries. Some of the queries return the sum of a two or more of the no_ tags numbers. mod (app, rel) refers to any module (application, release).

  • no_analyzed_modules
-  `"# AM"` (info/1)
-  `"# (Mod) app:App"` (application)
-  `"# (Mod) rel:Rel"` (release)
  • no_applications
-  `"# A"` (info/1)
  • no_calls。已解决和未解析调用数量的总和:
-  `"# (XLin) E + # (LLin) E"` (info/1)
-  `"T = E | mod:Mod, # (LLin) T + # (XLin) T"` (module)
-  `"T = E | app:App, # (LLin) T + # (XLin) T"` (application)
-  `"T = E | rel:Rel, # (LLin) T + # (XLin) T"` (release)
  • no_functions。库模块中的函数和函数module_info/0,1不计算在内info。假设"Extra := _:module_info/\"(0|1)\" + LM"已经评估过,本地和导出函数的总和为:
-  `"# (F - Extra)"` (info/1)
-  `"# (F * mod:Mod - Extra)"` (module)
-  `"# (F * app:App - Extra)"` (application)
-  `"# (F * rel:Rel - Extra)"` (release)
  • no_function_calls。本地调用数量,已解决的外部调用数量和未解决的调用总数:
-  `"# LC + # XC"` (info/1)
-  `"# LC | mod:Mod + # XC | mod:Mod"` (module)
-  `"# LC | app:App + # XC | app:App"` (application)
-  `"# LC | rel:Rel + # XC | mod:Rel"` (release)
  • no_inter_function_calls
-  `"# EE"` (info/1)
-  `"# EE | mod:Mod"` (module)
-  `"# EE | app:App"` (application)
-  `"# EE | rel:Rel"` (release)
  • no_releases
-  `"# R"` (info/1)

m(Module) -> [DebugInfoResult] | [NoDebugInfoResult] | Errorm(File) -> [DebugInfoResult] | [NoDebugInfoResult] | Error

类型

检查给定的BEAM文件(带或不带.beam扩展名)或通过调用找到的文件以code:which(Module)检查是否有调用deprecated functions,调用undefined functions以及未使用的本地函数。代码路径用作library path

如果BEAM文件包含debug information,则返回元组列表。每个元组的第一个元素是以下之一:

  • deprecated,第二个元素是对已弃用函数的调用的排序列表;
  • undefined,第二个元素是未定义函数调用的排序列表;
  • unused,第二个元素是未使用的本地函数的排序列表。

如果BEAM文件不包含调试信息,则返回元组列表。每个元组的第一个元素是以下之一:

  • deprecated,第二个元素是外部使用的弃用函数的排序列表;
  • undefined,第二个元素是一个未定义函数的排序列表。

q(Xref, Query [, Options]) -> {ok, Answer} | Error

类型

Xref server的上下文中评估querya,并返回最后一条语句的值。该值的语法取决于表达式:

  • 一组调用由一个排序列表表示,没有重复call()
  • 一组常数由一个排序列表表示,没有重复constant()
  • 一组强连通的组件是一个没有重复的排序列表Component
  • 强连通组件之间的一组调用是一个没有重复的排序列表ComponentCall
  • 一连串的通话由一个列表表示constant()。该列表包含每个调用的From顶点和最后一个调用的To顶点。
  • of运营商将返回false如果没有给定的常数之间的调用链都可以找到。
  • closure运算符的值(digraph表示)由原子表示'closure()'
  • 一组行号功能由一个排序列表表示,没有重复DefineAt
  • 一组行编号的函数调用由一个排序列表表示,没有重复CallAt
  • 一组行编号的函数和函数调用由一个排序列表来表示,而不重复AllLines

对于两者CallAtAllLines它认为没有列表元素是LineNumbers一个空列表; 这些元素已被删除。常量component和整数LineNumbers被排序并且没有重复。

remove_application(Xref, Applications) -> ok | Error

类型

Xref server删除应用程序及其模块并module data

remove_module(Xref, Modules) -> ok | Error

类型

删除analyzed modulesmodule data从一个Xref server

remove_release(Xref, Releases) -> ok | Error

类型

Xref server删除发布及其应用程序,模块和module data

replace_application(Xref, Application, Directory [, Options]) -> {ok, application()} | Error

类型

用从应用程序目录读取的其他模块替换应用程序的模块。应用程序的发布成员资格被保留。请注意,该应用程序的名称保留; 没有使用给定目录的名称。

replace_module(Xref, Module, File [, Options]) -> {ok, module()} | Error

类型

替代对象module dataanalyzed module从一个BEAM文件中读取数据。模块的应用程序成员资格被保留,模块的builtins选项值也被保留。如果读取模块的名称与给定模块不同,则会返回错误。

update函数是更新重新编译模块的模块数据的替代方法。

set_default(Xref, Option, Value) -> {ok, OldValue} | Errorset_default(Xref, OptionValues) -> ok | Error

类型

设置一个或多个选项的默认值。可以用这种方式设置的选项是:

  • builtins,初始默认值false;
  • recurse,初始默认值false;
  • verbose,初始默认值false;
  • warnings,初始默认值true

初始默认值在创建时设置Xref server

set_library_path(Xref, LibraryPath [, Options]) -> ok | Error

类型

设置library path。如果给定的路径是目录列表,library modules则通过选择以给定顺序遍历目录时遇到的第一个模块来确定该集合,以找出发生在多个目录中的那些模块。默认情况下,库路径是一个空列表。

库路径 code_path被使用的功能m/1d/1,但也可以明确地设置。但请注意,library module在设置模块数据时,代码路径将每遍使用一次。另一方面,如果只有少数使用但未分析的模块,则使用code_path可能比将库路径设置为更快code:get_path()

如果库路径设置为code_path,则库集合模块集合未确定,并且这些info函数将返回库模块的空列表。

start(NameOrOptions) -> Return

类型

创建一个Xref server。该过程可以可选地被命名​​。默认modefunctions。外部参照不能识别的选项被传递给gen_server:start/4

start(Name, Options) -> Return

类型

Xref server用给定的名称创建一个。默认modefunctions。外部参照不能识别的选项被传递给gen_server:start/4

stop(Xref)

类型

停止Xref server

update(Xref [, Options]) -> {ok, Modules} | Error

类型

替换上一次读取module data的所有analyzed modulesBEAM文件被某个add函数或函数读取的文件update。模块的应用程序成员资格被保留,builtins选项的值也是如此。返回替换模块的名称的排序列表。

variables(Xref [, Options]) -> {ok, [VariableInfo]}

类型

返回一个变量名的有序列表Xref server。默认是返回user variables唯一的。

另请参阅

beam_lib(3), digraph(3), digraph_utils(3), re(3), TOOLS User's Guide

Erlang 20

Erlang 是一种通用的面向并发的编程语言,可应付大规模开发活动的程序设计语言和运行环境。

主页 https://www.erlang.org/
源码 https://github.com/erlang/otp
版本 20
发布版本 20.1