一种残膜回收机防缠绕挑膜装置的制 一种秧草收获机用电力驱动行走机构

生成调用关系的方法、装置、存储介质和电子设备与流程

2022-03-19 15:40:07 来源:中国专利 TAG:


1.本公开涉及电子信息技术领域,具体地,涉及一种生成调用关系的方法、装置、存储介质和电子设备。


背景技术:

2.随着互联网和云计算等信息技术的迅猛发展,应用市场上出现了各种各样的app(英文:application,中文:应用程序),以满足用户多样化的需求。要保证app能够为用户提供稳定的服务,需要对app所提供的各个业务进行监控。对于大流量的业务来说,可以通过大盘监控来发现故障,对于小流量的业务来说,由于问题不明显,受影响范围小,往往很难及时发现。但是小流量的业务出现问题,也会影响到用户的使用,并且很容易积累成严重的故障,因此需要对小流量的业务进行实时监控。
3.要对小流量的业务进行实时监控,通常需要基于app的代码中的方法路径,通过在关注的方法调用关系上进行标记,并插入检测代码来实现。然而,方法调用关系往往是通过技术人员人为进行源码分析,通过词法、语法解析,编写相应的匹配函数来收集的。这种调用关系的生成方式效率低,准确度不高。


技术实现要素:

4.本公开的目的是提供一种生成调用关系的方法、装置、存储介质和电子设备,用以解决现有技术中存在的生成调用关系的效率和准确度低的问题。
5.为了实现上述目的,根据本公开实施例的第一方面,提供一种生成调用关系的方法,所述方法包括:
6.获取目标源文件对应的抽象语法树中至少一个第一调用节点,所述第一调用节点为方法定义节点;
7.针对每个所述第一调用节点,获取所述抽象语法树中,该第一调用节点的子节点;
8.在该第一调用节点的子节点中,确定该第一调用节点对应的第一被调用节点,所述第一被调用节点为方法调用节点,且所述抽象语法树中所述第一被调用节点的子节点不包括块节点;
9.将该第一调用节点对应的第一调用方法,调用所述第一被调用节点对应的第一被调用方法,作为一个调用链;
10.根据全部所述调用链,生成所述目标源文件的调用关系。
11.可选地,所述获取目标源文件对应的抽象语法树中的至少一个第一调用节点,包括:
12.从所述抽象语法树包括的全部方法定义节点中,确定所述至少一个第一调用节点,每个所述第一调用节点存在对应的第一类节点,所述第一类节点为该第一调用节点的父节点,且所述第一类节点为类定义节点。
13.可选地,在所述将该第一调用节点对应的第一调用方法,调用所述第一被调用节
点对应的第一被调用方法,作为该第一调用节点的调用链之前,所述方法还包括:
14.获取该第一调用节点对应的所述第一类节点;
15.根据该第一调用节点和对应的所述第一类节点,获取所述第一调用节点的方法名,和所述第一调用节点所属的类名,以确定所述第一调用方法,并根据所述第一被调用节点,获取所述第一被调用节点的方法名,和所述第一被调用节点所属的类名,以确定所述第一被调用方法。
16.可选地,在所述获取所述抽象语法树中,该第一调用节点的子节点之后,所述方法还包括:
17.在该第一调用节点的子节点中,确定该第一调用节点对应的至少一个第二被调用节点,所述第二被调用节点为方法调用节点;
18.针对每个所述第二被调用节点,获取所述抽象语法树中,该第二被调用节点的父节点;
19.在该第二被调用节点的父节点中,确定该第二被调用节点对应的第二调用节点,所述第二调用节点为方法调用节点,且所述第二调用节点的子节点中包括块节点;
20.将所述第二调用节点对应的第二调用方法,调用该第二被调用节点对应的第二被调用方法,作为一个所述调用链。
21.可选地,在所述根据全部所述调用链,生成所述目标源文件的调用关系之前,所述方法还包括:
22.获取所述抽象语法树中的至少一个第三调用节点,所述第三调用节点为方法定义节点,且所述第三调用节点存在对应的第三类节点,所述第三类节点为该第三调用节点的父节点,且所述第三类节点为分类定义节点;
23.针对每个所述第三调用节点,获取所述抽象语法树中,该第三调用节点的子节点;
24.在该第三调用节点的子节点中,确定该第三调用节点对应的第三被调用节点,所述第三被调用节点为方法调用节点;
25.将该第三调用节点对应的第三调用方法,调用所述第三被调用节点对应的第三被调用方法,作为一个所述调用链。
26.可选地,在所述将该第三调用节点对应的第三调用方法,调用所述第三被调用节点对应的第三被调用方法,作为一个所述调用链之前,所述方法还包括:
27.获取该第三调用节点对应的所述第三类节点;
28.根据该第三调用节点和对应的所述第三类节点,获取该第三调用节点的方法名,和该第三调用节点所属的类名,以确定所述第三调用方法,并根据所述第三被调用节点,获取所述第三被调用节点的方法名,和所述第三被调用节点所属的类名,以确定所述第三被调用方法。
29.可选地,所述根据全部所述调用链,生成所述目标源文件的调用关系,包括:
30.若第一调用链中包括的调用方法,在调用所述第一调用链中包括的被调用方法时存在隐式调用,获取所述第一调用链中包括的被调用方法的属性信息,所述属性信息包括参数信息,和/或返回值信息,所述第一调用链为全部所述调用链中的任一调用链;
31.根据所述第一调用链中包括的被调用方法的所述属性信息,确定隐式调用链;
32.根据所述隐式调用链和全部所述调用链,生成所述目标源文件的所述调用关系。
33.可选地,所述目标源文件为多个,所述目标源文件属于目标工程,在所述根据全部所述调用链,生成所述目标源文件的调用关系之后,所述方法还包括:
34.根据多个所述目标源文件的所述调用关系,生成所述目标工程的调用关系树。
35.根据本公开实施例的第二方面,提供一种生成调用关系的装置,所述装置包括:
36.第一获取模块,被配置为用于获取目标源文件对应的抽象语法树中至少一个第一调用节点,所述第一调用节点为方法定义节点;
37.第二获取模块,被配置为用于针对每个所述第一调用节点,获取所述抽象语法树中,该第一调用节点的子节点;在该第一调用节点的子节点中,确定该第一调用节点对应的第一被调用节点,所述第一被调用节点为方法调用节点,且所述抽象语法树中所述第一被调用节点的子节点不包括块节点;将该第一调用节点对应的第一调用方法,调用所述第一被调用节点对应的第一被调用方法,作为一个调用链;
38.第一生成模块,被配置为用于根据全部所述调用链,生成所述目标源文件的调用关系。
39.可选地,所述第一获取模块被配置为用于:
40.从所述抽象语法树包括的全部方法定义节点中,确定所述至少一个第一调用节点,每个所述第一调用节点存在对应的第一类节点,所述第一类节点为该第一调用节点的父节点,且所述第一类节点为类定义节点。
41.可选地,所述第二获取模块还被配置为用于:
42.在所述将该第一调用节点对应的第一调用方法,调用所述第一被调用节点对应的第一被调用方法,作为该第一调用节点的调用链之前,获取该第一调用节点对应的所述第一类节点;
43.根据该第一调用节点和对应的所述第一类节点,获取所述第一调用节点的方法名,和所述第一调用节点所属的类名,以确定所述第一调用方法,并根据所述第一被调用节点,获取所述第一被调用节点的方法名,和所述第一被调用节点所属的类名,以确定所述第一被调用方法。
44.可选地,所述第二获取模块还被配置为用于:
45.在所述获取所述抽象语法树中,该第一调用节点的子节点之后,在该第一调用节点的子节点中,确定该第一调用节点对应的至少一个第二被调用节点,所述第二被调用节点为方法调用节点;
46.针对每个所述第二被调用节点,获取所述抽象语法树中,该第二被调用节点的父节点;
47.在该第二被调用节点的父节点中,确定该第二被调用节点对应的第二调用节点,所述第二调用节点为方法调用节点,且所述第二调用节点的子节点中包括块节点;
48.将所述第二调用节点对应的第二调用方法,调用该第二被调用节点对应的第二被调用方法,作为一个所述调用链。
49.可选地,所述第二获取模块还被配置为用于:
50.获取所述抽象语法树中的至少一个第三调用节点,所述第三调用节点为方法定义节点,且所述第三调用节点存在对应的第三类节点,所述第三类节点为该第三调用节点的父节点,且所述第三类节点为分类定义节点;
51.针对每个所述第三调用节点,获取所述抽象语法树中,该第三调用节点的子节点;
52.在该第三调用节点的子节点中,确定该第三调用节点对应的第三被调用节点,所述第三被调用节点为方法调用节点;
53.将该第三调用节点对应的第三调用方法,调用所述第三被调用节点对应的第三被调用方法,作为一个所述调用链。
54.可选地,所述第二获取模块还被配置为用于:
55.在所述将该第三调用节点对应的第三调用方法,调用所述第三被调用节点对应的第三被调用方法,作为一个所述调用链之前,获取该第三调用节点对应的所述第三类节点;
56.根据该第三调用节点和对应的所述第三类节点,获取该第三调用节点的方法名,和该第三调用节点所属的类名,以确定所述第三调用方法,并根据所述第三被调用节点,获取所述第三被调用节点的方法名,和所述第三被调用节点所属的类名,以确定所述第三被调用方法。
57.可选地,所述第一生成模块包括:
58.获取子模块,被配置为用于若第一调用链中包括的调用方法,在调用所述第一调用链中包括的被调用方法时存在隐式调用,获取所述第一调用链中包括的被调用方法的属性信息,所述属性信息包括参数信息,和/或返回值信息,所述第一调用链为全部所述调用链中的任一调用链;
59.确定子模块,被配置为用于根据所述第一调用链中包括的被调用方法的所述属性信息,确定隐式调用链;
60.生成子模块,被配置为用于根据所述隐式调用链和全部所述调用链,生成所述目标源文件的所述调用关系。
61.可选地,所述装置还包括:
62.第二生成模块,被配置为用于根据多个所述目标源文件的所述调用关系,生成所述目标工程的调用关系树。
63.根据本公开实施例的第三方面,提供一种计算机可读存储介质,其上存储有计算机程序,该计算机程序被处理器执行时实现第一方面提供的生成调用关系的方法的步骤。
64.根据本公开实施例的第四方面,提供一种电子设备,包括:
65.存储器,其上存储有计算机程序;
66.处理器,用于执行所述存储器中的所述计算机程序,以实现第一方面提供的生成调用关系的方法的步骤。
67.通过上述技术方案,本公开首先在目标源文件对应的抽象语法树中,筛选出至少一个第一调用节点,第一调用节点为方法定义节点,之后针对每个第一调用节点,在抽象语法树中查找该第一调用节点的子节点,再确定该第一调用节点的子节点中,对应的第一被调用节点,其中,第一被调用节点为方法调用节点,且抽象语法树中第一被调用节点的子节点不包括块节点,然后将该第一调用节点对应的第一调用方法,调用第一被调用节点对应的第一被调用方法,作为一个调用链,最后根据全部的调用链,生成目标源文件的调用关系。本公开通过对抽象语法树中的节点进行筛选,提取出其中包括的调用方法和被调用方法之间的调用链,从而根据调用链自动、准确地生成调用关系,提高了调用关系的生成效率。
68.本公开的其他特征和优点将在随后的具体实施方式部分予以详细说明。
附图说明
69.附图是用来提供对本公开的进一步理解,并且构成说明书的一部分,与下面的具体实施方式一起用于解释本公开,但并不构成对本公开的限制。在附图中:
70.图1是根据一示例性实施例示出的一种生成调用关系的方法的流程图;
71.图2是根据一示例性实施例示出的一种调用关系的示意图;
72.图3是根据一示例性实施例示出的另一种生成调用关系的方法的流程图;
73.图4是根据一示例性实施例示出的另一种生成调用关系的方法的流程图;
74.图5是根据一示例性实施例示出的另一种调用关系的示意图;
75.图6是根据一示例性实施例示出的另一种生成调用关系的方法的流程图;
76.图7是根据一示例性实施例示出的另一种生成调用关系的方法的流程图;
77.图8是根据一示例性实施例示出的另一种调用关系的示意图;
78.图9是根据一示例性实施例示出的另一种生成调用关系的方法的流程图;
79.图10是根据一示例性实施例示出的另一种生成调用关系的方法的流程图;
80.图11是根据一示例性实施例示出的一种调用关系树的示意图;
81.图12是根据一示例性实施例示出的一种生成调用关系的装置的框图;
82.图13是根据一示例性实施例示出的另一种生成调用关系的装置的框图;
83.图14是根据一示例性实施例示出的另一种生成调用关系的装置的框图;
84.图15是根据一示例性实施例示出的一种电子设备的框图。
具体实施方式
85.这里将详细地对示例性实施例进行说明,其示例表示在附图中。下面的描述涉及附图时,除非另有表示,不同附图中的相同数字表示相同或相似的要素。以下示例性实施例中所描述的实施方式并不代表与本公开相一致的所有实施方式。相反,它们仅是与如所附权利要求书中所详述的、本公开的一些方面相一致的装置和方法的例子。
86.在介绍本公开提供的生成调用关系的方法、装置、存储介质和电子设备之前,首先对本公开中各个实施例所涉及的应用场景进行介绍。该应用场景可以任一种app,例如可以是基于ios平台的app。实现app的代码作为一个工程,其中包括了多个源文件。每个源文件都有一个对应的抽象语法树(英文:abstract syntax tree,缩写:ast),是该源文件中的代码的一种抽象表示。其中,抽象语法树可以通过clang/llvm提供的astmatchers接口来进行分析。抽象语法树中包括多个节点,每个节点都表示源文件中的一种结构。例如:objcmethoddecl节点为方法定义节点,代表了objective-c中定义方法的结构,其中包括了方法的实现体。objcimplementationdecl节点为类定义节点,代表了objective-c中定义类的结构,其中包括了完整的类的实现部分。objcmessageexpr节点为方法调用节点,代表了objective-c中方法调用的结构,可以理解为源文件中每一次方法调用,都会有一个对应的objcmessageexpr节点。blockexpr节点为块节点,代表了objective-c中块表达式的结构,其中包括了块(即block)的实现。objccategoryimpldecl节点为分类定义节点,代表了objective-c定义分类(即:category)的结构,其中包括了完整的分类的实现部分。
87.图1是根据一示例性实施例示出的一种生成调用关系的方法的流程图,如图1所示,该方法可以包括以下步骤:
88.步骤101,获取目标源文件对应的抽象语法树中至少一个第一调用节点,第一调用节点为方法定义节点。
89.举例来说,目标源文件可以是app对应的目标工程中的任一源文件,目标源文件例如可以是.m格式的文件。首先获取目标源文件对应的抽象语法树,再从抽象语法树中,筛选出至少一个第一调用节点。第一调用节点为抽象语法树中的方法定义节点(即objcmethoddecl节点),第一调用节点对应一个方法,其中包括了该方法的实现体,也就是说第一调用节点是对应的方法的定义,而不是对应的方法的声明。进一步的,还可以规定第一调用节点存在一个父节点,且该父节点为类定义节点(即objcimplementationdecl节点)。具体的,可以按照dsl(英文:domain specified language,中文:领域专用语言)的语法规则,来编写适用于第一调用节点的第一匹配规则(即matcher),然后在抽象语法树中查找符合第一匹配规则的第一调用节点,第一匹配规则例如可以是:objcmethoddecl()matcher。
90.步骤102,针对每个第一调用节点,获取抽象语法树中,该第一调用节点的子节点。
91.步骤103,在该第一调用节点的子节点中,确定该第一调用节点对应的第一被调用节点,第一被调用节点为方法调用节点,且抽象语法树中第一被调用节点的子节点不包括块节点。
92.步骤104,将该第一调用节点对应的第一调用方法,调用第一被调用节点对应的第一被调用方法,作为一个调用链。
93.示例的,针对至少一个第一调用节点中的每个第一调用节点,获取抽象语法树中该第一调用节点的子节点,该第一调用节点的子节点可以为一个,也可以为多个。然后在该第一调用节点的子节点中,筛选出第一被调用节点,第一被调用节点同样也对应一个方法,第一被调用节点可以为一个或多个。第一被调用节点满足两个条件:条件一,第一被调用节点为方法调用节点;条件二,抽象语法树中第一被调用节点的子节点(可以为一个或多个)中不包括块节点(即blockexpr节点)。其中,条件一可以理解为该第一调用节点对应的方法中,调用了第一被调用节点对应的方法。条件二可以理解为第一被调用节点中的参数不包括块,也就是说,第一被调用节点对应的方法中,没有调用块中定义的方法。需要说明的是,如果抽象语法树中,该第一调用节点不存在的子节点,表示该第一调用节点对应的方法没有调用其他方法(该第一调用节点可能会被其他方法调用)。需要说明的是,上述第一调用节点对应的方法,和第一被调用节点对应的方法,可以理解目标源文件中普通的oc方法,即不属于块,也不属于分类的方法。
94.在确定该第一调用节点和对应的第一被调用节点后,可以确定第一调用节点对应的第一调用方法,和第一被调用节点对应的第一被调用方法,然后将第一调用方法,调用第一被调用方法,作为一个调用链。需要说明的是,若只存在一个第一被调用节点,那么步骤104中得到一个调用链,若存在n(n为大于1的自然数)个第一被调用节点,那么步骤104可以执行n次,得到n个调用链。其中,调用链可以理解为调用方法(即caller)调用被调用方法(即callee),即调用链由调用方法和被调用方法组成,如果将调用链用有向边来表示,那么调用链为从调用方法指向被调用方法的边。例如,在确定第一调用方法时,可以将第一调用
方法标记为caller,将第一被调用方法标记为callee,这样调用链即为caller指向callee的边。
95.步骤105,根据全部调用链,生成目标源文件的调用关系。
96.示例的,在得到全部第一调用节点的调用链之后,可以根据全部调用链来生成目标源文件的调用关系。调用关系可以理解为多个调用链的集合,如果将调用链用有向边来表示,那么调用关系可以用有向图来表示。可以将多个调用链中相同的方法进行合并,以得到调用关系,其中相同的方法,可以理解为两个方法的方法名相同,且两个方法所属的类的类名也相同。以步骤101中获取到了2个第一调用节点,分别对应两个第一调用方法:[类a方法a],和[类b方法b]来举例。在对每个第一调用节点执行步骤102至步骤104后,得到调用链1:[类a方法a]调用[类a方法c]、调用链2:[类a方法a]调用[类b方法d]、调用链3:[类b方法b]调用[类a方法a],如图2中的(a)所示。那么,根据上述3个调用链生成调用关系时,调用链3中的被调用函数(即[类a方法a]),与调用链1中的调用函数(即[类a方法a])是相同的方法,可以进行合并,得到调用关系如图2中的(b)所示。
[0097]
这样,本公开从源文件对应的抽象语法树中,筛选出第一调用节点,然后对每个第一调用节点,匹配对应的第一被调用节点,这样,就能提取出源文件中包括的调用方法和被调用方法之间的调用链,最后根据源文件中包括的全部调用链,生成源文件的调用关系,能够自动、准确地得到调用关系。无需技术人员进行源码分析,也不需要手动编写匹配函数,有效提高了调用关系的生成效率。
[0098]
综上所述,本公开首先在目标源文件对应的抽象语法树中,筛选出至少一个第一调用节点,第一调用节点为方法定义节点,之后针对每个第一调用节点,在抽象语法树中查找该第一调用节点的子节点,再确定该第一调用节点的子节点中,对应的第一被调用节点,其中,第一被调用节点为方法调用节点,且抽象语法树中第一被调用节点的子节点不包括块节点,然后将该第一调用节点对应的第一调用方法,调用第一被调用节点对应的第一被调用方法,作为一个调用链,最后根据全部的调用链,生成目标源文件的调用关系。本公开通过对抽象语法树中的节点进行筛选,提取出其中包括的调用方法和被调用方法之间的调用链,从而根据调用链自动、准确地生成调用关系,提高了调用关系的生成效率。
[0099]
在一种实现方式中,步骤101中获取第一调用节点的方式可以为:
[0100]
从抽象语法树包括的全部方法定义节点中,确定至少一个第一调用节点,每个第一调用节点存在对应的第一类节点,第一类节点为该第一调用节点的父节点,且第一类节点为类定义节点。
[0101]
示例的,由于objective-c中要求每个方法都需要属于某一个类,那么还可以对第一调用节点做进一步的限定:在抽象语法树中,第一调用节点存在对应的第一类节点,其中,第一类节点满足为两个条件:条件一:第一类节点为类定义节点;条件二,第一类节点为该第一调用节点的父节点。其中,条件一表示,第一类节点对应一个类,其中包括了该类完整的实现部分。条件二表示,第一调用节点对应的方法,属于第一类节点对应的类,也就是说,第一类节点对应的类中,定义了第一调用节点对应的方法。若抽象语法树中存在某个方法定义节点,不属于任何一个类(即不存在对应的第一类节点),那么这个方法定义节点不为第一调用节点,可以过滤掉这个方法定义节点。具体的,可以按照dsl的语法规则,来编写适用于第一类节点的第二匹配规则,然后在抽象语法树中查找符合第二匹配规则的第一类
节点,第二匹配规则例如可以是:objcimplementationdecl()matcher。
[0102]
图3是根据一示例性实施例示出的另一种生成调用关系的方法的流程图,如图3所示,在步骤104之前,该方法还可以包括:
[0103]
步骤106,获取该第一调用节点对应的第一类节点。
[0104]
步骤107,根据该第一调用节点和对应的第一类节点,获取第一调用节点的方法名,和第一调用节点所属的类名,以确定第一调用方法,并根据第一被调用节点,获取第一被调用节点的方法名,和第一被调用节点所属的类名,以确定第一被调用方法。
[0105]
举例来说,在目标工程中唯一确定一个方法,需要知道方法的方法名和类名,也就是说需要从两个维度来确定一个方法,即方法的方法名,和方法所属的类的类名。那么,要确定该第一调用方法和第一被调用方法,就分别需要知道该第一调用方法的方法名、类名,和第一被调用方法的方法名、类名。由于一个方法被调用时(对应方法调用节点),会指明该方法的方法名、类名,因此,可以直接对第一被调用节点进行解析,得到第一被调用方法的方法名,和第一被调用方法所属的类名。由于一个方法在被定义时(对应方法定义节点),可能只表明了方法名,通过对该第一调用节点进行解析,只能得到第一调用方法的方法名。要获取第一调用方法的类名,还需要先获取该第一调用节点对应的第一类节点,然后对第一类节点进行解析,得到第一调用方法所属的类名。
[0106]
图4是根据一示例性实施例示出的另一种生成调用关系的方法的流程图,如图4所示,在步骤102之后,该方法还可以包括以下步骤:
[0107]
步骤108,在该第一调用节点的子节点中,确定该第一调用节点对应的至少一个第二被调用节点,第二被调用节点为方法调用节点。
[0108]
步骤109,针对每个第二被调用节点,获取抽象语法树中,该第二被调用节点的父节点。
[0109]
步骤110,在该第二被调用节点的父节点中,确定该第二被调用节点对应的第二调用节点,第二调用节点为方法调用节点,且第二调用节点的子节点中包括块节点。
[0110]
步骤111,将第二调用节点对应的第二调用方法,调用该第二被调用节点对应的第二被调用方法,作为一个调用链。
[0111]
举例来说,目标源文件中除了普通的oc方法之外,还可能存在块中定义的方法,因此可以从抽象语法树中,进一步筛选出块中定义的方法对应的调用链。首先,针对在步骤101中确定的每个第一调用节点,确定该第一调用节点的子节点(可以是一个或多个),然后在该第一调用节点的子节点中,确定至少一个,为方法调用节点的第二被调用节点。第二被调用节点同样对应一个方法。也就是说,第一调用节点对应的方法,调用了第二被调用节点对应的方法。之后,针对每个第二被调用节点,在抽象语法树中,查找该第二被调用节点的父节点,并在该第二被调用节点的父节点中,确定第二调用节点(可以是一个或多个),第二调用节点同样对应一个方法。第二调用节点满足为两个条件:条件一:第二调用节点为方法调用节点;条件二,第二调用节点的子节点中包括块节点。其中,条件一表示,第二调用节点对应的方法,调用了第二被调用节点对应的方法。条件二表示,第二调用节点的子节点可能有一个或多个,其中包括了块节点,也就是说,第二调用节点对应的方法中,调用的方法为块中定义的方法。
[0112]
将第二调用节点对应的第二调用方法,调用该第二被调用节点对应的第二被调用
方法,作为一个调用链,可以得到块中定义的方法对应的调用链。其中,由于第二调用节点,和第二被调用节点,均为方法调用节点,那么可以通过解析第二调用节点,得到第二调用方法的方法名和所属的类名,以确定第二调用方法。同样的,可以通过解析该第二被调用节点,得到第二被调用方法的方法名和所属的类名,以确定第二被调用方法。需要说明的是,若只存在一个第二调用节点,那么步骤111中得到一个调用链,若存在m(m为大于1的自然数)个第二调用节点,那么步骤111可以执行m次,得到m个调用链。
[0113]
在得到块中定义的方法对应的调用链之后,相应的,步骤105可以将普通oc方法对应的调用链,和块中定义的方法对应的调用链进行聚合,以得到目标源文件的调用关系。以执行步骤108至111,得到的调用链4:[类b方法b]调用[类g方法g]为例,其中,[类g方法g]为块中定义的方法(即第二被调用节点对应的方法),[类b方法b]为普通oc方法(即第二调用节点对应的方法)。在图2中的(b)所示的调用关系的基础上,聚合了调用链4的调用关系可以如图5所示。
[0114]
这样,本公开还可以从抽象语法树中,提取出块中定义的方法对应的调用链,进一步提高了调用关系的准确度和完整度,使得调用关系中能够涵盖块中定义的方法,从而也扩展了调用关系的适用范围。
[0115]
图6是根据一示例性实施例示出的另一种生成调用关系的方法的流程图,如图6所似乎,在步骤105之前,该方法还可以包括:
[0116]
步骤112,获取抽象语法树中的至少一个第三调用节点,第三调用节点为方法定义节点,且第三调用节点存在对应的第三类节点,第三类节点为该第三调用节点的父节点,且第三类节点为分类定义节点。
[0117]
举例来说,目标源文件中除了普通的oc方法之外,还可能存在分类中定义的方法,因此可以从抽象语法树中,进一步筛选出分类中定义的方法对应的调用链。首先,在抽象语法树中筛选出至少一个第三调用节点。其中,第三调用节点满足两个条件:条件一:第三调用节点为方法定义节点;条件二:第三调用节点存在对应的第三类节点,第三类节点为该第三调用节点的父节点,且第三类节点为分类定义节点(即objccategoryimpldecl节点)。其中,条件一表示第三调用节点对应一个方法,其中包括了该方法的实现体,也就是说第三调用节点是对应的方法的定义,而不是对应的方法的声明。条件二表示第三调用节点对应的方法,属于第三类节点对应的类,也就说第三类节点对应的类中,定义了第三调用方法对应的方法。可以理解为,第三调用节点对应的方法是抽象语法树中,分类中定义的方法。具体的,可以按照dsl的语法规则,来编写适用于第三类节点的第三匹配规则,然后在抽象语法树中查找符合第三匹配规则的第三类节点,第三匹配规则例如可以是:objccategoryimpldecl()matcher。
[0118]
步骤113,针对每个第三调用节点,获取抽象语法树中,该第三调用节点的子节点。
[0119]
步骤114,在该第三调用节点的子节点中,确定该第三调用节点对应的第三被调用节点,第三被调用节点为方法调用节点。
[0120]
步骤115,将该第三调用节点对应的第三调用方法,调用第三被调用节点对应的第三被调用方法,作为一个调用链。
[0121]
示例的,针对至少一个第三调用节点中的每个第三调用节点,获取抽象语法树中该第三调用节点的子节点,该第三调用节点的子节点可以为一个或多个。然后在该第三调
用节点的子节点中,筛选出第三被调用节点,第三被调用节点同样也对应一个方法,第三被调用节点可以为一个或多个。第三被调用节点为方法调用节点,也就是说该第三调用节点对应的方法中,调用了第三被调用节点对应的方法。需要说明的是,如果抽象语法树中,该第三调用节点不存在的子节点,表示该第三调用节点对应的方法没有调用其他方法(该第三调用节点可能会被其他方法调用)。
[0122]
在确定该第三调用节点和对应的第三被调用节点后,可以确定第三调用节点对应的第三调用方法,和第三被调用节点对应的第三被调用方法,然后将第三调用方法,调用第三被调用方法,作为一个调用链,可以得到分类中定义的方法对应的调用链。需要说明的是,若只存在一个第三被调用节点,那么步骤115中得到一个调用链,若存在p(p为大于1的自然数)个第三被调用节点,那么步骤104可以执行p次,得到p个调用链。
[0123]
图7是根据一示例性实施例示出的另一种生成调用关系的方法的流程图,如图7所示,在步骤115之前,该方法还包括:
[0124]
步骤116,获取该第三调用节点对应的第三类节点。
[0125]
步骤117,根据该第三调用节点和对应的第三类节点,获取该第三调用节点的方法名,和该第三调用节点所属的类名,以确定第三调用方法,并根据第三被调用节点,获取第三被调用节点的方法名,和第三被调用节点所属的类名,以确定第三被调用方法。
[0126]
示例的,与步骤106和107中的处理方式相同,可以直接对第三被调用节点进行解析,得到第三被调用方法的方法名,和第三被调用方法所属的类名,从而确定第三被调用方法。通过对该第三调用节点进行解析,得到该第三调用方法的方法名。再获取该第三调用节点对应的第三类节点,然后对第三类节点进行解析,以得到第三调用方法所属的类名,从而确定第三调用方法。
[0127]
在得到分类中定义的方法对应的调用链之后,相应的,步骤105可以将普通oc方法对应的调用链,和分类中定义的方法对应的调用链进行聚合,还可以进一步将块中定义的方法对应的调用链进行聚合,以得到目标源文件的调用关系。以执行步骤112至115,得到调用链5:[类h方法h]调用[类b方法d]为例,其中,[类h方法h]为分类中定义的方法(即第三调用节点对应的方法),[类b方法d]为普通oc方法(即第三被调用节点对应的方法)。在图5所示的调用关系的基础上,聚合了调用链5的调用关系可以如图8所示。
[0128]
这样,本公开还可以从抽象语法树中,提取出分类中定义的方法对应的调用链,进一步提高了调用关系的准确度和完整度,使得调用关系中能够涵盖分类中定义的方法,从而也扩展了调用关系的适用范围。
[0129]
图9是根据一示例性实施例示出的另一种生成调用关系的方法的流程图,如图9所示,步骤105可以通过以下方式来实现:
[0130]
步骤1051,若第一调用链中包括的调用方法,在调用第一调用链中包括的被调用方法时存在隐式调用,获取第一调用链中包括的被调用方法的属性信息,属性信息包括参数信息,和/或返回值信息,第一调用链为全部调用链中的任一调用链。
[0131]
步骤1052,根据第一调用链中包括的被调用方法的属性信息,确定隐式调用链。
[0132]
步骤1053,根据隐式调用链和全部调用链,生成目标源文件的调用关系。
[0133]
举例来说,目标源文件中除了存在普通的oc方法、块中定义的方法和分类中定义的方法之外,还可能存在隐式调用。由于在抽象语法树中,并不存在隐式调用对应的方法调
用节点,因此在生成目标源文件的调用关系时,可以依次判断每个调用链中,是否存在隐式调用,从而得到隐式调用对应的隐式调用链,最后根据隐式调用链和全部调用链,生成目标源文件的调用关系。具体的,以第一调用链为例,第一调用链由调用方法和被调用方法组成,即调用方法,调用被调用方法。那么,可以判断第一调用链中包括的调用方法,在调用第一调用链中包括的被调用方法时是否存在隐式调用。由于隐式调用的数量有限,可以通过穷举的方式来确定是否存在隐式调用。如果第一调用链中包括的调用方法,在调用第一调用链中包括的被调用方法时存在隐式调用,那么获取第一调用链中包括的被调用方法的属性信息,属性信息可以包括参数信息,和/或返回值信息。然后根据第一调用链中包括的被调用方法的属性信息,确定隐式调用链,隐式调用链可以是一个,也可以是多个。隐式调用链能够使第一调用链更加完整,可以理解为,第一调用链是粗粒度的调用,而隐式调用链,能够将第一调用链内包括的调用方法和被调用方法之间具体的调用机制补全。
[0134]
具体的,如果第一调用链包括的被调用方法中,包括启动activity的节点,那么将该节点作为调用方法,将该节点启动的activity节点,作为被调用方法,得到第一调用链的一个隐式调用链。如果第一调用链包括的被调用方法中,包括启动service的节点,那么将该节点作为调用方法,将该节点启动的service节点作为被调用方法,得到第一调用链的一个隐式调用链。如果第一调用链包括的被调用方法中,包括register receiver的节点,那么将该节点作为调用方法,将该节点注册的broadcast receiver节点作为被调用方法,得到第一调用链的一个隐式调用链。如果第一调用链包括的被调用方法中,包括发送广播的节点,那么将该节点作为调用方法,将接收该节点发送的广播的broadcast receiver节点作为被调用方法,得到第一调用链的一个隐式调用链。
[0135]
以调用链1为[类a方法a]调用[类a方法c]来举例,根据[类a方法c]的属性信息,确定其中包括一个register receiver节点,那么找到register receiver节点注册的broadcast receiver节点,得到一个从register receiver指向broadcast receiver的隐式调用链。那么调用链1可以被扩充为[类a方法a]指向register receiver,register receiver指向broadcast receiver,broadcast receiver指向[类a方法c]。
[0136]
图10是根据一示例性实施例示出的另一种生成调用关系的方法的流程图,目标源文件为多个,目标源文件属于目标工程,在步骤105之后,该方法还可以包括:
[0137]
步骤118,根据多个目标源文件的调用关系,生成目标工程的调用关系树。
[0138]
举例来说,app对应的目标工程中可以包括多个目标源文件,针对每个目标源文件执行上述生成调用关系的方法,得到每个目标源文件的调用关系,然后可以将全部的目标源文件的调用关系进行聚合,得到目标工程的调用关系树。例如,可以通过ios提供的编译数据库(例如:clang compilation database)获知每个目标源文件是如何被编译的,然后可以编写一个批处理脚本,来对所有的目标源文件进行处理,得到包含每个目标源文件的调用关系的文件(例如可以是.json格式的文件)。批处理脚本可以先获取该目标源文件对应的抽象语法树,然后按照预设过滤条件对其中的节点进行过滤,再执行上述生成调用关系的方法,最后进行格式化,得到包括了调用关系的.json文件,预设过滤条件可以为黑名单,其中记录指定过滤的方法,例如:第三方库中的方法等。例如,目标工程中包括了3个目标源文件:1.m、2.m和3.m,通过批处理脚本对3个目标源文件进行处理,得到对应的1.json、2.json和3.json。
[0139]
调用关系树可以理解为多个调用关系的集合,如果用有向边来表示调用链,用有向图来表示调用关系,那么调用关系树也可以用有向图来表示。可以将多个调用关系中相同的方法进行聚合,以得到调用关系树,其中相同的方法,可以理解为两个方法的方法名相同,且两个方法所属的类的类名也相同。以目标工程中包括了两个目标源文件为例,其中一个目标源文件的调用关系如图2中的(b)所示,另一个目标源文件的调用关系中包括了3个调用链:调用链6:[类d方法d]调用[类a方法a]、调用链7:[类d方法d]调用[类e方法e]、调用链8:[类e方法e]调用[类e方法f],将两个目标源文件的调用关系进行聚合,得到的目标工程的调用关系树可以如图11所示。
[0140]
这样,本公开还可以跨文件获取调用关系,从而聚合得到目标工程的调用关系树,进一步扩展了调用关系的适用范围。
[0141]
综上所述,本公开首先在目标源文件对应的抽象语法树中,筛选出至少一个第一调用节点,第一调用节点为方法定义节点,之后针对每个第一调用节点,在抽象语法树中查找该第一调用节点的子节点,再确定该第一调用节点的子节点中,对应的第一被调用节点,其中,第一被调用节点为方法调用节点,且抽象语法树中第一被调用节点的子节点不包括块节点,然后将该第一调用节点对应的第一调用方法,调用第一被调用节点对应的第一被调用方法,作为一个调用链,最后根据全部的调用链,生成目标源文件的调用关系。本公开通过对抽象语法树中的节点进行筛选,提取出其中包括的调用方法和被调用方法之间的调用链,从而根据调用链自动、准确地生成调用关系,提高了调用关系的生成效率。
[0142]
图12是根据一示例性实施例示出的一种生成调用关系的装置的框图,如图12所示,该装置200包括:
[0143]
第一获取模块201,被配置为用于获取目标源文件对应的抽象语法树中至少一个第一调用节点,第一调用节点为方法定义节点。
[0144]
第二获取模块202,被配置为用于针对每个第一调用节点,获取抽象语法树中,该第一调用节点的子节点。在该第一调用节点的子节点中,确定该第一调用节点对应的第一被调用节点,第一被调用节点为方法调用节点,且抽象语法树中第一被调用节点的子节点不包括块节点。将该第一调用节点对应的第一调用方法,调用第一被调用节点对应的第一被调用方法,作为一个调用链。
[0145]
第一生成模块203,被配置为用于根据全部调用链,生成目标源文件的调用关系。
[0146]
在一种实现方式中,第一获取模块201被配置为用于:
[0147]
从抽象语法树包括的全部方法定义节点中,确定至少一个第一调用节点,每个第一调用节点存在对应的第一类节点,第一类节点为该第一调用节点的父节点,且第一类节点为类定义节点。
[0148]
在另一种实现方式中,第二获取模块202还被配置为用于:
[0149]
在将该第一调用节点对应的第一调用方法,调用第一被调用节点对应的第一被调用方法,作为该第一调用节点的调用链之前,获取该第一调用节点对应的第一类节点。
[0150]
根据该第一调用节点和对应的第一类节点,获取第一调用节点的方法名,和第一调用节点所属的类名,以确定第一调用方法,并根据第一被调用节点,获取第一被调用节点的方法名,和第一被调用节点所属的类名,以确定第一被调用方法。
[0151]
在另一种实现方式中,第二获取模块202还被配置为用于:
[0152]
在获取抽象语法树中,该第一调用节点的子节点之后,在该第一调用节点的子节点中,确定该第一调用节点对应的至少一个第二被调用节点,第二被调用节点为方法调用节点。
[0153]
针对每个第二被调用节点,获取抽象语法树中,该第二被调用节点的父节点。
[0154]
在该第二被调用节点的父节点中,确定该第二被调用节点对应的第二调用节点,第二调用节点为方法调用节点,且第二调用节点的子节点中包括块节点。
[0155]
将第二调用节点对应的第二调用方法,调用该第二被调用节点对应的第二被调用方法,作为一个调用链。
[0156]
在另一种实现方式中,第二获取模块202还被配置为用于:
[0157]
获取抽象语法树中的至少一个第三调用节点,第三调用节点为方法定义节点,且第三调用节点存在对应的第三类节点,第三类节点为该第三调用节点的父节点,且第三类节点为分类定义节点。
[0158]
针对每个第三调用节点,获取抽象语法树中,该第三调用节点的子节点。
[0159]
在该第三调用节点的子节点中,确定该第三调用节点对应的第三被调用节点,第三被调用节点为方法调用节点。
[0160]
将该第三调用节点对应的第三调用方法,调用第三被调用节点对应的第三被调用方法,作为一个调用链。
[0161]
在另一种实现方式中,第二获取模块202还被配置为用于:
[0162]
在将该第三调用节点对应的第三调用方法,调用第三被调用节点对应的第三被调用方法,作为一个调用链之前,获取该第三调用节点对应的第三类节点。
[0163]
根据该第三调用节点和对应的第三类节点,获取该第三调用节点的方法名,和该第三调用节点所属的类名,以确定第三调用方法,并根据第三被调用节点,获取第三被调用节点的方法名,和第三被调用节点所属的类名,以确定第三被调用方法。
[0164]
图13是根据一示例性实施例示出的另一种生成调用关系的装置的框图,如图13所示,第一生成模块203包括:
[0165]
获取子模块2031,被配置为用于若第一调用链中包括的调用方法,在调用第一调用链中包括的被调用方法时存在隐式调用,获取第一调用链中包括的被调用方法的属性信息,属性信息包括参数信息,和/或返回值信息,第一调用链为全部调用链中的任一调用链。
[0166]
确定子模块2032,被配置为用于根据第一调用链中包括的被调用方法的属性信息,确定隐式调用链。
[0167]
生成子模块2033,被配置为用于根据隐式调用链和全部调用链,生成目标源文件的调用关系。
[0168]
图14是根据一示例性实施例示出的另一种生成调用关系的装置的框图,如图14所示,该装置200还包括:
[0169]
第二生成模块204,被配置为用于根据多个目标源文件的调用关系,生成目标工程的调用关系树。
[0170]
关于上述实施例中的装置,其中各个模块执行操作的具体方式已经在有关该方法的实施例中进行了详细描述,此处将不做详细阐述说明。
[0171]
综上所述,本公开首先在目标源文件对应的抽象语法树中,筛选出至少一个第一
调用节点,第一调用节点为方法定义节点,之后针对每个第一调用节点,在抽象语法树中查找该第一调用节点的子节点,再确定该第一调用节点的子节点中,对应的第一被调用节点,其中,第一被调用节点为方法调用节点,且抽象语法树中第一被调用节点的子节点不包括块节点,然后将该第一调用节点对应的第一调用方法,调用第一被调用节点对应的第一被调用方法,作为一个调用链,最后根据全部的调用链,生成目标源文件的调用关系。本公开通过对抽象语法树中的节点进行筛选,提取出其中包括的调用方法和被调用方法之间的调用链,从而根据调用链自动、准确地生成调用关系,提高了调用关系的生成效率。
[0172]
图15是根据一示例性实施例示出的一种电子设备300的框图。如图15所示,该电子设备300可以包括:处理器301,存储器302。该电子设备300还可以包括多媒体组件303,输入/输出(i/o)接口304,以及通信组件305中的一者或多者。
[0173]
其中,处理器301用于控制该电子设备300的整体操作,以完成上述的生成调用关系的方法中的全部或部分步骤。存储器302用于存储各种类型的数据以支持在该电子设备300的操作,这些数据例如可以包括用于在该电子设备300上操作的任何应用程序或方法的指令,以及应用程序相关的数据,例如联系人数据、收发的消息、图片、音频、视频等等。该存储器302可以由任何类型的易失性或非易失性存储设备或者它们的组合实现,例如静态随机存取存储器(static random access memory,简称sram),电可擦除可编程只读存储器(electrically erasable programmable read-only memory,简称eeprom),可擦除可编程只读存储器(erasable programmable read-only memory,简称eprom),可编程只读存储器(programmable read-only memory,简称prom),只读存储器(read-only memory,简称rom),磁存储器,快闪存储器,磁盘或光盘。多媒体组件303可以包括屏幕和音频组件。其中屏幕例如可以是触摸屏,音频组件用于输出和/或输入音频信号。例如,音频组件可以包括一个麦克风,麦克风用于接收外部音频信号。所接收的音频信号可以被进一步存储在存储器302或通过通信组件305发送。音频组件还包括至少一个扬声器,用于输出音频信号。i/o接口304为处理器301和其他接口模块之间提供接口,上述其他接口模块可以是键盘,鼠标,按钮等。这些按钮可以是虚拟按钮或者实体按钮。通信组件305用于该电子设备300与其他设备之间进行有线或无线通信。无线通信,例如wi-fi,蓝牙,近场通信(near field communication,简称nfc),2g、3g、4g、nb-iot、emtc、或其他5g等等,或它们中的一种或几种的组合,在此不做限定。因此相应的该通信组件305可以包括:wi-fi模块,蓝牙模块,nfc模块等等。
[0174]
在一示例性实施例中,电子设备300可以被一个或多个应用专用集成电路(application specific integrated circuit,简称asic)、数字信号处理器(digital signal processor,简称dsp)、数字信号处理设备(digital signal processing device,简称dspd)、可编程逻辑器件(programmable logic device,简称pld)、现场可编程门阵列(field programmable gate array,简称fpga)、控制器、微控制器、微处理器或其他电子元件实现,用于执行上述的生成调用关系的方法。
[0175]
在另一示例性实施例中,还提供了一种包括程序指令的计算机可读存储介质,该程序指令被处理器执行时实现上述的生成调用关系的方法的步骤。例如,该计算机可读存储介质可以为上述包括程序指令的存储器302,上述程序指令可由电子设备300的处理器301执行以完成上述的生成调用关系的方法。
[0176]
在另一示例性实施例中,还提供一种计算机程序产品,该计算机程序产品包含能够由可编程的装置执行的计算机程序,该计算机程序具有当由该可编程的装置执行时用于执行上述的生成调用关系的方法的代码部分。
[0177]
以上结合附图详细描述了本公开的优选实施方式,但是,本公开并不限于上述实施方式中的具体细节,在本公开的技术构思范围内,本领域技术人员在考虑说明书及实践本公开后,容易想到本公开的其它实施方案,均属于本公开的保护范围。
[0178]
另外需要说明的是,在上述具体实施方式中所描述的各个具体技术特征,在不矛盾的情况下,可以通过任何合适的方式进行组合。同时本公开的各种不同的实施方式之间也可以进行任意组合,只要其不违背本公开的思想,其同样应当视为本公开所公开的内容。本公开并不局限于上面已经描述出的精确结构,本公开的范围仅由所附的权利要求来限制。
再多了解一些

本文用于企业家、创业者技术爱好者查询,结果仅供参考。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

相关文献