CN112860264B - 一种抽象语法树重构方法及装置 - Google Patents

一种抽象语法树重构方法及装置 Download PDF

Info

Publication number
CN112860264B
CN112860264B CN202110343587.6A CN202110343587A CN112860264B CN 112860264 B CN112860264 B CN 112860264B CN 202110343587 A CN202110343587 A CN 202110343587A CN 112860264 B CN112860264 B CN 112860264B
Authority
CN
China
Prior art keywords
node
syntax tree
abstract syntax
nodes
class
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
Application number
CN202110343587.6A
Other languages
English (en)
Other versions
CN112860264A (zh
Inventor
徐克宝
杨丹
何旭敏
杨鹏宇
Current Assignee (The listed assignees may be inaccurate. Google has not performed a legal analysis and makes no representation or warranty as to the accuracy of the list.)
Industrial and Commercial Bank of China Ltd ICBC
Original Assignee
Industrial and Commercial Bank of China Ltd ICBC
Priority date (The priority date 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 date listed.)
Filing date
Publication date
Application filed by Industrial and Commercial Bank of China Ltd ICBC filed Critical Industrial and Commercial Bank of China Ltd ICBC
Priority to CN202110343587.6A priority Critical patent/CN112860264B/zh
Publication of CN112860264A publication Critical patent/CN112860264A/zh
Application granted granted Critical
Publication of CN112860264B publication Critical patent/CN112860264B/zh
Active legal-status Critical Current
Anticipated expiration legal-status Critical

Links

Classifications

    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F8/00Arrangements for software engineering
    • G06F8/40Transformation of program code
    • G06F8/41Compilation
    • G06F8/43Checking; Contextual analysis
    • G06F8/433Dependency analysis; Data or control flow analysis
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F8/00Arrangements for software engineering
    • G06F8/40Transformation of program code
    • G06F8/41Compilation
    • G06F8/44Encoding
    • G06F8/443Optimisation
    • G06F8/4434Reducing the memory space required by the program code
    • G06F8/4435Detection or removal of dead or redundant code

Abstract

本申请实施例提供一种抽象语法树重构方法及装置,可用于信息安全技术领域,其方法包括:根据一预设的抽象语法树,将该抽象语法树上的所有节点划分为第一节点和第二节点;所述第一节点为导入类节点,所述第二节点为非导入类节点;根据第二节点与第一节点的引用关系,确定冗余的第一节点;在所述抽象语法树中,将所有非冗余的第一节点置于所述第二节点之后,生成更新的抽象语法树。本申请明显地提高了开发人员在重构存量代码工作效率,大幅度降低了开发人员的工作量,使得开发人员在重构存量代码时无需考虑删除多余代码导入删除逻辑和检验逻辑,为降低应用技术债务提供了技术支撑。

Description

一种抽象语法树重构方法及装置
技术领域
本申请涉及计算机技术领域,具体涉及抽象语法树重构方法及装置。
背景技术
随着互联网技术和金融科技的发展,项目迭代速度越来越快,但由于开发人员水平层次不齐、历史遗留等问题导致的开发过程中引入了实际不需要使用的类,进而导致了大量的开源jar包依赖,项目工程臃肿等问题,在应用上云等应用场景下,应用体量显得尤其笨重。从单个类来讲,人工通过开发工具参与识别单个类是否存在导入的情况,需要识别出当前类中存在多少类是多余导入的,需要人工甄别,删除和修改后才能清理非必要的代码,人工遍历整个项目和多个项目,实现存量代码的重构。一旦存在规模上百万行的存量的存量项目或出现多个子项目都需要做重构的情况下,对于开发人员无异是一种巨大的技术债务,亟待一种能够自动清理代码导入类的自动化方法。
发明内容
针对现有技术中的问题,本申请提供一种抽象语法树重构方法及装置,方法包括:根据一预设的抽象语法树,将该抽象语法树上的所有节点划分为第一节点和第二节点;所述第一节点为导入类节点,所述第二节点为非导入类节点;根据第二节点与第一节点的引用关系,确定冗余的第一节点;在所述抽象语法树中,将所有非冗余的第一节点置于所述第二节点之后,生成更新的抽象语法树。本申请明显地提高了开发人员在重构存量代码工作效率,大幅度降低了开发人员的工作量,使得开发人员在重构存量代码时无需考虑删除多余代码导入删除逻辑和检验逻辑,为降低应用技术债务提供了技术支撑。
本发明的一方面,提供一种抽象语法树重构方法,包括:
根据一预设的抽象语法树,将该抽象语法树上的所有节点划分为第一节点和第二节点;所述第一节点为导入类节点,所述第二节点为非导入类节点;
根据第二节点与第一节点的引用关系,确定冗余的第一节点;
在所述抽象语法树中,将所有非冗余的第一节点置于所述第二节点之后,生成更新的抽象语法树。
在优选的实施例中,还包括:生成所述抽象语法树。
在优选的实施例中,根据一预设的抽象语法树,将该抽象语法树上的所有节点划分为第一节点和第二节点,包括:
遍历所述抽象语法树,将该抽象语法树上的每个节点各自标记为第一节点和第二节点中的一个。
在优选的实施例中,还包括:
将所有第一节点归入导入类集合,将所有第二节点归入非导入集合;
剔除所述导入类集合中冗余的第一节点;
所述将所有非冗余的第一节点置于所述第二节点之后,包括:
将剔除冗余之后的所述导入类集合置于所述非导入类集合的尾部。
在优选的实施例中,所述根据第二节点与第一节点的引用关系,确定冗余的第一节点,包括:
若一个第一节点未被所述第二节点引用,则将该第一节点确定为冗余的第一节点。
在优选的实施例中,还包括:根据所述更新的抽象语法树,生成清理后的源代码,具体步骤包括:
遍历更新的所述抽象语法树,得到所有节点;
根据所有节点生成源代码。
在优选的实施例中,所述抽象语法树包括类根节点、包名节点、外部类类节点以及类主体节点;所述根据所有节点生成源代码,包括:按照类别将类根节点、包名节点、外部类类节点以及类主体节点输出至字符流,生成所述源代码。
在优选的实施例中,还包括:将清理后的源代码覆盖至指定目录下。
本发明的又一方面,提供一种抽象语法树重构装置,包括:
节点划分模块,根据一预设的抽象语法树,将该抽象语法树上的所有节点划分为第一节点和第二节点;所述第一节点为导入类节点,所述第二节点为非导入类节点;
冗余节点确定模块,根据第二节点与第一节点的引用关系,确定冗余的第一节点;
抽象语法树更新模块,在所述抽象语法树中,将所有非冗余的第一节点置于所述第二节点之后,生成更新的抽象语法树。
在优选的实施例中,还包括:抽象语法树生成模块,生成所述抽象语法树。
在优选的实施例中,根据一预设的抽象语法树,将该抽象语法树上的所有节点划分为第一节点和第二节点,包括:
遍历所述抽象语法树,将该抽象语法树上的每个节点各自标记为第一节点和第二节点中的一个。
在优选的实施例中,还包括:
集合生成模块,将所有第一节点归入导入类集合,将所有第二节点归入非导入集合;
冗余类剔除模块,剔除所述导入类集合中冗余的第一节点;
抽象语法树重构模块,所述将所有非冗余的第一节点置于所述第二节点之后,包括:
将剔除冗余之后的所述导入类集合置于所述非导入类集合的尾部。
在优选的实施例中,所述根据第二节点与第一节点的引用关系,确定冗余的第一节点,包括:
若一个第一节点未被所述第二节点引用,则将该第一节点确定为冗余的第一节点。
在优选的实施例中,还包括:源代码更新模块,根据所述更新的抽象语法树,生成清理后的源代码,具体包括:
节点获取单元,遍历更新的所述抽象语法树,得到所有节点;
源代码生成单元,根据所有节点生成源代码。
在优选的实施例中,所述抽象语法树包括类根节点、包名节点、外部类类节点以及类主体节点;所述根据所有节点生成源代码,包括:按照类别将类根节点、包名节点、外部类类节点以及类主体节点输出至字符流,生成所述源代码。
在优选的实施例中,还包括:将清理后的源代码覆盖至指定目录下。
本发明的又一方面,本申请提供一种电子设备,包括存储器、处理器及存储在存储器上并可在处理器上运行的计算机程序,所述处理器执行所述程序时实现所述的抽象语法树重构方法。
本发明的又一方面,本申请提供一种计算机可读存储介质,其上存储有计算机程序,该计算机程序被处理器执行时实现所述的抽象语法树重构方法。
由上述技术方案可知,本申请提供的一种抽象语法树重构方法,方法包括:根据一预设的抽象语法树,将该抽象语法树上的所有节点划分为第一节点和第二节点;所述第一节点为导入类节点,所述第二节点为非导入类节点;根据第二节点与第一节点的引用关系,确定冗余的第一节点;在所述抽象语法树中,将所有非冗余的第一节点置于所述第二节点之后,生成更新的抽象语法树。本申请明显地提高了开发人员在重构存量代码工作效率,大幅度降低了开发人员的工作量,使得开发人员在重构存量代码时无需考虑删除多余代码导入删除逻辑和检验逻辑,为降低应用技术债务提供了技术支撑。
附图说明
为了更清楚地说明本申请实施例或现有技术中的技术方案,下面将对实施例或现有技术描述中所需要使用的附图作简单地介绍,显而易见地,下面描述中的附图是本申请的一些实施例,对于本领域普通技术人员来讲,在不付出创造性劳动的前提下,还可以根据这些附图获得其他的附图。
图1是抽象语法树重构方法流程示意图。
图2是使用节点集合重构抽象语法树流程示意图。
图3是由抽象语法树重构源代码流程示意图。
图4是抽象语法树重构装置结构示意图。
图5是本申请实施例中的电子设备的结构示意图。
具体实施方式
为使本申请实施例的目的、技术方案和优点更加清楚,下面将结合本申请实施例中的附图,对本申请实施例中的技术方案进行清楚、完整的描述,显然,所描述的实施例是本申请一部分实施例,而不是全部的实施例。基于本申请中的实施例,本领域普通技术人员在没有作出创造性劳动前提下所获得的所有其他实施例,都属于本申请保护的范围。
需要说明的是,本申请公开的抽象语法树重构方法及装置可用于信息安全技术领域,也可用于除信息安全技术领域之外的任意领域,本申请公开的抽象语法树重构方法及装置的应用领域不做限定。
随着互联网技术和金融科技的发展,项目迭代速度越来越快,但由于开发人员水平层次不齐、历史遗留等问题导致的开发过程中引入了实际不需要使用的类,进而导致了大量的开源jar包依赖,项目工程臃肿等问题,在应用上云等应用场景下,应用体量显得尤其笨重。
从单个类来讲,人工通过开发工具参与识别单个类是否存在导入的情况,需要识别出当前类中存在多少类是多余导入的,需要人工甄别,删除和修改后才能清理非必要的代码,人工遍历整个项目和多个项目,实现存量代码的重构。
一旦存在规模上百万行的存量的存量项目或出现多个子项目都需要做重构的情况下,对于开发人员无异是一种巨大的技术债务,亟待一种能够自动清理代码导入类的自动化方法。
针对现有问题中的至少一个,本申请提供一种抽象语法树重构方法及装置,方法包括:根据一预设的抽象语法树,将该抽象语法树上的所有节点划分为第一节点和第二节点;所述第一节点为导入类节点,所述第二节点为非导入类节点;根据第二节点与第一节点的引用关系,确定冗余的第一节点;在所述抽象语法树中,将所有非冗余的第一节点置于所述第二节点之后,生成更新的抽象语法树。本申请明显地提高了开发人员在重构存量代码工作效率,大幅度降低了开发人员的工作量,使得开发人员在重构存量代码时无需考虑删除多余代码导入删除逻辑和检验逻辑,为降低应用技术债务提供了技术支撑。
下面结合附图对本发明提供的抽象语法树重构方法及装置进行详细说明。
本申请提供一种抽象语法树重构方法,如图1,包括:
S1:根据一预设的抽象语法树,将该抽象语法树上的所有节点划分为第一节点和第二节点;所述第一节点为导入类节点,所述第二节点为非导入类节点;
具体的,在计算机科学中,抽象语法树是源代码语法结构的一种抽象表示。它以树状的形式表现编程语言的语法结构,树上的每个节点都表示源代码中的一种结构。之所以说是抽象的,是因为抽象语法树并不会表示出真实语法出现的每一个细节,比如说,嵌套括号被隐含在树的结构中,并没有以节点的形式呈现。抽象语法树并不依赖于源语言的语法,也就是说语法分析阶段所采用的上下文无文文法,因为在写文法时,经常会对文法进行等价的转换(消除左递归,回溯,二义性等),这样会给文法分析引入一些多余的成分,对后续阶段造成不利影响,甚至会使合个阶段变得混乱。因些,很多编译器经常要独立地构造语法分析树,为前端,后端建立一个清晰的接口。可以理解,一个抽象语法树是通过分析一个软件项目的源代码而生成的。一般地,采用文件流的形式扫描源代码,将所有的源代码形成代码文件流,再将代码文件流读取为文本,以文件为基本编译单元进行词法解析。在具体的实施例过程,所述以文件为基本编译单元进行词法解析的步骤包括首先将计算机内存中代码文件以字符形式按行读取到基本编译单元对象中,然后截止读取文件最后一行,该文件源代码读取完毕,基本编译单元对象准备完成,通过对基本编译单元对象数据解析,基于编程语言语法规定,对基本编译单元中的符号、语法关键字完成规则校验。最终将基本编译单元数据解析成类根节点、包名节点、外部类类节点集合、类主体节点集合,至此词法分析结束。未完成规则校验的则标记为词法解析不成功。在完成词法解析后,筛选词法解析成功的文件流集合中的基本编译单元,输出并导入至一个空的语法树,从而生成源代码的抽象语法树。从抽象语法树的生成过程中,可以理解,抽象语法树按照源代码的结构包括了类根节点、包名节点、外部类类节点和类主体节点。
在具体的实施例中,遍历生成的抽象语法树中的所有节点,若节点对应的是一个导入外部预设类函数结构,则将该节点标记为第一节点,若节点不是对应的一个导入类函数结构,则将该节点标记为第二节点。例如一个用于矩阵运算的预设类函数是预先定义好的,源代码中直接导入了该矩阵运算类,则导入该矩阵运算类的节点就是一个第一节点;再例如一个求和函数,其没有外部预设类的导入,则将该求和函数对应的节点标记为第二节点。通过上述方法可以将抽象语法树中所有的节点划分为第一节点和第二节点两大类。
S2:根据第二节点与第一节点的引用关系,确定冗余的第一节点;
具体的,本申请的目标是将代码中没有起到作用的冗余外部类清除,可以理解,若一个外部导入类被非导入类引用了,则其对于源代码而言就是有效的导入类,而如果一个导入类没有被所有的非导入类引用,说明它是一个冗余的外部导入类,可以将其删除,对源代码的逻辑没有影响,同时可以减少源代码的数据量。确定一个第一节点是否为冗余节点的步骤包括:若一个第一节点未被所述第二节点引用,则将该第一节点确定为冗余的第一节点。例如对于一个第一节点a,通过遍历第二节点,查找该第一节点a是否被引用,假设该第一节点a被一个第二节点b引用了,则该第一节点a为有效节点,需要被保留;如果通过遍历第二节点,发现该第一节点未被第二节点中的任意一个引用,则说明该第一节点a对于源代码的逻辑而言是冗余的,是一个冗余的第一节点。
S3:在所述抽象语法树中,将所有非冗余的第一节点置于所述第二节点之后,生成更新的抽象语法树。
具体的,确定了冗余的导入类后,整个抽象语法树中的所有节点被标记为三类:冗余第一节点,非冗余第一节点和第二节点。遍历整个抽象语法树的所有节点,若节点为第二节点,则将其置于一集合的前部,若节点为非冗余的第一节点,则将其置于该集合的后部,从而得到一个集合,该集合包括了抽象语法树中的所有非冗余的第一节点和第二节点。可以理解,该集合就是抽象语法树中删除了冗余的第一节点的结果。例如一个抽象语法树共包括10个节点{a.b,c,d,e,f,g,h,I,j}其中第二节点为a,c,d,h,j,非冗余的导入类为b,I,冗余的第一节点为e,f,g。在该具体的实施例中,遍历抽象语法树的10个节点,从a节点开始遍历,由于a为第二节点,所以将其放在新建的空集合的头部,得到{a}。遍历至b节点,由于b未非冗余的第一节点,故将其放在集合尾部,得到{a,b}。遍历至c节点,由于c为一个第二节点,故将其放在集合头部,得到{c,a,b}。遍历至d节点,由于其是在个非导入类的节点,故将其放在集合头部,得到{d,c,a,b}。遍历至e节点,由于其为一个冗余的第一节点,所以跳过,遍历至f节点,以此类推。最终得到集合{j,h,d,c,a,b,I},即为去除了冗余的第一节点的抽象语法树节点集合。从上述过程中可以发现,对抽象语法树的所有节点进行了两次遍历,为了减少遍历带来的循环消耗,在另一个具体的实施例中,在第一次遍历语法树,将抽象语法树的所有节点划分为第一节点和第二节点之后,如图2,执行如下步骤:
S31:将所有第一节点归入导入类集合,将所有第二节点归入非导入集合;
具体的,假设一个抽象语法树共有8个节点{a.b,c,d,e,f,g,h},通过第一次遍历,将所有的节点分为第一节点a,c,d和第二节点b,e,f,g,h。将所有的第一节点归入导入类集合得到{a,c,d},将所有的第二节点归入非导入类集合得到{b,e,f,g,h}。
S32:剔除所述导入类集合中冗余的第一节点;
具体的,如上述具体的实施例,根据导入类与非导入类的引用关系,确定了导入类中冗余的第一节点是d,则将d进行剔除,得到集合{a,c},即为剔除冗余之后的导入类集合。
S33:所述将所有非冗余的第一节点置于所述第二节点之后,包括:
将剔除冗余之后的所述导入类集合置于所述非导入类集合的尾部。
具体的,如上述具体的实施例,将剔除冗余之后的所述导入类集合置于所述非导入类集合的尾部,即将{a,c}置于{b,e,f,g,h}的尾部,得到{b,e,f,g,h,a,c},至此也得到了去除了冗余的第一节点的抽象语法树节点集合。该具体的实施例中,对抽象语法树只进行了一次遍历,减少了消耗。
在具体的实施例中,根据所述更新的抽象语法树,对应生成清理后的源代码。
具体的,重构以后的抽象语法树需要对应生成清理了冗余导入类的源代码,如图3,根据抽象语法树生成清理后的源代码的步骤包括:
S41:遍历更新的所述抽象语法树,得到所有节点;
具体的,更新后的抽象语法树中的所有节点包括了类根节点、包名节点、外部类类节点以及类主体节点。
S42:根据所有节点生成源代码。
具体的,获取到更新后的抽象语法树的所有节点后,将所有的节点按照节点的类型输出至字符流中,使用源代码的相应编译器对输出的字符流按照单元进行编译,最终生成源代码文本。例如对于JavaScript的源代码可以使用bable这个库进行抽象语法树的节点字符流向JavaScript源代码的生成。
生成源代码文本后,读取代码导出配置规则配置指定目录,即选择是否覆盖、重新导出到新目录。通过读取生成的清理后源代码文本到文件流中并写到硬盘指定目录中。
结合一个具体的实施场景,对本申请做进一步说明。
现有一个JavaScript项目的源代码需要清理其中冗余的导入类。在JavaScript的语法解析领域,一个流行的开源项目是Esprima,利用这个工具来完成任务。此外,需要借助Node来构建能够在命令行运行的JS代码。首先创建项目的基本目录结构,以及初始化NPM。借助Esprima解析代码非常简单,只要使用一个方法即可:var ast=esprima.parse(code);esprima.parse()方法接收两种类型的参数:字符串或Node的Buffer对象,它也可以收附加的选项作为参数。解析后返回结果即为抽象语法树(AST),抽象语法树遵守Mozilla SpiderMonkey的解析器的API。通过观察生成的语法树可以发现每个节点都有一个type,根节点的type为Program。type也是所有节点都共有的,其他的属性依赖于节点的type。
得到代码的抽象语法树后,对得到的抽象语法树进行遍历,我们可以借助Estraverse进行节点的遍历,标记出第一节点和第二节点。创建了两个l对象分别用来存放第一节点和第二节点,其中存放第一节点的对象名为Inversion,存放第二节点的对象为NoInversion。
将所有节点划分为第一节点和第二节点后,遍历第二节点中type为声明类的节点,如果该节点涉及其他类的调用,则判断该调用的类是否存在于第一节点对象集合中,若存在则将比第一节点标记为有效节点,即在节点中添加一个属性值effect,其值为true是有效节点,其值为false是冗余节点。在完成第二节点的遍历后,新建一个对象InversionEffect用于存放第一节点中属性值effect为true的所有节点。然后进行抽象语法树的重构,将对象InversionEffect与对象NoInversion进行合并,组成一个新的对象newAST,其中新的对象newAST中尾部是对象InversionEffect的节点,头部是对象NoInversion的节点。最后将对象newAST中所有的节点按照类型输出为字符流,利用babel中的transform方法,对字符流进行编译后,生成源代码文本。
将生成的清理后源代码覆盖至原源代码的目录中,使得项目可以重新运行。
由以上描述可知,本发明提供的一种抽象语法树重构方法,方法包括:根据一预设的抽象语法树,将该抽象语法树上的所有节点划分为第一节点和第二节点;所述第一节点为导入类节点,所述第二节点为非导入类节点;根据第二节点与第一节点的引用关系,确定冗余的第一节点;在所述抽象语法树中,将所有非冗余的第一节点置于所述第二节点之后,生成更新的抽象语法树。本申请明显地提高了开发人员在重构存量代码工作效率,大幅度降低了开发人员的工作量,使得开发人员在重构存量代码时无需考虑删除多余代码导入删除逻辑和检验逻辑,为降低应用技术债务提供了技术支撑。
从软件层面来说,本申请提供一种用于执行所述抽象语法树重构方法中全部或部分内容的抽象语法树重构装置的实施例,参见图4,所述抽象语法树重构装置具体包含有如下内容:
节点划分模块1,根据一预设的抽象语法树,将该抽象语法树上的所有节点划分为第一节点和第二节点;所述第一节点为导入类节点,所述第二节点为非导入类节点;
冗余节点确定模块2,根据第二节点与第一节点的引用关系,确定冗余的第一节点;
抽象语法树更新模块3,在所述抽象语法树中,将所有非冗余的第一节点置于所述第二节点之后,生成更新的抽象语法树;
由以上描述可知,本发明提供的抽象语法树重构装置,本装置根据一预设的抽象语法树,将该抽象语法树上的所有节点划分为第一节点和第二节点;所述第一节点为导入类节点,所述第二节点为非导入类节点;根据第二节点与第一节点的引用关系,确定冗余的第一节点;在所述抽象语法树中,将所有非冗余的第一节点置于所述第二节点之后,生成更新的抽象语法树。本申请明显地提高了开发人员在重构存量代码工作效率,大幅度降低了开发人员的工作量,使得开发人员在重构存量代码时无需考虑删除多余代码导入删除逻辑和检验逻辑,为降低应用技术债务提供了技术支撑。
在本发明的实施例中,提供一种抽象语法树重构装置,用于执行如下包括:
S1:根据一预设的抽象语法树,将该抽象语法树上的所有节点划分为第一节点和第二节点;所述第一节点为导入类节点,所述第二节点为非导入类节点;
具体的,在计算机科学中,抽象语法树是源代码语法结构的一种抽象表示。它以树状的形式表现编程语言的语法结构,树上的每个节点都表示源代码中的一种结构。之所以说是抽象的,是因为抽象语法树并不会表示出真实语法出现的每一个细节,比如说,嵌套括号被隐含在树的结构中,并没有以节点的形式呈现。抽象语法树并不依赖于源语言的语法,也就是说语法分析阶段所采用的上下文无文文法,因为在写文法时,经常会对文法进行等价的转换(消除左递归,回溯,二义性等),这样会给文法分析引入一些多余的成分,对后续阶段造成不利影响,甚至会使合个阶段变得混乱。因些,很多编译器经常要独立地构造语法分析树,为前端,后端建立一个清晰的接口。可以理解,一个抽象语法树是通过分析一个软件项目的源代码而生成的。一般地,采用文件流的形式扫描源代码,将所有的源代码形成代码文件流,再将代码文件流读取为文本,以文件为基本编译单元进行词法解析。在具体的实施例过程,所述以文件为基本编译单元进行词法解析的步骤包括首先将计算机内存中代码文件以字符形式按行读取到基本编译单元对象中,然后截止读取文件最后一行,该文件源代码读取完毕,基本编译单元对象准备完成,通过对基本编译单元对象数据解析,基于编程语言语法规定,对基本编译单元中的符号、语法关键字完成规则校验。最终将基本编译单元数据解析成类根节点、包名节点、外部类类节点集合、类主体节点集合,至此词法分析结束。未完成规则校验的则标记为词法解析不成功。在完成词法解析后,筛选词法解析成功的文件流集合中的基本编译单元,输出并导入至一个空的语法树,从而生成源代码的抽象语法树。从抽象语法树的生成过程中,可以理解,抽象语法树按照源代码的结构包括了类根节点、包名节点、外部类类节点和类主体节点。
在具体的实施例中,遍历生成的抽象语法树中的所有节点,若节点对应的是一个导入外部预设类函数结构,则将该节点标记为第一节点,若节点不是对应的一个导入类函数结构,则将该节点标记为第二节点。例如一个用于矩阵运算的预设类函数是预先定义好的,源代码中直接导入了该矩阵运算类,则导入该矩阵运算类的节点就是一个第一节点;再例如一个求和函数,其没有外部预设类的导入,则将该求和函数对应的节点标记为第二节点。通过上述方法可以将抽象语法树中所有的节点划分为第一节点和第二节点两大类。
S2:根据第二节点与第一节点的引用关系,确定冗余的第一节点;
具体的,本申请的目标是将代码中没有起到作用的冗余外部类清除,可以理解,若一个外部导入类被非导入类引用了,则其对于源代码而言就是有效的导入类,而如果一个导入类没有被所有的非导入类引用,说明它是一个冗余的外部导入类,可以将其删除,对源代码的逻辑没有影响,同时可以减少源代码的数据量。确定一个第一节点是否为冗余节点的步骤包括:若一个第一节点未被所述第二节点引用,则将该第一节点确定为冗余的第一节点。例如对于一个第一节点a,通过遍历第二节点,查找该第一节点a是否被引用,假设该第一节点a被一个第二节点b引用了,则该第一节点a为有效节点,需要被保留;如果通过遍历第二节点,发现该第一节点未被第二节点中的任意一个引用,则说明该第一节点a对于源代码的逻辑而言是冗余的,是一个冗余的第一节点。
S3:在所述抽象语法树中,将所有非冗余的第一节点置于所述第二节点之后,生成更新的抽象语法树;
具体的,确定了冗余的导入类后,整个抽象语法树中的所有节点被标记为三类:冗余第一节点,非冗余第一节点和第二节点。遍历整个抽象语法树的所有节点,若节点为非冗余的第一节点,则将其置于一集合的前部,若节点为非导入类,则将其置于该集合的后部,从而得到一个集合,该集合包括了抽象语法树中的所有非冗余的第一节点和第二节点。可以理解,该集合就是抽象语法树中删除了冗余的第一节点的结果。例如一个抽象语法树共包括10个节点{a.b,c,d,e,f,g,h,I,j}其中第二节点为a,c,d,h,j,非冗余的导入类为b,I,冗余的第一节点为e,f,g。在该具体的实施例中,遍历抽象语法树的10个节点,从a节点开始遍历,由于a为第二节点,所以将其放在新建的空集合的头部,得到{a}。遍历至b节点,由于b未非冗余的第一节点,故将其放在集合尾部,得到{a,b}。遍历至c节点,由于c为一个第二节点,故将其放在集合头部,得到{c,a,b}。遍历至d节点,由于其是在个非导入类的节点,故将其放在集合头部,得到{d,c,a,b}。遍历至e节点,由于其为一个冗余的第一节点,所以跳过,遍历至f节点,以此类推。最终得到集合{j,h,d,c,a,b,I},即为去除了冗余的第一节点的抽象语法树节点集合。从上述过程中可以发现,对抽象语法树的所有节点进行了两次遍历,为了减少遍历带来的循环消耗,在另一个具体的实施例中,在第一次遍历语法树,将抽象语法树的所有节点划分为第一节点和第二节点之后,执行如下步骤:
S31:将所有第一节点归入导入类集合,将所有第二节点归入非导入集合;
具体的,假设一个抽象语法树共有8个节点{a.b,c,d,e,f,g,h},通过第一次遍历,将所有的节点分为第一节点a,c,d和第二节点b,e,f,g,h。将所有的第一节点归入导入类集合得到{a,c,d},将所有的第二节点归入非导入类集合得到{b,e,f,g,h}。
S32:剔除所述导入类集合中冗余的第一节点;
具体的,如上述具体的实施例,根据导入类与非导入类的引用关系,确定了导入类中冗余的第一节点是d,则将d进行剔除,得到集合{a,c},即为剔除冗余之后的导入类集合。
S33:所述将所有非冗余的第一节点置于所述第二节点之后,包括:
将剔除冗余之后的所述导入类集合置于所述非导入类集合的尾部。
具体的,如上述具体的实施例,将剔除冗余之后的所述导入类集合置于所述非导入类集合的尾部,即将{a,c}置于{b,e,f,g,h}的尾部,得到{b,e,f,g,h,a,c},至此也得到了去除了冗余的第一节点的抽象语法树节点集合。该具体的实施例中,对抽象语法树只进行了一次遍历,减少了消耗。
在具体的实施例中,装置还包括了源代码更新模块,即根据所述更新的抽象语法树,对应生成清理后的源代码。
具体的,重构以后的抽象语法树需要对应生成清理了冗余导入类的源代码,根据抽象语法树生成清理后的源代码,执行如下步骤包括:
S41:遍历更新的所述抽象语法树,得到所有节点;
具体的,更新后的抽象语法树中的所有节点包括了类根节点、包名节点、外部类类节点以及类主体节点。
S42:根据所有节点生成源代码。
具体的,获取到更新后的抽象语法树的所有节点后,将所有的节点按照节点的类型输出至字符流中,使用源代码的相应编译器对输出的字符流按照单元进行编译,最终生成源代码文本。例如对于JavaScript的源代码可以使用bable这个库进行抽象语法树的节点字符流向JavaScript源代码的生成。
生成源代码文本后,读取代码导出配置规则配置指定目录,即选择是否覆盖、重新导出到新目录。通过读取生成的清理后源代码文本到文件流中并写到硬盘指定目录中。
结合一个具体的实施场景,对本申请做进一步说明。
现有一个JavaScript项目的源代码需要清理其中冗余的导入类。在JavaScript的语法解析领域,一个流行的开源项目是Esprima,利用这个工具来完成任务。此外,需要借助Node来构建能够在命令行运行的JS代码。首先创建项目的基本目录结构,以及初始化NPM。借助Esprima解析代码非常简单,只要使用一个方法即可:var ast=esprima.parse(code);esprima.parse()方法接收两种类型的参数:字符串或Node的Buffer对象,它也可以收附加的选项作为参数。解析后返回结果即为抽象语法树(AST),抽象语法树遵守Mozilla SpiderMonkey的解析器的API。通过观察生成的语法树可以发现每个节点都有一个type,根节点的type为Program。type也是所有节点都共有的,其他的属性依赖于节点的type。
得到代码的抽象语法树后,对得到的抽象语法树进行遍历,我们可以借助Estraverse进行节点的遍历,标记出第一节点和第二节点。创建了两个l对象分别用来存放第一节点和第二节点,其中存放第一节点的对象名为Inversion,存放第二节点的对象为NoInversion。
将所有节点划分为第一节点和第二节点后,遍历第二节点中type为声明类的节点,如果该节点涉及其他类的调用,则判断该调用的类是否存在于第一节点对象集合中,若存在则将比第一节点标记为有效节点,即在节点中添加一个属性值effect,其值为true是有效节点,其值为false是冗余节点。在完成第二节点的遍历后,新建一个对象InversionEffect用于存放第一节点中属性值effect为true的所有节点。然后进行抽象语法树的重构,将对象InversionEffect与对象NoInversion进行合并,组成一个新的对象newAST,其中新的对象newAST中尾部是对象InversionEffect的节点,头部是对象NoInversion的节点。最后将对象newAST中所有的节点按照类型输出为字符流,利用babel中的transform方法,对字符流进行编译后,生成源代码文本。
将生成的清理后源代码覆盖至原源代码的目录中,使得项目可以重新运行。
由以上描述可知,本发明提供的一种抽象语法树重构装置,本装置根据一预设的抽象语法树,将该抽象语法树上的所有节点划分为第一节点和第二节点;所述第一节点为导入类节点,所述第二节点为非导入类节点;根据第二节点与第一节点的引用关系,确定冗余的第一节点;在所述抽象语法树中,将所有非冗余的第一节点置于所述第二节点之后,生成更新的抽象语法树。本申请明显地提高了开发人员在重构存量代码工作效率,大幅度降低了开发人员的工作量,使得开发人员在重构存量代码时无需考虑删除多余代码导入删除逻辑和检验逻辑,为降低应用技术债务提供了技术支撑。
从硬件层面来说,本申请提供一种用于实现抽象语法树重构方法中的全部或部分内容的电子设备的实施例,所述电子设备具体包含有如下内容:
图5为本申请实施例的电子设备9600的系统构成的示意框图。如图5所示,该电子设备9600可以包括中央处理器9100和存储器9140;存储器9140耦合到中央处理器9100。值得注意的是,该图5是示例性的;还可以使用其他类型的结构,来补充或代替该结构,以实现电信功能或其他功能。
在一实施例中,抽象语法树重构功能可以被集成到中央处理器中。其中,中央处理器可以被配置为进行如下控制:
S1:根据一预设的抽象语法树,将该抽象语法树上的所有节点划分为第一节点和第二节点;所述第一节点为导入类节点,所述第二节点为非导入类节点;
S2:根据第二节点与第一节点的引用关系,确定冗余的第一节点;
S3:在所述抽象语法树中,将所有非冗余的第一节点置于所述第二节点之后,生成更新的抽象语法树。
从上述描述可知,本申请实施例提供的电子设备,明显地提高了开发人员在重构存量代码工作效率,大幅度降低了开发人员的工作量,使得开发人员在重构存量代码时无需考虑删除多余代码导入删除逻辑和检验逻辑,为降低应用技术债务提供了技术支撑。
在另一个实施方式中,抽象语法树重构装置可以与中央处理器9100分开配置,例如可以抽象语法树重构装置配置为与中央处理器9100连接的芯片,通过中央处理器的控制来实现抽象语法树重构功能。
如图5所示,该电子设备9600还可以包括:通信模块9110、输入单元9120、音频处理器9130、显示器9160、电源9170。值得注意的是,电子设备9600也并不是必须要包括图5中所示的所有部件;此外,电子设备9600还可以包括图5中没有示出的部件,可以参考现有技术。
如图5所示,中央处理器9100有时也称为控制器或操作控件,可以包括微处理器或其他处理器装置和/或逻辑装置,该中央处理器9100接收输入并控制电子设备9600的各个部件的操作。
其中,存储器9140,例如可以是缓存器、闪存、硬驱、可移动介质、易失性存储器、非易失性存储器或其它合适装置中的一种或更多种。可储存上述与失败有关的信息,此外还可存储执行有关信息的程序。并且中央处理器9100可执行该存储器9140存储的该程序,以实现信息存储或处理等。
输入单元9120向中央处理器9100提供输入。该输入单元9120例如为按键或触摸输入装置。电源9170用于向电子设备9600提供电力。显示器9160用于进行图像和文字等显示对象的显示。该显示器例如可为LCD显示器,但并不限于此。
该存储器9140可以是固态存储器,例如,只读存储器(ROM)、随机存取存储器(RAM)、SIM卡等。还可以是这样的存储器,其即使在断电时也保存信息,可被选择性地擦除且设有更多数据,该存储器的示例有时被称为EPROM等。存储器9140还可以是某种其它类型的装置。存储器9140包括缓冲存储器9141(有时被称为缓冲器)。存储器9140可以包括应用/功能存储部9142,该应用/功能存储部9142用于存储应用程序和功能程序或用于通过中央处理器9100执行电子设备9600的操作的流程。
存储器9140还可以包括数据存储部9143,该数据存储部9143用于存储数据,例如联系人、数字数据、图片、声音和/或任何其他由电子设备使用的数据。存储器9140的驱动程序存储部9144可以包括电子设备的用于通信功能和/或用于执行电子设备的其他功能(如消息传送应用、通讯录应用等)的各种驱动程序。
通信模块9110即为经由天线9111发送和接收信号的发送机/接收机9110。通信模块(发送机/接收机)9110耦合到中央处理器9100,以提供输入信号和接收输出信号,这可以和常规移动通信终端的情况相同。
基于不同的通信技术,在同一电子设备中,可以设置有多个通信模块9110,如蜂窝网络模块、蓝牙模块和/或无线局域网模块等。通信模块(发送机/接收机)9110还经由音频处理器9130耦合到扬声器9131和麦克风9132,以经由扬声器9131提供音频输出,并接收来自麦克风9132的音频输入,从而实现通常的电信功能。音频处理器9130可以包括任何合适的缓冲器、解码器、放大器等。另外,音频处理器9130还耦合到中央处理器9100,从而使得可以通过麦克风9132能够在本机上录音,且使得可以通过扬声器9131来播放本机上存储的声音。
本申请的实施例还提供能够实现上述实施例中的抽象语法树重构方法中全部步骤的一种计算机可读存储介质,所述计算机可读存储介质上存储有计算机程序,该计算机程序被处理器执行时实现上述实施例中的执行主体为服务器或客户端的抽象语法树重构方法的全部步骤,例如,所述处理器执行所述计算机程序时实现下述步骤:
S1:根据一预设的抽象语法树,将该抽象语法树上的所有节点划分为第一节点和第二节点;所述第一节点为导入类节点,所述第二节点为非导入类节点;
S2:根据第二节点与第一节点的引用关系,确定冗余的第一节点;
S3:在所述抽象语法树中,将所有非冗余的第一节点置于所述第二节点之后,生成更新的抽象语法树;
从上述描述可知,本申请实施例提供的计算机可读存储介质,明显地提高了开发人员在重构存量代码工作效率,大幅度降低了开发人员的工作量,使得开发人员在重构存量代码时无需考虑删除多余代码导入删除逻辑和检验逻辑,为降低应用技术债务提供了技术支撑。
本领域内的技术人员应明白,本发明的实施例可提供为方法、装置、或计算机程序产品。因此,本发明可采用完全硬件实施例、完全软件实施例、或结合软件和硬件方面的实施例的形式。而且,本发明可采用在一个或多个其中包含有计算机可用程序代码的计算机可用存储介质(包括但不限于磁盘存储器、CD-ROM、光学存储器等)上实施的计算机程序产品的形式。
本发明是参照根据本发明实施例的方法、设备(装置)、和计算机程序产品的流程图和/或方框图来描述的。应理解可由计算机程序指令实现流程图和/或方框图中的每一流程和/或方框、以及流程图和/或方框图中的流程和/或方框的结合。可提供这些计算机程序指令到通用计算机、专用计算机、嵌入式处理机或其他可编程数据处理设备的处理器以产生一个机器,使得通过计算机或其他可编程数据处理设备的处理器执行的指令产生用于实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能的装置。
这些计算机程序指令也可存储在能引导计算机或其他可编程数据处理设备以特定方式工作的计算机可读存储器中,使得存储在该计算机可读存储器中的指令产生包括指令装置的制造品,该指令装置实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能。
这些计算机程序指令也可装载到计算机或其他可编程数据处理设备上,使得在计算机或其他可编程设备上执行一系列操作步骤以产生计算机实现的处理,从而在计算机或其他可编程设备上执行的指令提供用于实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能的步骤。
本发明中应用了具体实施例对本发明的原理及实施方式进行了阐述,以上实施例的说明只是用于帮助理解本发明的方法及其核心思想;同时,对于本领域的一般技术人员,依据本发明的思想,在具体实施方式及应用范围上均会有改变之处,综上所述,本说明书内容不应理解为对本发明的限制。

Claims (14)

1.一种抽象语法树重构方法,其特征在于,包括:
根据一预设的抽象语法树,将该抽象语法树上的所有节点划分为第一节点和第二节点;所述第一节点为导入类节点,所述第二节点为非导入类节点;
根据第二节点与第一节点的引用关系,确定冗余的第一节点;
在所述抽象语法树中,将所有非冗余的第一节点置于所述第二节点之后,生成更新的抽象语法树;
将所有第一节点归入导入类集合,将所有第二节点归入非导入集合;
剔除所述导入类集合中冗余的第一节点;
所述将所有非冗余的第一节点置于所述第二节点之后,包括:
将剔除冗余之后的所述导入类集合置于所述非导入类集合的尾部;
所述根据第二节点与第一节点的引用关系,确定冗余的第一节点,包括:
若一个第一节点未被所述第二节点引用,则将该第一节点确定为冗余的第一节点。
2.根据权利要求1所述的抽象语法树重构方法,其特征在于,还包括:生成所述抽象语法树。
3.根据权利要求1所述的抽象语法树重构方法,其特征在于,根据一预设的抽象语法树,将该抽象语法树上的所有节点划分为第一节点和第二节点,包括:
遍历所述抽象语法树,将该抽象语法树上的每个节点各自标记为第一节点和第二节点中的一个。
4.根据权利要求1所述的抽象语法树重构方法,其特征在于,还包括:根据所述更新的抽象语法树,生成清理后的源代码,具体步骤包括:
遍历更新的所述抽象语法树,得到所有节点;
根据所有节点生成源代码。
5.根据权利要求4所述的抽象语法树重构方法,其特征在于,所述抽象语法树包括类根节点、包名节点、外部类类节点以及类主体节点;所述根据所有节点生成源代码,包括:按照类别将类根节点、包名节点、外部类类节点以及类主体节点输出至字符流,生成所述源代码。
6.根据权利要求1所述的抽象语法树重构方法,其特征在于,还包括:将清理后的源代码覆盖至指定目录下。
7.一种抽象语法树重构装置,其特征在于,包括:
节点划分模块,根据一预设的抽象语法树,将该抽象语法树上的所有节点划分为第一节点和第二节点;所述第一节点为导入类节点,所述第二节点为非导入类节点;
冗余节点确定模块,根据第二节点与第一节点的引用关系,确定冗余的第一节点;
抽象语法树更新模块,在所述抽象语法树中,将所有非冗余的第一节点置于所述第二节点之后,生成更新的抽象语法树;
集合生成模块,将所有第一节点归入导入类集合,将所有第二节点归入非导入集合;
冗余类剔除模块,剔除所述导入类集合中冗余的第一节点;
所述抽象语法树重构模块,所述将所有非冗余的第一节点置于所述第二节点之后,具体包括:将剔除冗余之后的所述导入类集合置于所述非导入类集合的尾部;
所述冗余节点确定模块,所述根据第二节点与第一节点的引用关系,确定冗余的第一节点,具体包括:若一个第一节点未被所述第二节点引用,则将该第一节点确定为冗余的第一节点。
8.根据权利要求7所述的抽象语法树重构装置,其特征在于,还包括:抽象语法树生成模块,生成所述抽象语法树。
9.根据权利要求7所述的抽象语法树重构装置,其特征在于,根据一预设的抽象语法树,将该抽象语法树上的所有节点划分为第一节点和第二节点,包括:
遍历所述抽象语法树,将该抽象语法树上的每个节点各自标记为第一节点和第二节点中的一个。
10.根据权利要求7所述的抽象语法树重构装置,其特征在于,还包括:源代码更新模块,根据所述更新的抽象语法树,生成清理后的源代码,具体包括:
节点获取单元,遍历更新的所述抽象语法树,得到所有节点;
源代码生成单元,根据所有节点生成源代码。
11.根据权利要求10所述的抽象语法树重构装置,其特征在于,所述抽象语法树包括类根节点、包名节点、外部类类节点以及类主体节点;所述根据所有节点生成源代码,包括:按照类别将类根节点、包名节点、外部类类节点以及类主体节点输出至字符流,生成所述源代码。
12.根据权利要求7所述的抽象语法树重构装置,其特征在于,还包括:将清理后的源代码覆盖至指定目录下。
13.一种电子设备,包括存储器、处理器及存储在存储器上并可在处理器上运行的计算机程序,其特征在于,所述处理器执行所述程序时实现权利要求1至6任一项所述的抽象语法树重构方法。
14.一种计算机可读存储介质,其上存储有计算机程序,其特征在于,该计算机程序被处理器执行时实现权利要求1至6任一项所述的抽象语法树重构方法。
CN202110343587.6A 2021-03-30 2021-03-30 一种抽象语法树重构方法及装置 Active CN112860264B (zh)

Priority Applications (1)

Application Number Priority Date Filing Date Title
CN202110343587.6A CN112860264B (zh) 2021-03-30 2021-03-30 一种抽象语法树重构方法及装置

Applications Claiming Priority (1)

Application Number Priority Date Filing Date Title
CN202110343587.6A CN112860264B (zh) 2021-03-30 2021-03-30 一种抽象语法树重构方法及装置

Publications (2)

Publication Number Publication Date
CN112860264A CN112860264A (zh) 2021-05-28
CN112860264B true CN112860264B (zh) 2024-02-09

Family

ID=75993269

Family Applications (1)

Application Number Title Priority Date Filing Date
CN202110343587.6A Active CN112860264B (zh) 2021-03-30 2021-03-30 一种抽象语法树重构方法及装置

Country Status (1)

Country Link
CN (1) CN112860264B (zh)

Families Citing this family (2)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN113918951B (zh) * 2021-12-16 2022-03-22 北京微步在线科技有限公司 基于抽象语法树的恶意代码检测方法、装置及电子设备
CN114780100B (zh) * 2022-04-08 2023-04-07 芯华章科技股份有限公司 编译方法、电子设备及存储介质

Citations (3)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN111124414A (zh) * 2019-12-02 2020-05-08 东巽科技(北京)有限公司 一种基于操作链接的抽象语法树取词方法
CN111767076A (zh) * 2020-06-23 2020-10-13 中国工商银行股份有限公司 代码重构方法及装置
CN112363706A (zh) * 2020-11-20 2021-02-12 上海悦易网络信息技术有限公司 一种嵌套组合的预处理方法及设备

Family Cites Families (1)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US20140282373A1 (en) * 2013-03-15 2014-09-18 Trinity Millennium Group, Inc. Automated business rule harvesting with abstract syntax tree transformation

Patent Citations (3)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN111124414A (zh) * 2019-12-02 2020-05-08 东巽科技(北京)有限公司 一种基于操作链接的抽象语法树取词方法
CN111767076A (zh) * 2020-06-23 2020-10-13 中国工商银行股份有限公司 代码重构方法及装置
CN112363706A (zh) * 2020-11-20 2021-02-12 上海悦易网络信息技术有限公司 一种嵌套组合的预处理方法及设备

Also Published As

Publication number Publication date
CN112860264A (zh) 2021-05-28

Similar Documents

Publication Publication Date Title
US9524279B2 (en) Help document animated visualization
CN110502227B (zh) 代码补全的方法及装置、存储介质、电子设备
US8972936B2 (en) Version labeling in a version control system
CN112860264B (zh) 一种抽象语法树重构方法及装置
CN108469955B (zh) 一种基于注解的Android注入框架实现方法
CN107665170B (zh) 一种流程测试方法及装置
CN112988601A (zh) 测试脚本开发方法及装置
CN111367524A (zh) 枚举类型设计方法及装置
CN114138244A (zh) 模型类文件自动生成方法、装置、存储介质及电子设备
US11573790B2 (en) Generation of knowledge graphs based on repositories of code
CN115237805A (zh) 测试案例数据准备方法及装置
CN113468534B (zh) 针对安卓应用程序的漏洞检测方法及相关装置
CN115904480B (zh) 代码重构方法、装置、电子设备及存储介质
CN112925564B (zh) 一种源代码的冗余导入类清理方法及装置
CN112970011A (zh) 记录查询优化中的谱系
US8825588B2 (en) Rule correlation to rules input attributes according to disparate distribution analysis
CN112860585B (zh) 一种测试脚本断言生成方法及装置
CN113419957A (zh) 基于规则的大数据离线批处理性能容量扫描方法及装置
CN114168119A (zh) 代码文件编辑方法、装置、电子设备以及存储介质
CN109992293B (zh) Android系统组件版本信息的组装方法及装置
CN111782641A (zh) 数据错误修复方法及系统
CN115543323B (zh) 一种页面开发方法及装置
CN110334098A (zh) 一种基于脚本的数据库合并方法及系统
CN113111223B (zh) 报文生成xml串的方法及装置
US20180032929A1 (en) Risk-adaptive agile software development

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