CN117421252B - 代码检测方法、装置及计算机可读存储介质 - Google Patents
代码检测方法、装置及计算机可读存储介质 Download PDFInfo
- Publication number
- CN117421252B CN117421252B CN202311736739.4A CN202311736739A CN117421252B CN 117421252 B CN117421252 B CN 117421252B CN 202311736739 A CN202311736739 A CN 202311736739A CN 117421252 B CN117421252 B CN 117421252B
- Authority
- CN
- China
- Prior art keywords
- entity
- dependency
- dependency relationship
- instance
- code
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Active
Links
- 238000001514 detection method Methods 0.000 title claims abstract description 48
- 238000000034 method Methods 0.000 claims abstract description 145
- 230000001419 dependent effect Effects 0.000 claims description 36
- 230000008878 coupling Effects 0.000 claims description 23
- 238000010168 coupling process Methods 0.000 claims description 23
- 238000005859 coupling reaction Methods 0.000 claims description 23
- 238000012360 testing method Methods 0.000 claims description 16
- 230000015654 memory Effects 0.000 claims description 15
- 238000012986 modification Methods 0.000 claims description 14
- 230000004048 modification Effects 0.000 claims description 14
- 239000003607 modifier Substances 0.000 claims description 10
- 238000000605 extraction Methods 0.000 claims description 5
- 238000012937 correction Methods 0.000 claims description 3
- 238000012217 deletion Methods 0.000 claims description 2
- 230000037430 deletion Effects 0.000 claims description 2
- 238000001914 filtration Methods 0.000 claims description 2
- 230000002441 reversible effect Effects 0.000 abstract description 11
- 230000008569 process Effects 0.000 abstract description 9
- 238000004590 computer program Methods 0.000 description 16
- 230000002829 reductive effect Effects 0.000 description 15
- 230000006870 function Effects 0.000 description 14
- 230000008859 change Effects 0.000 description 5
- 238000013461 design Methods 0.000 description 5
- 238000010586 diagram Methods 0.000 description 5
- 230000036961 partial effect Effects 0.000 description 4
- 230000007547 defect Effects 0.000 description 3
- 238000011161 development Methods 0.000 description 3
- 230000018109 developmental process Effects 0.000 description 3
- 230000003190 augmentative effect Effects 0.000 description 2
- 230000009286 beneficial effect Effects 0.000 description 2
- 238000004891 communication Methods 0.000 description 2
- 230000000694 effects Effects 0.000 description 2
- 238000013507 mapping Methods 0.000 description 2
- 102000002067 Protein Subunits Human genes 0.000 description 1
- 108010001267 Protein Subunits Proteins 0.000 description 1
- 230000006978 adaptation Effects 0.000 description 1
- 238000004458 analytical method Methods 0.000 description 1
- 230000006399 behavior Effects 0.000 description 1
- 230000002349 favourable effect Effects 0.000 description 1
- 238000007429 general method Methods 0.000 description 1
- 230000003993 interaction Effects 0.000 description 1
- 238000012804 iterative process Methods 0.000 description 1
- 230000000670 limiting effect Effects 0.000 description 1
- 238000002715 modification method Methods 0.000 description 1
- 238000003062 neural network model Methods 0.000 description 1
- 230000003287 optical effect Effects 0.000 description 1
- 238000012545 processing Methods 0.000 description 1
- 230000003068 static effect Effects 0.000 description 1
- 238000006467 substitution reaction Methods 0.000 description 1
- 238000012546 transfer Methods 0.000 description 1
- 238000011144 upstream manufacturing Methods 0.000 description 1
Classifications
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F11/00—Error detection; Error correction; Monitoring
- G06F11/36—Preventing errors by testing or debugging software
- G06F11/3604—Software analysis for verifying properties of programs
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F8/00—Arrangements for software engineering
- G06F8/70—Software maintenance or management
- G06F8/71—Version control; Configuration management
Landscapes
- Engineering & Computer Science (AREA)
- Theoretical Computer Science (AREA)
- Software Systems (AREA)
- General Engineering & Computer Science (AREA)
- Physics & Mathematics (AREA)
- General Physics & Mathematics (AREA)
- Computer Hardware Design (AREA)
- Quality & Reliability (AREA)
- Computer Security & Cryptography (AREA)
- Stored Programmes (AREA)
Abstract
本申请提供了一种代码检测方法、装置及计算机可读存储介质,其中,该方法包括:先获取反模式实例集合,然后基于该反模式实例集合,在待测依赖关系集合中检测目标依赖关系,这里的反模式实例集合是由一个或多个反模式的预设依赖关系实例组成的集合,因此,基于该反模式实例集合从待测依赖关系集合中检测得到的目标依赖关系也是反模式的。因此,基于该方法可以对软件代码执行反模式检测,以便对反模式的依赖关系进行及时处理,减少后续代码演进中出现的问题。
Description
技术领域
本申请属于软件应用领域,尤其涉及一种代码检测方法、装置及计算机可读存储介质。
背景技术
在软件应用领域,软件系统通常由各种实体组成,而实体之间通常会存在各种依赖关系,即一个实体可能会使用另外一个或多个实体的服务或者功能,具体可以表现为函数调用、方法重写、类继承、参数传递、返回值等形式。
因此,依赖关系反映了代码的结构和功能之间的关系,这也就导致部分依赖关系可能会导致软件架构上的问题,从而使得后续代码演进困难。
发明内容
本申请实施例提供了一种代码检测方法、装置及计算机可读存储介质,可以对代码进行反模式检测。
第一方面,提供了一种代码检测方法,该方法可以应用于服务器(可以是本地服务器,也可以是云端服务器),也可以应用于电子设备(如计算机、手机、工作站、数字助理等)。
具体地,该方法包括:获取反模式实例集合,然后基于该反模式实例集合,在待测依赖关系集合中检测目标依赖关系。其中,该反模式实例集合包括一个或多个用于描述依赖方式为反模式的依赖关系的预设依赖关系实例,该待测依赖关系集合包括由待测软件代码内的实体所构成的一组或多组依赖关系,该目标依赖关系对应的依赖方式为反模式。
基于上述方案,可以预先确定反模式实例集合,以获取符合反模式的预设依赖关系实例,进一步地可以将与预设依赖关系实例匹配的依赖关系确定为符合反模式的目标依赖关系。该方法中,新定义了反模式的依赖关系,该反模式依赖关系更加关注伴生代码基于原生代码的耦合情况,因此基于反模式实例集合最终检测到的目标依赖关系更能反应不良耦合可能带来的架构隐患。同时,反模式中涉及的实体修改都与伴生代码的开发者有关,更有利于开发者进行缺陷定位和代码理解。
可选地,反模式实例集合中的预设依赖关系实例可以通过依赖子图来描述依赖关系,依赖子图内实体之间的耦合方式为反模式。
可选地,该待测依赖关系集合可以包括该待测软件代码内实体所构成的部分依赖关系中的部分依赖。
基于上述方案,可以仅对不分依赖关系进行检测(也就是说,可以对要检测的依赖关系进行筛选),以降低检测量,节省资源开销。
可选地,待测软件代码是由伴生代码耦合原生代码得到的,待测依赖关系集合包括伴生代码内的实体与原生代码内的实体之间所构成的依赖关系。
由上可知,本申请实施例提供的方案可以应用于伴生代码耦合原生代码的场景中,如定制化安卓操作系统中,软件开发商在安卓原生代码的基础上增加了伴生代码(即扩展代码)以进行功能扩展。在这种场景下,原生代码在进行迭代的时候不会考虑伴生代码的情况,因此可能会出现一些代码冲突或稳定性等问题,这种问题通常是由于原生代码和伴生代码之间的不良耦合关系(即反模式的依赖关系)导致的,因此在该场景下,对原生代码和伴生代码之间的依赖关系进行反模式检测具有重大意义,可以降低后续代码迭代的时候出现问题的几率。
在上述方案中,待测依赖关系集合仅包括待测软件代码内实体构成的依赖关系中的部分依赖关系,从而可以减少检测量,提高检测效率。并且,待测依赖关系集合中主要包括原生实体和伴生实体之间的依赖关系,而不包括原生实体与原生实体之间的依赖关系,因为原生实体与原生实体之间的依赖关系通常存在于原生代码中,伴生方通常无法对这部分依赖关系进行调整,因此可以不对这部分依赖关系进行检测,从而减少检测量,降低资源消耗。
可选地,待测依赖关系集合还包括伴生代码内的不同实体之间所构成的依赖关系,和/或由待测软件代码内的实体构成的依赖关系中依赖类型为定义define的依赖关系。
在上述方案中,待测依赖关系集合还可以包括伴生代码内的不同实体之间所构成的依赖关系。由于伴生代码为伴生方添加的代码,伴生方可以对这部分代码进行调整,因此检测这部分代码内构成的反模式依赖关系有利于伴生方对伴生代码内的缺陷进行定位,从而可以及时对伴生代码进行调整,以减少后续耦合问题。
在上述方案中,待测依赖关系集合还可以包括依赖类型为定义define的依赖关系。由于反模式的依赖关系通常都是由define类型的依赖关系导致的,因此,将依赖类型为define的依赖关系加入待测依赖关系集合,就可以是的待测依赖关系集合中涵盖了可能发生反模式问题的绝大部分依赖关系,既可以提高检索效果,又可以尽可能降低检索量。
可选地,在待测依赖关系集合中检测目标依赖关系之前,方法还包括:将由待测软件代码内的实体所构成的依赖关系中的冗余关系进行过滤得到基础依赖关系,冗余关系包括日志信息对应的依赖关系和/或工具类代码对应的依赖关系;从基础依赖关系中确定待测依赖关系集合。
在上述方案中,在确定待测依赖关系集合之前,还可以先将由待测软件代码内的实体所构成的依赖关系中的冗余关系进行过滤得到基础依赖关系,然后从该基础依赖关系中确定该待测依赖关系集合。由于冗余关系通常占据了大量的内容,而这些内容对检测反模式的依赖关系会造成一定的干扰,因此预先将这些冗余关系进行过滤,可以降低检测量,提高检测效率。
可选地,该方法还包括:调用可扩展的依赖关系抽取(extensible entityrelation extraction,ENRE)工具获取该待测软件代码的基础依赖信息,该基础依赖信息包括以下一项或多项:该待测软件代码内的实体对应的唯一索引名、实体名、实体类别、实体参数、访问限制级别,该软件代码内的实体构成的依赖关系对应的依赖类型、源实体、目标实体;调用依赖面(dependency façade,DepFCD)工具获取该待测软件代码内实体的归属方信息,该归属方信息包括原生方和伴生方,该原生方的实体包括活跃原生实体、原生过时实体、侵入式原生实体,该伴生方的实体包括扩展实体;基于该基础依赖信息和该归属方信息,确定该待测依赖关系集合。
基于上述方案,可以分别通过ENRE工具和DepFCD工具获取待测软件代码的基础依赖信息,以及实体对应的归属方信息,从而可以基于这些信息确定待测依赖关系集合。
可选地,在待测依赖关系集合中检测目标依赖关系之前,方法还包括:获取待测软件代码中的重构信息;基于重构信息对待测软件代码中的侵入式实体的属性信息做重构修正。
可选地,重构信息所指示的重构操作包括以下一项或多项:类和方法的提取,重命名,移动,以及方法参数的修改。
基于上述方案,可以降低待测软件代码的耦合度,减少构成反模式的依赖关系的数量,从而减少代码迭代时出现的问题。
可选地,基于反模式实例集合,在待测依赖关系集合中检测目标依赖关系,包括:获取反模式实例集合中的每个预设依赖关系实例对应的依赖属性信息和实体属性信息;将待测依赖关系集合中,与反模式实例集合中的任意预设依赖关系实例对应的依赖属性信息和实体属性信息匹配的依赖关系,确定为目标依赖关系。
基于上述方案,可以通过依赖属性信息和实体属性信息来执行依赖关系的匹配检索。由于一个依赖关系的特征通常可以由依赖属性信息和实体属性信息联合确定,因此通过这两种信息进行匹配检索,可以比较准确地检索出待测依赖关系集合中的反模式依赖关系,即可以提高检索的准确度。
可选地,依赖属性信息包括依赖类别,实体属性信息包括:源实体归属方,目标实体归属方,源实体类别和/或源实体索引,目标实体类别和/或目标实体索引。
可选地,实体属性信息还包括实体final修饰修改属性和/或实体可访问属性。
可选地,将待测依赖关系集合中,与反模式实例集合中的任意预设依赖关系实例对应的依赖属性信息和实体属性信息匹配的依赖关系,确定为目标依赖关系,包括:以待测依赖关系集合中的依赖关系对应的依赖属性信息和实体属性信息为键值,构建查询字典;将反模式实例集合中的预设依赖关系实例对应的依赖属性信息和实体属性信息在查询字典中进行匹配检索,确定目标依赖关系。
基于上述方案,可以基于待测依赖关系集合中的依赖关系的属性构建查询字典,通过该查询字典进行匹配检索,可以提高检索的效率。
可选地,预设依赖关系实例包括第一依赖关系实例、第二依赖关系实例、第三依赖关系实例、第四依赖关系实例以及第五依赖关系实例中的至少一个;其中,第一依赖关系实例指示删除原生实体的final修饰符,第二依赖关系实例指示使用原生实体访问限制级别超过预设级别的接口,第三依赖关系实例指示在原生类中添加伴生内部类,第四依赖关系实例指示对原生方法添加参数,第五依赖关系实例指示原生类继承伴生类。
可选地,第一依赖关系实例表现为第一实体依赖于第二实体;依赖方式为删除所述第二实体的final修饰符;该第一实体和该第二实体的实体类别(category)均为方法或均为类;依赖类别为重写(override)或继承(inherit);第一实体为扩展实体,即第一实体的归属方为伴生方;第二实体为侵入式原生实体,即第二实体的归属方为原生方(即第二实体为)。
可选地,第二依赖关系实例表现为第三实体依赖于第四实体;依赖方式为调用该第四实体的接口;该第三实体和该第四实体的实体类别均为方法;依赖类别为调用(call);第三实体为扩展实体,即第三实体的归属方为伴生方;第四实体为活跃原生实体或旧版本原生实体,即该第四实体的归属方为原生方;该第四实体的接口的访问限制级别(restriction level)超过预设级别。
可选地,第三依赖关系实例表现为第五实体依赖于第六实体;依赖方式为第五实体包含(contain)第六实体;第五实体和第六实体的实体类别均为类;依赖类别为定义(define);第五实体为浸入式原生实体,即第五实体的归属方为原生方;第六实体为扩展实体,即第六实体的归属方为伴生方。
可选地,第四依赖关系实例表现为第七实体依赖于第八实体;第七实体的实体类别为方法,该第八实体的实体类别为变量;依赖类别为参数(parameter)添加;第七实体为侵入式原生实体,即第七实体的归属方为原生方;第八实体为扩展实体,即第八实体的归属方为伴生方。
可选地,第五依赖关系实例变现为第九实体依赖于第十实体;第九实体和第十实体的实体类别均为类;依赖类别为继承(inherit);第九实体为侵入式原生实体,即第九实体的归属方为原生方;第十实体为扩展实体,即第十实体的归属方为伴生方。
第二方面,提供了一种代码检测装置,该代码检测装置包括:实例获取模块,用于获取反模式实例集合,该反模式实例集合包括一个或多个预设依赖关系实例,该预设依赖关系实例用于描述依赖方式为反模式的依赖关系反模式检测模块,用于基于该反模式实例集合,在待测依赖关系集合中检测目标依赖关系,该待测依赖关系集合包括由待测软件代码内的实体所构成的一组或多组依赖关系,该目标依赖关系对应的依赖方式为反模式。
第三方面,提供了一种代码检测装置,包括存储器、处理器,该存储器上存储有可在所述处理器上运行的计算机程序,所述处理器执行所述计算机程序时,使得电子设备实现如上述第一方面所述的代码检测方法的步骤。
第四方面,提供了一种计算机可读存储介质,该计算机可读存储介质存储有计算机程序,该计算机程序被处理器执行时,实现如上述第一方面所述的代码检测方法的步骤。
第五方面,提供了一种计算机程序产品,当计算机程序产品在电子设备上运行时,使得电子设备执行上述第一方面所述的代码检测方法。
第六方面,提供了一种芯片系统,该芯片系统包括处理器,该处理器与存储器耦合,该处理器执行存储器中存储的计算机程序,以实现上述第一方面所述的代码检测方法。
其中,芯片系统可以是单个芯片或者,多个芯片组成的芯片模组。
可以理解的是,上述第二方面至第六方面的有益效果可以参见上述第一方面中的相关描述,在此不再赘述。
附图说明
图1示出了通过依赖图表示依赖关系的示例图;
图2示出了两种依赖子图的示例图;
图3示出了伴生代码内的实体和原生代码内的实体之间产生的依赖关系的示意图;
图4示出了本申请实施例提供的方法100的示例性流程图;
图5示出了本申请实施例提供的反模式依赖关系的依赖子图;
图6示出了本申请实施例提供的一种代码检测装置的结构示意图;
图7示出了本申请实施例提供的另一种代码检测装置的结构示意图。
具体实施方式
下面将结合本申请实施例中的附图,对本申请实施例中的技术方案进行描述。
软件代码内的实体通常会构成各种依赖关系,可以通过依赖图等方式表示实体之间的依赖关系。图1给出了一种通过依赖图来表示依赖关系的示例。如图1所示,依赖图可以由节点和边组成。
其中,每个节点表示软件代码中的一个实体。这里的实体是指软件代码中的独立单元或对象,例如,实体具体可以是类(class)、方法(method)、变量(variable)、接口(interface)等。其中,类用于描述具有相似属性和行为的对象的模板,其类封装了数据和方法,并通过实例化创建对象;方法是一段独立的代码块,用于执行特定的任务或实现特定的功能;变量可以指的是具体参数的值;接口定义了一组操作或功能的集合,规定了实现该接口的类必须提供的方法和属性。可以理解的是,上述实体仅仅是部分类型的实体的示例,在实际应用中还有多种其他不同类型的实体,这里不作限定,不同类型的实体在代码中拥有不同的职责和功能,它们共同构成了软件系统的组成部分,相互协作完成各种任务和功能。
边是连接起发生依赖的两个实体之间的桥梁。并且,边为有向边,边的方向指代依赖发生的方向,例如,依赖关系“ei→ej”表示实体ei到实体ej的依赖关系,即实体ei依赖于实体ej,实体ei是发起依赖的实体,可以被称作源实体,实体ej是被依赖的实体,可以被称作目标实体。
对于一个实体而言,其可以依赖于一个实体,也可以依赖于多个实体,也可以不依赖于任何实体;其可以被一个实体依赖,也可以被多个实体依赖,还可以不被任何实体依赖。
一个依赖图可以被拆分成多个依赖子图,即依赖子图是依赖图的子集。一个依赖子图可以用来描述两个实体之间的依赖关系,也可以用来描述两个以上实体之间的依赖关系,本申请不作限定。图2示出了两种依赖子图的示例,其中,图2中的(a)示出了两个实体之间的依赖关系,即方法m(method m)调用方法n(method n),图2中的(b)示出了三个实体之间的依赖关系,即方法m调用方法n,同时,类B(class B)定义方法n。
由上可知,实体之间的依赖关系能够反映软件代码的结构和功能之间的关系,因此在一些应用场景下,例如在代码耦合的场景下,部分依赖关系可能会导致软件架构上的问题。下面结合具体场景进行示例性说明。
软件开发商(或称为伴生方)经常会在已有代码的基础上做进一步的定制和开发,以增强和优化软件系统的功能或性能,也就是说,伴生方开发的一些项目通常是由伴生方开发的代码耦合上游开发的源代码(也可以称作原生代码)得到的。例如,在安卓移动操作系统开源生态下,伴生方基于安卓原生代码基础仓(安卓开放源代码项目(android opensource project,AOSP))进行定制伴生和开发以满足市场用户需求、体现差异化产品特色、突出竞争力。
伴生方在开发安卓原生系统时,需要将伴生代码和原生代码进行耦合,因此会形成依赖切面,即伴生代码内的实体和原生代码内的实体之间会产生依赖关系。下面以图3为例进行说明。图3示出了原生代码和伴生代码进行耦合时产生的依赖图,在图3中包括四种实体,即活跃原生(actively native)实体,扩展(extensive)实体,侵入式原生(intrusively native)实体,旧版本原生(obsoletely native)实体。其中,活跃原生实体、侵入式原生实体、旧版本原生实体属于原生方(即上游软件系统,如原生安卓系统),统称为原生实体,扩展实体属于伴生方(即下游软件系统,定制化安卓系统),还可以称为伴生实体。活跃原生实体是由原生方创建的、未被修改(或者说保持不变)的实体,侵入式原生实体是由原生方创建的、但被伴生方侵入式修改后的实体,旧版本原生实体是由原生方创建的、被原生方弃用但被伴生方依赖的实体。在图3所示的示例中,伴生实体和原生实体之间的依赖关系构成了依赖切面,即扩展实体与侵入式原生实体之间的依赖关系,以及扩展实体与旧版本原生实体之间的依赖关系。
然而在这种场景下,实体之间的一些不良依赖方式(或称为耦合方式)可能会导致代码在后续迭代的过程会出现一些问题,如代码冲突问题,或代码运行稳定性问题等。为了方便描述,本申请将会导致代码迭代问题的不良耦合方式称为反模式(或设计反模式)。
鉴于此,本申请实施例提供了一种代码检测方法,在该方法中,可以通过预先确定的反模式实例集合检测软件代码中构成反模式的依赖关系,从而可以对这部分依赖关系进行计时处理,减少后续代码演进过程中出现的问题。下面结合图4中的方法100对本申请实施例提供的该方法的具体实现流程做示例性说明。可以理解的是,该方法100可以由服务器执行,也可以由电子设备执行,或者由服务器或电子设备上的模块执行,该电子设备例如可以是计算机(包括笔记本电脑、超级移动个人计算机(ultra-mobile personal computer,UMPC)、上网本等)、手机、平板电脑、可穿戴设备、车载设备、增强现实(augmented reality,AR)/虚拟现实(virtual reality,VR)设备、个人数字助理(personal digital assistant,PDA)等设备,本申请实施例对电子设备的具体类型不作任何限制。为了方便,后续方法100以服务器执行为例进行说明。
S110,获取反模式实例集合。
示例性地,预先获取反模式实例集合,其中,该反模式实例集合包括一个或多个预设依赖关系实例,该预设依赖关系实例用于描述依赖方式为反模式的依赖关系。
在一种可能的实现方式中,可以由开发人员基于软件代码的应用场景,预先总结并定义符合设计反模式的依赖关系,并生成所述预设依赖关系实例。例如,开发人员以定制化安卓操作系统场景下的耦合代码实例为基础,总结出各种依赖方式(或称作耦合方式),并将其中的不良依赖方式定义为反模式,并组成反模式实例集合。然后将反模式实例集合输入服务器。对应地,服务器通过输入接口获取该反模式实例集合。
在另一种可能的实现方式中,服务器也可以从内部存储器中读取预先存储的反模式实例集合。
在又一种可能的实现方式中,服务器也可以自行生成该反模式实例集合。例如,服务器可以将历史代码和日志信息输入预先训练的神经网络模型中,然后输出反模式实例集合,该日志信息记录了软件代码的运行状态、迭代过程、错误和异常信息、安全事件等。
可以理解的是,本申请实施例不限定上述预设依赖关系实例描述反模式的依赖关系的方式。作为示例,该预设依赖关系实例可以通过依赖子图的形式描述反模式的依赖关系,也可以通过机器能够识别的代码语言描述该反模式的依赖关系,或者也可以通过描述依赖关系对应的依赖属性信息和实体属性信息来描述该反模式的依赖关系,本申请对此不作限定。
下面对反模式实例集合中的预设依赖关系实例的具体含义作示例性说明。作为一种示例,该预设依赖关系实例包括第一依赖关系实例、第二依赖关系实例、第三依赖关系实例、第四依赖关系实例以及第五依赖关系实例中的至少一个。下面结合图5对这几种预设依赖关系实例分别进行说明。
第一依赖关系实例指示删除原生实体的final修饰符。例如,第一依赖关系实例表现为第一实体依赖于第二实体;依赖方式为删除所述第二实体的final修饰符;该第一实体和该第二实体的实体类别(category)均为方法或均为类;依赖类别为重写(override)或继承(inherit);第一实体为扩展实体,即第一实体的归属方为伴生方;第二实体为侵入式原生实体,即第二实体的归属方为原生方(即第二实体为)。也就是说,在第一依赖关系实例中,通过删除第二实体的final修饰符,实现第一实体对第二实体的方法重写或类继承。
图5中的(a)给出了第一依赖关系实例的一种示例,在该示例中,第一实体为方法m(method m),第二实体为方法n(method n),方法m依赖于方法n,具体地,通过删除方法n的final修饰符以实现方法重写;图5中的(b)给出了第一依赖关系实例的另一种示例,在该示例中,第一实体为类C(class C),第二实体为类D(class D),类C依赖于类D,通过删除类D的final修饰符以实现类继承。
第一依赖关系实例所指示的依赖关系可以提升伴生代码对原生代码的可访问面,以扩展功能,但是违反了开闭原则,破坏继承体系,并且原生代码在迭代后,有可能会对final修饰的实体进行修改甚至删除,从而导致方法被重载后产生新的稳定性、逻辑、性能等方面的问题。因此第一依赖关系实例描述了一种反模式的依赖关系。
第二依赖关系实例指示使用原生实体访问限制级别超过预设级别的接口。例如,第二依赖关系实例表现为第三实体依赖于第四实体;依赖方式为调用该第四实体的接口;该第三实体和该第四实体的实体类别均为方法;依赖类别为调用(call);第三实体为扩展实体,即第三实体的归属方为伴生方;第四实体为活跃原生实体或旧版本原生实体,即该第四实体的归属方为原生方;该第四实体的接口的访问限制级别(restriction level)超过预设级别。
图5中的(c)给出了第二依赖关系实例的一种示例,在该示例中,第三实体为方法m,第四实体为方法n,方法m依赖于方法n,具体地,方法m调用方法n的接口,并且方法n的接口的访问限制级别为hidden(即高限制级别接口)。
第二依赖关系实例所指示的依赖关系中,为了满足功能需求,使用软件代码实体访问限制级别较高的原生接口(即不允许使用或不推荐使用的接口),这类接口极不稳定,使用范围受外部约束,因此容易对后续代码演进造成影响。因此第二依赖关系实例描述了另一种反模式的依赖关系。
第三依赖关系实例指示在原生类中添加伴生内部类。例如,第三依赖关系实例表现为第五实体依赖于第六实体;依赖方式为第五实体包含(contain)第六实体;第五实体和第六实体的实体类别均为类;依赖类别为定义(define);第五实体为浸入式原生实体,即第五实体的归属方为原生方;第六实体为扩展实体,即第六实体的归属方为伴生方。
图5中的(d)给出了第三依赖关系实例的一种示例,在该示例中,第五实体为类A,第六实体为类B,类A依赖于类B,具体地,类A包含类B。另外,类A定义了方法m,且方法m为私有方法;类B定义了方法n,且方法n调用方法m。也就是说,通过在原生类(类A)中添加伴生内部类(类B),以访问原生类中的私有(private)方法或公开(public)方法(方法m)。
第三依赖关系实例指示的依赖关系中,通过在原生类中添加伴生内部类,可以访问原生类中的方法以扩大访问面。但是,如果访问的是原生类的公开(public)方法,这样既无法达到扩大可访问面的目的,反而由于对原生类的侵入式修改,更容易导致代码演进时产生代码冲突等问题。因此第三依赖关系实例描述了又一种反模式的依赖关系。
第四依赖关系实例指示对原生方法添加参数。例如,第四依赖关系实例表现为第七实体依赖于第八实体;第七实体的实体类别为方法,该第八实体的实体类别为变量;依赖类别为参数(parameter)添加;第七实体为侵入式原生实体,即第七实体的归属方为原生方;第八实体为扩展实体,即第八实体的归属方为伴生方。
图5中的(e)给出了第四依赖关系实例的一种示例,在该示例中,第七实体为方法m,第八实体为变量v,方法m依赖于变量v,具体地,方法m添加变量v作为参数。
第四依赖关系实例指示的依赖关系中,通过对原生方法增加参数,以扩展原生接口的功能,但是该方法的修改会级联得导致任何调用该方法的位置都需要进行适配,如果原生代码发生了修改,伴生代码将需要大量的适配工作。因此第四依赖关系实例描述了又一种反模式的依赖关系。
第五依赖关系实例指示原生类继承伴生类。例如,第五依赖关系实例变现为第九实体依赖于第十实体;第九实体和第十实体的实体类别均为类;依赖类别为继承(inherit);第九实体为侵入式原生实体,即第九实体的归属方为原生方;第十实体为扩展实体,即第十实体的归属方为伴生方。
图5中的(f)给出了第五依赖关系实例的一种示例,在该示例中,第九实体为类A,第十实体为类B,类A依赖于类B,具体地,类A继承类B。
第五依赖关系实例指示的依赖关系中,通过修改原生类的父类,以达到扩展原生类功能的同时减少对原生类的侵入式修改,但是原生类(类A)的子类可能会重载该原生类中的方法,若在升级中对该原生类的方法进行修改,由于修改的方法被重写,故这种变动容易被忽略,即使编译通过在运行时也会出现语义冲突等问题,难以定位。因此第五依赖关系实例描述了又一种反模式的依赖关系。
可以理解的是,本申请实施例仅示例性地给出了部分符合反模式的预设依赖关系实例,其他可能会导致代码迭代问题的不良依赖关系实例也应在本申请的保护范围内。
S120,基于该反模式实例集合,在待测依赖关系集合中检测目标依赖关系。
示例性地,在获取反模式实例集合之后,基于该反模式实例集合,在待测依赖关系集合中检测目标依赖关系集合。其中,该待测依赖关系集合包括由待测软件代码内的实体所构成的一组或多组依赖关系,该目标依赖关系对应的依赖方式为反模式,该目标依赖关系包括一种或多种依赖关系。也就是说,本申请实施例提供的方法,基于反模式实例集合,检测待测软件代码中的反模式依赖关系。
上述待测软件代码例如可以是由伴生代码耦合原生代码得到,也就是说,该待测软件代码可以是一段耦合代码,如软件开发商将伴生代码耦合安卓原生代码后得到的定制化安卓操作系统的软件代码。在一种示例中,该待测软件代码还可以仅包括伴生代码,以及原生代码中被侵入式修改后的代码。
在第一种可能的实现方式中,该待测依赖关系集合可以包括该待测软件代码内的实体所构成的所有依赖关系。通过这种方式可以对该待测软件代码内产生的所有依赖关系进行检测,避免因未被检测导致部分反模式的依赖关系没能得到及时处理的情况。
在第二种可能的实现方式中,该待测依赖关系集合可以包括该待测软件代码内实体所构成的部分依赖关系中的部分依赖。也就是说,可以提前对将要测量的依赖关系进行筛选,以降低检测量,节省资源开销。
作为第二种可能的实现方式对应的一种示例,该待测依赖关系集合包括伴生代码内的实体与原生代码内的实体之间所构成的依赖关系。也就是说,我们可以仅关注由于伴生代码和原生代码耦合所产生的依赖关系,通过这种方式,在尽量减少检测量的同时,还可以对主要产生反模式问题的依赖关系进行检测。具体例如,可以基于DepFCD工具对待测软件代码进行处理以获得依赖切面Rf={r},该依赖切面即表示原生实体和伴生实体之间的依赖关系。在一种可能的实现方式中,依赖切面Rf包括的是原生实体和伴生实体之间直接的依赖关系(即确定的依赖关系),这里的直接的依赖关系是相对间接的依赖关系而言的,例如,r1依赖于r2,r2依赖于r3,则r1和r2之间,以及r2和r3之间具有确定的依赖关系,r1和r3之间具有间接的依赖关系。其中,DepFCD是一个用Python编写的工具,可以检测原生-伴生开发场景中,软件代码的伴生历史信息,软件代码内实体的归属方以及依赖切面信息。
可选地,该待测依赖关系集合还可以包括该伴生代码内的不同实体之间所构成的依赖关系。也就是说,我们还可以进一步关注伴生代码内部所产生的依赖关系。例如,首先可以调用ENRE工具获取待测软件代码内的基础依赖信息,具体地,可以通过ENRE工具获取待测软件代码的基础依赖信息,该基础依赖信息包括:待测软件代码内实体的唯一索引名、实体名、实体类别、实体参数(方法实体)、访问限制级别,以及实体之间产生的依赖关系的依赖类型、依赖源实体、依赖目标实体。其中,ENRE工具是一个用Java编写的库/API,可以检测软件代码的静态依赖。基于上述基础依赖信息,可以确定待测软件代码内实体构成的依赖关系集合。进一步地,可以调用DepFCD获取待测软件代码实体归属方信息(原生方或是伴生方)。基于该实体归属方信息,可以从上述确定的依赖关系集合中确定伴生代码内的不同实体之间所构成的依赖关系集合,即伴生添加的依赖关系集合Re={r}。
进一步可选地,该待测依赖关系集合还包括由待测软件代码内的实体构成的依赖关系中依赖类型为定义(define)的依赖关系。例如,通过调用ENRE工具获取待测软件代码内的基础依赖信息之后,基于该基础依赖信息确定依赖类型为定义(define)的依赖关系集合Rd={r}。
因此,本申请实施例中所述的待测依赖关系集合可以是Rf、Re、Rd的并集,即Rf∪Re∪Rd。
因此,在上述可能的实现方式中,待测依赖关系集合仅包括待测软件代码内实体构成的依赖关系中的部分依赖关系,从而可以减少检测量,提高检测效率。并且,待测依赖关系集合中主要包括原生实体和伴生实体之间的依赖关系,以及伴生实体与伴生实体之间的依赖关系,而不包括原生实体与原生实体之间的依赖关系,因为原生实体与原生实体之间的依赖关系通常存在于原生代码中,伴生方通常无法对这部分依赖关系进行调整,因此可以不对这部分依赖关系进行检测,从而减少检测量,降低资源消耗。
可选地,在确定待测依赖关系集合之前,还可以先将由待测软件代码内的实体所构成的依赖关系中的冗余关系进行过滤得到基础依赖关系,然后从该基础依赖关系中确定该待测依赖关系集合。其中,该冗余关系包括日志信息对应的依赖关系和/或工具类代码对应的依赖关系。由于冗余关系通常占据了大量的内容,而这些内容对检测反模式的依赖关系会造成一定的干扰,因此预先将这些冗余关系进行过滤,可以降低检测量,提高检测效率。
可以理解的是,上述确定待测依赖关系集合的步骤可以在S110之前执行,也可以在S110之后执行,本申请对此不作限定。
可选地,在确定待测依赖关系集合之前,可以先获取该待测软件代码中的重构信息,并基于该重构信息对该待测软件代码中的侵入式实体的属性信息做重构修正。其中,该重构信息所指示的重构操作包括以下一项或多项:类和方法的提取,重命名,移动,以及方法参数的修改。例如,调用重构检测工具RefactoringMiner分析待测软件代码中的重构信息,结合重构信息对待测软件代码侵入式实体部分的属性信息做重构修正,具体过程这里不作限定。其中,RefactoringMiner是一个用Java编写的库/API,可以检测软件代码中应用的重构,其中重构信息可以表示为RefInfo={(e1,m,e2)},e1表示重构操作对应原生代码实体属性,e2表示重构操作对应伴生代码实体属性,m表示重构内容。通过这种方式可以降低待测软件代码的耦合度,减少构成反模式的依赖关系的数量。
下面对检测目标依赖关系的具体实现方式作示例性说明。
示例性地,首先获取反模式实例集合中的每个预设依赖关系实例对应的依赖属性信息和实体属性信息。也就是说,首先需要将反模式实例集合中的预设依赖关系实例转换为代码可识别的描述规则Rules,例如以key-value的形式依次描述预设依赖关系实例的每条依赖边的依赖属性和实体属性。
作为示例,该依赖属性信息包括依赖类别(category→string),该实体属性信息包括:源实体归属方(ownership→string),目标实体归属方,源实体类别(category→string)和/或源实体索引,目标实体类别(category→string)和/或目标实体索引(id→int)。
可选地,该实体属性信息还包括实体final修饰修改属性(final_del→bool)和/或实体可访问属性(accessible→array[string])。
进一步地,将该待测依赖关系集合中,与该反模式实例集合中的任意预设依赖关系实例对应的依赖属性信息和实体属性信息匹配的依赖关系,确定为该目标依赖关系。换句话说,当待测依赖关系集合中的某个依赖关系的依赖属性和实体属性与反模式实例集合中的某个预设依赖关系实例的依赖属性和实体属性相匹配,则将该依赖关系确定为目标依赖关系。
下面对一种可能的实现方式作示例性说明。
以待测依赖关系集合中的依赖关系对应的依赖属性信息和实体属性信息为键值,构建查询字典。
例如,构建查询字典RelationDictionary={(category, direction, src, dest)→{r}},其中,category代表依赖类别;direction代表依赖的源实体和目标实体的归属方组合,可以将伴生方记为1,原生方记为0,即direction的可选值为00,01,10,11四种,“00”表示源实体和目标实体均属于原生方,“01”表示源实体属于原生方,目标实体属于伴生方,“10”表示源实体属于伴生方,目标实体属于原生方,“11”表示源实体和目标实体均属于伴生方;src表示源实体的实体类别或唯一索引,dest表示目标实体的实体类别或唯一索引。具体的,对于待测依赖关系集合中的任一依赖关系r构建以下索引中的至少一项,通过以上七种索引方式中的任一种访问到包含依赖r的依赖集合:
RelationDictionary[r.category][r.direction][r.src.category][r.dest.category];
RelationDictionary[r.category][r.direction][r.src.category][r.dest.id];
RelationDictionary[r.category][r.direction][r.src.id][r.dest.category];
RelationDictionary[r.category][r.direction][r.src.id][r.dest.id];
RelationDictionary[r.category][r.direction][r.src.category][r.src.id][r.dest.category];
RelationDictionary[r.category][r.direction][r.src.category][r.dest.category][r.dest.id];
RelationDictionary[r.category][r.direction][r.src.category][r.src.id][r.dest.category][r.dest.id]。
在生成上述查询字典之后,将该反模式实例集合中的预设依赖关系实例对应的依赖属性信息和实体属性信息在该查询字典中进行匹配检索,确定该目标依赖关系。
作为一种示例,可以先初始化两个依赖集合sample={}和result={},并且获取反模式实例集合中的每个预设依赖关系实例对应的依赖属性信息和实体属性信息,例如,依次对预设依赖关系实例中的每条依赖边进行解析,获得依赖属性信息rel(依赖类别category),源实体的实体属性信息src(实体类别src_category和/或唯一索引src_index),目标实体的实体属性信息dest(实体类别dest_category和/或唯一索引dest_index)(可以优先使用dest_index,在dest_index无效时则使用dest_category),以及源实体和目标实体的实体归属方组合信息direction。然后基于该预设依赖关系实例的依赖属性信息和实体属性信息,结合RelationDictionary进行匹配检索,若匹配到依赖关系match={r}(即至少一个预设依赖关系实例的依赖属性信息和实体属性信息与该依赖关系对应在查询字典中的索引匹配),对match进行深度优先匹配,将r加入sample。
进一步地,检测sample中的依赖关系是否满足预设依赖关系实例对应的依赖关系,如果是的话,则将该依赖关系加入result,否则对下一条依赖边规则Rule重复此步骤,直到与所有Rule匹配的所有依赖边检索完毕。
例如,从匹配成功的预设依赖关系实例中提取源实体的实体属性信息src中的其他属性信息,以及目标实体的实体属性信息dest中的其他属性信息。这里的其他属性信息指的是上述实体类别和唯一索引以外的其他实体属性信息,例如实体final修饰修改属性和/或实体可访问属性。然后判断sample中的依赖关系r中的源实体和目标实体的其他属性信息,是否与该预设依赖关系实例的源实体和目标实体的其他属性信息匹配,如果是的话,则将该依赖关系r添加到result集合中,该result集合为最终匹配成功的依赖关系的集合。
以其他属性信息为final_del为例。若预设依赖关系实例中的实体对应的src.final_del为true,则表示该实体为原生实体,伴生时(即伴生代码在进行耦合时对其进行了侵入式修改)删除了该原生实体final修饰符。然后遍历sample集合中的每一个依赖关系,以其中一个依赖关系r为例,结合实体字典EntityDictionary获取其源实体src映射的原生实体native_src,若源实体src的final属性为false,且该源实体对应的原生实体native_src的final属性为true,则将该依赖关系r加入最终匹配的依赖集result={r}。可以理解的是,上述源实体为侵入式原生实体,其对应的原生实体指的是改侵入式原生实体对应的、经过侵入式修改之前的、原生代码内的实体。
在一种可能的实现方式中,可以先获取侵入式原生实体所对应的原生代码中原生实体的唯一索引名,进而获取该侵入式原生实体的其他属性或非属性依赖信息的变化情况,包括实体修饰符变化、实体所继承父类的变化以及实体参数的变化等。下面对获取侵入式原生实体所对应的原生代码中原生实体的唯一索引名的一种可能的实现方式作示例性说明:
首先,初始化待测软件代码中侵入式原生实体集E与对应的原生代码内的原生实体的映射字典,EntityDictionary = {e→Ø},初始化原生代码实体类别、全名及参数属性信息映射NativeEntityDictionary = {(category,qualifiedName,params)→e},初始化侵入式原生实体集E重构前属性信息ExtEntityBeforeRef = { e→(e.category,e.qualifiedName,e.params)}。
然后,基于软件代码伴生历史信息{commit},获取伴生重构信息集合,表示为RefInfo[commit]。
进一步地,对于RefInfo[commit]中的每一重构信息(ei,m,ej),如果ej与EntityDictionary中某实体ek信息匹配,则将重构前实体信息更新至ExtEntityBeforeRef[ek]= (ei.category,ei.qualifiedName,ei.params)。
对于EntityDictionary中的每一个实体,得到映射的原生实体 en=NativeEntityDictionary[ExtEntityBeforeRef[e]],并将映射的原生实体唯一索引名更新至EntityDictionary[e]=en.index。
下面以图5中的(d)所示的预设依赖关系实例为例,具体介绍在待测依赖关系集合中检测目标依赖关系的一种可能的实现方式。
图5中的(d)所示的依赖子图描述了在原生类中添加伴生内部类的依赖关系,该依赖关系包括四条边,下面分别对这四条边对应的依赖关系进行描述。
将类A和类B之间组成的依赖边记为依赖边#1,其对应的描述规则Rule#1为:原生类中伴生添加内部类,即原生class定义(define)伴生class,源实体和目标实体的实体类型均为class,依赖类型为define,源实体为侵入式原生实体,即源实体属于原生方,目标实体为扩展实体,即目标实体属于伴生方,因此direction可以采用“01”表示。
将类B和方法n之间组成的依赖边记为依赖边#2,其对应的描述规则Rule#2为:在伴生内部类中定义伴生方法,即伴生class定义(define)伴生method,源实体的实体类型为class,目标实体的实体类型为method,依赖类型为define,源实体和目标实体均为扩展实体,即源实体和目标实体均属于伴生方,因此direction可以采用“11”进行描述。应理解,依赖边#2的源实体与依赖边#1的目标实体为同一实体,因此此处通过id绑定索引值信息。
将方法n和方法m之间组成的依赖边记为依赖边#3,其对应的描述规则Rule#3为:伴生方法调用原生方法,即伴生method调用(call)原生method,源实体和目标实体的实体类型均为method,依赖类型为call,源实体为扩展实体,即源实体属于伴生方,目标实体为原生实体,即目标实体属于原生方,因此direction可以采用“10”进行描述。同时,目标实体的实体可访问属性(accessible属性)为public,即方法m为public方法。应理解,依赖边#3的源实体与依赖边#2的目标实体为同一实体,因此此处通过id绑定索引值信息。
将类A和方法m之间组成的依赖边记为依赖边#4,其对应的描述规则Rule#4为:原生类定义原生方法,即原生class定义(define)原生method,源实体为class,目标实体为method,雨来类型为define,源实体和目标实体属于原生方,因此direction可以采用“00”进行描述。应理解,依赖边#4的源实体与依赖边#1的源实体为同一实体,依赖边#4的目标实体与依赖边#3的目标实体为同一实体,因此此处通过id绑定索引值信息。
分别将上述四条依赖边所对应的依赖关系转化为代码可以识别的规则描述如下:
/>
解析上述预设依赖实例各依赖边的描述规则Rule。另外,构建查询字典RelationDictionary;初始化反模式实例集result={}以及单实例依赖集sample={}。
基于上述描述规则Rule和查询字典进行匹配检索:
第一次匹配查询:解析依赖边#1对应的Rule#1,获得依赖属性Define,实体属性src:'class',dest:'class',direction='01'。基于Rule#1在RelationDictionary进行匹配检索,假设待测依赖关系集合中只有依赖r1满足匹配条件,最终匹配集合{r1},匹配其中的r1,并更新sample={r1}。
第二次匹配查询:解析依赖边#2对应的Rule#2,获得依赖属性Define,实体属性src:r1.dest.id,dest:'method',direction='11'。基于Rule#2以及依赖r1中的目标实体的唯一索引(依赖边#2的源实体与依赖边#1的目标实体为同一实体)再次在RelationDictionary进行匹配检索,假设待测依赖关系集合中的依赖r2,r3均满足匹配条件,得到匹配集合{r2, r3},先匹配其中的r2,并更新sample={r1, r2}。
第三次匹配查询:解析依赖边#3对应的Rule#3,获得依赖属性Call,实体属性src:r2.dest.id,dest:'method',direction='10'。基于Rule#3以及依赖r2的目标实体的唯一索引(依赖边#3的源实体与依赖边#2的目标实体为同一实体)再次在RelationDictionary进行匹配检索,假设没有依赖满足匹配条件,得到匹配集合{},由于匹配集合为空,依赖r2无法构成反模式,因此,更新sample={r1}。
再次匹配第二次匹配查询得到的集合{r2, r3}中的r3,并更新sample={r1, r3}。
第四次匹配查询:解析依赖边#3对应的Rule#3,获得依赖属性Call,实体属性src:r3.dest.id,dest:'method',direction='10'。基于Rule#3以及依赖r3的目标实体的唯一索引(依赖边#3的源实体与依赖边#2的目标实体为同一实体)再次在RelationDictionary进行匹配检索,假设待测依赖关系集合中的依赖r4,r5均满足匹配条件,进一步判断r4和r5的实体属性信息中的其他属性信息是否满足匹配条件。由于依赖边#3中目标实体的实体可访问属性(accessible属性)为public,因此检测r4和r5的accessible属性是否匹配。假设r4不匹配,但r5匹配,因此更新sample={r1, r3, r5}。
第五次匹配查询:解析依赖边#4对应的Rule#4,获得依赖属性Define,实体属性src:r1.src.id,dest:r5.dest.id,direction='00'。基于Rule#4以及依赖r1的源实体的唯一索引和依赖r5的目标实体的唯一索引(依赖边#4的源实体与依赖边#1的源实体为同一实体,依赖边#4的目标实体与依赖边#3的目标实体为同一实体)在RelationDictionary进行匹配检索,假设只有依赖r6满足匹配条件,得到最终匹配集合{r6},匹配其中的r6,并更新sample={r1, r3, r5, r6},此时sample满足反模式实例,将sample添加至result中至此反模式伴生添加内部类检测完成。
综上所述,本申请实施例提供的代码检测方法,可以预先确定反模式实例集合,以获取符合反模式的预设依赖关系实例,进一步地可以将与预设依赖关系实例匹配的依赖关系确定为符合反模式的目标依赖关系。本申请实施例提供的方法是一种通用的用于检测反模式的方法,能够适用不同开发商的演进场景,也就是说,可以不仅仅针对单一开发商在代码迭代过程出现的具体问题(如一套代码中循环依赖等问题)。在该方法中,新定义了反模式的依赖关系,该反模式依赖关系更加关注伴生代码基于原生代码的耦合情况,因此基于反模式实例集合最终检测到的目标依赖关系更能反应不良耦合可能带来的架构隐患。同时,反模式中涉及的实体修改都与伴生代码的开发者有关,更有利于开发者进行缺陷定位和代码理解,而不仅仅是将反模式检测停留在冲突分析层面。
相应于上述各方法实施例给出的方法,本申请实施例还提供了相应的装置,该装置例如是服务器或电子设备,该电子设备包括用于执行上述各个方法实施例相应的模块。该模块可以是软件,也可以是硬件,或者是软件和硬件结合。可以理解的是,上述各方法实施例所描述的技术特征同样适用于以下装置实施例,因此,未详细描述的内容可以参见上文方法实施例,为了简洁,这里不再赘述。
图6示出了本申请实施例提供的装置200的结构框图,为了方便,仅示出了与本申请实施例相关的部分。参照图6,该装置200具体可以包括以下模块:
实例获取模块210,用于获取反模式实例集合,该反模式实例集合包括一个或多个预设依赖关系实例,该预设依赖关系实例用于描述依赖方式为反模式的依赖关系。
反模式检测模块220,用于基于该反模式实例集合,在待测依赖关系集合中检测目标依赖关系,该待测依赖关系集合包括由待测软件代码内的实体所构成的一组或多组依赖关系,该目标依赖关系对应的依赖方式为反模式。
需要说明的是,上述模块/单元之间的信息交互、执行过程等内容,由于与本申请方法实施例基于同一构思,其具体功能及带来的技术效果,具体可参见方法和系统实施例部分,此处不再赘述。
图7示出了本申请实施例提供的另一种装置300的结构示意图,该装置300包括:至少一个处理器310、存储器320以及存储在所述存储器中并可在所述至少一个处理器上运行的计算机程序321,所述处理器执行所述计算机程序时实现上述任意各个方法实施例中的步骤。
本申请实施例还提供了一种计算机可读存储介质,所述计算机可读存储介质存储有计算机程序,所述计算机程序被处理器执行时实现可实现上述各个方法实施例中的步骤。
本申请实施例提供了一种计算机程序产品,当计算机程序产品在装置上运行时,使得该装置执行时实现可实现上述各个方法实施例中的步骤。
集成的单元如果以软件功能单元的形式实现并作为独立的产品销售或使用时,可以存储在一个计算机可读取存储介质中。基于这样的理解,本申请实现上述实施例方法中的全部或部分流程,可以通过计算机程序来指令相关的硬件来完成,所述的计算机程序可存储于一计算机可读存储介质中,该计算机程序在被处理器执行时,可实现上述各个方法实施例的步骤。其中,所述计算机程序包括计算机程序代码,所述计算机程序代码可以为源代码形式、对象代码形式、可执行文件或某些中间形式等。所述计算机可读介质至少可以包括:能够将计算机程序代码携带到拍照装置/电子设备的任何实体或装置、记录介质、计算机存储器、只读存储器(read-only memory,ROM)、随机存取存储器(random accessmemory,RAM)、电载波信号、电信信号以及软件分发介质。例如U盘、移动硬盘、磁碟或者光盘等。在某些司法管辖区,根据立法和专利实践,计算机可读介质不可以是电载波信号和电信信号。
在上述实施例中,对各个实施例的描述都各有侧重,某个实施例中没有详述或记载的部分,可以参见其它实施例的相关描述。
本领域普通技术人员可以意识到,结合本文中所公开的实施例描述的各示例的单元及算法步骤,能够以电子硬件、或者计算机软件和电子硬件的结合来实现。这些功能究竟以硬件还是软件方式来执行,取决于技术方案的特定应用和设计约束条件。专业技术人员可以对每个特定的应用来使用不同方法来实现所描述的功能,但是这种实现不应认为超出本申请的范围。
在本申请所提供的实施例中,应该理解到,所揭露的装置/网络设备和方法,可以通过其它的方式实现。例如,以上所描述的装置/网络设备实施例仅仅是示意性的,例如,所述模块或单元的划分,仅仅为一种逻辑功能划分,实际实现时可以有另外的划分方式,例如多个单元或组件可以结合或者可以集成到另一个系统,或一些特征可以忽略,或不执行。另一点,所显示或讨论的相互之间的耦合或直接耦合或通讯连接可以是通过一些接口,装置或单元的间接耦合或通讯连接,可以是电性,机械或其它的形式。
所述作为分离部件说明的单元可以是或者也可以不是物理上分开的,作为单元显示的部件可以是或者也可以不是物理单元,即可以位于一个地方,或者也可以分布到多个网络单元上。可以根据实际的需要选择其中的部分或者全部单元来实现本实施例方案的目的。
以上所述实施例仅用以说明本申请的技术方案,而非对其限制;尽管参照前述实施例对本申请进行了详细的说明,本领域的普通技术人员应当理解:其依然可以对前述各实施例所记载的技术方案进行修改,或者对其中部分技术特征进行等同替换;而这些修改或者替换,并不使相应技术方案的本质脱离本申请各实施例技术方案的精神和范围,均应包含在本申请的保护范围之内。
另外,需要说明的是,在本申请中涉及的各种数字编号(如说明书和权利要求书及上述附图中的术语“第一”、“第二”、“第三”、“第四”以及其他各种术语标号等(如果存在)等)仅为描述方便进行的区分,并不用来限制本申请的范围。各过程的序号的大小并不意味着执行顺序的先后,各过程的执行顺序应以其功能和内在逻辑确定。
术语“包括”和“具有”以及他们的任何变形都意味着“包括但不限于”,除非是以其他方式特别强调,例如,包括了一系列步骤或单元的过程、方法、系统、产品或设备不必限于清楚地列出的那些步骤或单元,而是可包括没有清楚地列出的或对于这些过程、方法、产品或设备固有的其它步骤或单元。
在本申请实施例中,“示例性地”或者“例如”等词用于表示作例子、例证或说明。本申请实施例中被描述为“示例性地”或者“例如”的任何实施例或设计方案不应被解释为比其它实施例或设计方案更优选或更具优势。确切而言,使用“示例性地”或者“例如”等词旨在以具体方式呈现相关概念。
在本申请的各个实施例中,如果没有特殊说明以及逻辑冲突,不同的实施例之间的术语和/或描述具有一致性、且可以相互引用,不同的实施例中的技术特征根据其内在的逻辑关系可以组合形成新的实施例。本申请方法实施例中的具体操作方法也可以应用于装置实施例或系统实施例中。
本申请实施例中涉及的“存储”或“保存”,可以是指的保存在一个或者多个存储器中。所述一个或者多个存储器,可以是单独的设置,也可以是集成在编码器或者译码器,处理器、或电子设备中。所述一个或者多个存储器,也可以是一部分单独设置,一部分集成在译码器、处理器、或电子设备中。存储器的类型可以是任意形式的存储介质,本申请并不对此限定。
Claims (11)
1.一种代码检测方法,其特征在于,所述方法包括:
获取反模式实例集合,所述反模式实例集合包括一个或多个预设依赖关系实例,所述预设依赖关系实例用于描述依赖方式为反模式的依赖关系,所述反模式的依赖关系为会导致待测软件代码产生代码迭代问题的不良依赖关系,所述待测软件代码是由伴生代码耦合原生代码得到的,所述预设依赖关系实例包括第一依赖关系实例、第二依赖关系实例、第三依赖关系实例、第四依赖关系实例以及第五依赖关系实例中的至少一个;其中,所述第一依赖关系实例指示删除原生实体的final修饰符,所述第二依赖关系实例指示使用原生实体访问限制级别超过预设级别的接口,所述第三依赖关系实例指示在原生类中添加伴生内部类,所述第四依赖关系实例指示对原生方法添加参数,所述第五依赖关系实例指示原生类继承伴生类;
基于所述反模式实例集合,在待测依赖关系集合中检测目标依赖关系,所述待测依赖关系集合包括所述伴生代码内的实体与所述原生代码内的实体之间所构成的依赖关系,所述目标依赖关系的依赖属性和实体属性与所述反模式实例集合中的至少一个预设依赖关系实例的依赖属性和实体属性匹配,所述目标依赖关系对应的依赖方式为反模式。
2.根据权利要求1所述的方法,其特征在于,所述待测依赖关系集合还包括所述伴生代码内的不同实体之间所构成的依赖关系,和/或由待测软件代码内的实体构成的依赖关系中依赖类型为定义define的依赖关系。
3.根据权利要求1或2所述的方法,其特征在于,在所述在待测依赖关系集合中检测目标依赖关系之前,所述方法还包括:
将由待测软件代码内的实体所构成的依赖关系中的冗余关系进行过滤得到基础依赖关系,所述冗余关系包括日志信息对应的依赖关系和/或工具类代码对应的依赖关系;
从所述基础依赖关系中确定所述待测依赖关系集合。
4.根据权利要求1或2所述的方法,其特征在于,在所述在待测依赖关系集合中检测目标依赖关系之前,所述方法还包括:
获取所述待测软件代码中的重构信息;
基于所述重构信息对所述待测软件代码中的侵入式实体的属性信息做重构修正。
5.根据权利要求4所述的方法,其特征在于,所述重构信息所指示的重构操作包括以下一项或多项:类和方法的提取,重命名,移动,以及方法参数的修改。
6.根据权利要求1或2所述的方法,其特征在于,所述基于所述反模式实例集合,在待测依赖关系集合中检测目标依赖关系,包括:
获取所述反模式实例集合中的每个预设依赖关系实例对应的依赖属性信息和实体属性信息;
将所述待测依赖关系集合中,与所述反模式实例集合中的任意预设依赖关系实例对应的依赖属性信息和实体属性信息匹配的依赖关系,确定为所述目标依赖关系。
7.根据权利要求6所述的方法,其特征在于,所述依赖属性信息包括依赖类别,所述实体属性信息包括:源实体归属方,目标实体归属方,源实体类别和/或源实体索引,目标实体类别和/或目标实体索引。
8.根据权利要求7所述的方法,其特征在于,所述实体属性信息还包括实体final修饰修改属性和/或实体可访问属性。
9.根据权利要求6所述的方法,其特征在于,所述将所述待测依赖关系集合中,与所述反模式实例集合中的任意预设依赖关系实例对应的依赖属性信息和实体属性信息匹配的依赖关系,确定为所述目标依赖关系,包括:
以所述待测依赖关系集合中的依赖关系对应的依赖属性信息和实体属性信息为键值,构建查询字典;
将所述反模式实例集合中的预设依赖关系实例对应的依赖属性信息和实体属性信息在所述查询字典中进行匹配检索,确定所述目标依赖关系。
10.一种代码检测装置,其特征在于,所述代码检测装置的结构中包括处理器和存储器;
所述存储器用于存储支持所述代码检测装置执行如权利要求1至9中任意一项所提供的方法的程序,以及存储用于实现如权利要求1至9中任意一项所述的方法所涉及的数据;
所述处理器被配置为用于执行所述存储器中存储的程序。
11.一种计算机可读存储介质,其特征在于,所述计算机可读存储介质中存储有指令,当其在计算机上运行时,使得计算机执行如权利要求1至9中任意一项所述的方法。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202311736739.4A CN117421252B (zh) | 2023-12-18 | 2023-12-18 | 代码检测方法、装置及计算机可读存储介质 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202311736739.4A CN117421252B (zh) | 2023-12-18 | 2023-12-18 | 代码检测方法、装置及计算机可读存储介质 |
Publications (2)
Publication Number | Publication Date |
---|---|
CN117421252A CN117421252A (zh) | 2024-01-19 |
CN117421252B true CN117421252B (zh) | 2024-05-31 |
Family
ID=89530551
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN202311736739.4A Active CN117421252B (zh) | 2023-12-18 | 2023-12-18 | 代码检测方法、装置及计算机可读存储介质 |
Country Status (1)
Country | Link |
---|---|
CN (1) | CN117421252B (zh) |
Citations (11)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US9323644B1 (en) * | 2015-09-30 | 2016-04-26 | Semmle Limited | Query-based software dependency analysis |
CN109977008A (zh) * | 2019-02-22 | 2019-07-05 | 福建天泉教育科技有限公司 | 一种应用程序依赖的js代码与原生库兼容的方法及终端 |
CN111797157A (zh) * | 2020-07-21 | 2020-10-20 | 政采云有限公司 | 一种数据处理方法、系统及电子设备和存储介质 |
CN112579152A (zh) * | 2019-09-30 | 2021-03-30 | 南京大学 | 一种面向Python语言的文档缺陷检测方法 |
CN113778852A (zh) * | 2021-06-04 | 2021-12-10 | 南方科技大学 | 一种基于正则表达式的代码分析方法 |
CN114328208A (zh) * | 2021-12-24 | 2022-04-12 | 中国电信股份有限公司 | 代码检测方法及装置、电子设备、存储介质 |
CN115185818A (zh) * | 2022-06-20 | 2022-10-14 | 南京邮电大学 | 一种基于二进制集合的程序依赖簇检测方法 |
US11544046B1 (en) * | 2020-08-26 | 2023-01-03 | Amazon Technologies, Inc. | Dynamic cloud anti-pattern detection for a modernization assessment service |
CN116069671A (zh) * | 2023-03-20 | 2023-05-05 | 南京优测信息科技有限公司 | 跨语言软件源代码的综合依赖关系分析 |
CN116610568A (zh) * | 2023-05-09 | 2023-08-18 | 支付宝(杭州)信息技术有限公司 | 一种识别代码的依赖关系的方法、装置、设备及介质 |
CN117149980A (zh) * | 2023-09-15 | 2023-12-01 | 交叉信息核心技术研究院(西安)有限公司 | 基于指标森林的架构衰退检测方法、系统、装置及介质 |
-
2023
- 2023-12-18 CN CN202311736739.4A patent/CN117421252B/zh active Active
Patent Citations (11)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US9323644B1 (en) * | 2015-09-30 | 2016-04-26 | Semmle Limited | Query-based software dependency analysis |
CN109977008A (zh) * | 2019-02-22 | 2019-07-05 | 福建天泉教育科技有限公司 | 一种应用程序依赖的js代码与原生库兼容的方法及终端 |
CN112579152A (zh) * | 2019-09-30 | 2021-03-30 | 南京大学 | 一种面向Python语言的文档缺陷检测方法 |
CN111797157A (zh) * | 2020-07-21 | 2020-10-20 | 政采云有限公司 | 一种数据处理方法、系统及电子设备和存储介质 |
US11544046B1 (en) * | 2020-08-26 | 2023-01-03 | Amazon Technologies, Inc. | Dynamic cloud anti-pattern detection for a modernization assessment service |
CN113778852A (zh) * | 2021-06-04 | 2021-12-10 | 南方科技大学 | 一种基于正则表达式的代码分析方法 |
CN114328208A (zh) * | 2021-12-24 | 2022-04-12 | 中国电信股份有限公司 | 代码检测方法及装置、电子设备、存储介质 |
CN115185818A (zh) * | 2022-06-20 | 2022-10-14 | 南京邮电大学 | 一种基于二进制集合的程序依赖簇检测方法 |
CN116069671A (zh) * | 2023-03-20 | 2023-05-05 | 南京优测信息科技有限公司 | 跨语言软件源代码的综合依赖关系分析 |
CN116610568A (zh) * | 2023-05-09 | 2023-08-18 | 支付宝(杭州)信息技术有限公司 | 一种识别代码的依赖关系的方法、装置、设备及介质 |
CN117149980A (zh) * | 2023-09-15 | 2023-12-01 | 交叉信息核心技术研究院(西安)有限公司 | 基于指标森林的架构衰退检测方法、系统、装置及介质 |
Also Published As
Publication number | Publication date |
---|---|
CN117421252A (zh) | 2024-01-19 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
US8239404B2 (en) | Identifying entries and exits of strongly connected components | |
CN108268777B (zh) | 一种利用补丁信息进行未知漏洞发现的相似性检测方法 | |
CN109117164B (zh) | 基于关键元素差异性分析的微服务更新方法及系统 | |
US10394694B2 (en) | Unexplored branch search in hybrid fuzz testing of software binaries | |
US7853930B2 (en) | Annotating graphs to allow quick loading and analysis of very large graphs | |
CN110007920B (zh) | 一种获取代码依赖关系的方法、装置及电子设备 | |
US9135572B2 (en) | Method and arrangement for processing data | |
CN111913713B (zh) | 一种基于服务调用追踪的异构服务集成方法 | |
CN106682514B (zh) | 基于子图挖掘的系统调用序列特征模式集生成方法 | |
CN112084438A (zh) | 扫码跳转数据处理方法、装置、设备及系统 | |
Yonai et al. | Mercem: Method name recommendation based on call graph embedding | |
CN112860265A (zh) | 一种源代码数据库操作异常检测方法及装置 | |
US8707260B2 (en) | Resolving interdependencies between heterogeneous artifacts in a software system | |
CN112069052A (zh) | 一种异常对象检测方法、装置、设备及存储介质 | |
CN117421252B (zh) | 代码检测方法、装置及计算机可读存储介质 | |
US8832641B2 (en) | Model-operative pattern representation and operational enablement using declarative componential-driven domain-specific programming language | |
CN116166547A (zh) | 代码变更范围分析方法、装置、设备、存储介质 | |
CN114791865A (zh) | 一种基于关系图的配置项自洽性检测方法、系统和介质 | |
US8010572B1 (en) | Kstore scenario simulator processor and XML file | |
CN109299004B (zh) | 关键元素差异性分析方法及系统 | |
CN111813843B (zh) | 一种数据处理方法、装置及平台 | |
EP1019811B1 (en) | Method and apparatus for processing a request to a boolean rule | |
CN113626823A (zh) | 一种基于可达性分析的组件间交互威胁检测方法及装置 | |
CN113536052B (zh) | 一种基于k边连通分量在大型网络中搜索个性化影响力社区的方法 | |
US11010387B2 (en) | Join operation and interface for wildcards |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
PB01 | Publication | ||
PB01 | Publication | ||
SE01 | Entry into force of request for substantive examination | ||
SE01 | Entry into force of request for substantive examination | ||
GR01 | Patent grant | ||
GR01 | Patent grant |