本发明涉及一种基于AST的Java代码SSA单路径的生成方法。
背景技术:
程序静态分析(Program Static Analysis)是在不运行程序的前提下进行的代码分析工作,随着越来越多的代码被上传到开源代码库中,大多数代码不可以直接运行,我们要对这些开源代码进行分析理解,就需要借助静态分析技术。静态分析技术中经常会涉及到符号执行(Symbolic Execution),抽象语法树(Abstract Syntax Tree,AST)分析,控制流分析(Control Flow Analysis)等,借鉴这些静态分析技术的思想,我们旨在提供一种Java代码静态单赋值(Static Single Assignment,SSA)格式的单路径的生成方法支持Java代码静态分析方面的工作,研究者可以在该工具的基础上进行Java代码的分析,降低了直接从代码文本进行分析的复杂性。
JDT(Java Development Tools)是Eclipse提供的一组用于实现Java IDE的工具,核心是AST,利用JDT提供的AST访问API,我们可以将Java代码转化成AST,遍历AST树节点,修改AST树结构并将修改写回到源代码。
技术实现要素:
针对现有技术中存在的问题,本发明目的是,提供一种Java代码SSA格式的单路径的生成方法支持Java代码静态分析方面的工作,研究者可以在该工具的基础上进行Java代码的分析,降低了直接从代码文本进行分析的复杂性。
本发明是通过以下的技术方案实现的:一种基于AST的Java代码SSA单路径的生成方法,包括步骤:
步骤10:输入存放.java文件的src目录的路径;
步骤11:使用ASTParser获得Java代码的AST;
步骤12:使用ASTVisitor处理所有的MethodDeclaration,将每一个方法都拆分成若干条单路径代码;
步骤13:使用JDT AST修改单路径代码的AST,将单路径转化为SSA的格式;
步骤14:将SSA格式的单路径封装成符合Java语法规范的Java类,存放在path目录下,作为输出。
其中步骤10所输入的Java工程源代码具有如下的目录结构:
TestCase类的包名为testcase,有test和test2两个方法,经过步骤14之后,最终的输出结果如下,其中每一个类中均包含若干条path_no方法,其参数和返回值均与路径所在方法相同,no为路径编号:
在步骤12中,使用ASTVisitor处理所有的MethodDeclaration,将每一个方法都拆分成若干条单路径代码的过程包括:
步骤20:获得MethodDeclaration的Body语句块Block
步骤21:依次处理Block中的每一条Statement,将条件分支语句如IfStatement,WhileStatement,ForStatement等拆分成一组平行的分支
步骤22:在不同组的平行分支各选一条分支进行组合,得到一条单路径
步骤23:穷举所有的分支间的组合情况,得到所有的单路径
步骤21涉及到对Block的递归处理,最终得到相应的中间结构,中间结构采用多叉树表示程序的控制流,便于进行路径抽取。步骤22能够对中间结构的不同层级间兄弟节点进行排列组合,得到其中的一条单路径。
在步骤13中,将单路径转化为SSA的格式的过程包括:
步骤30:使用ASTParser获得单路径代码的AST;
步骤31:使用ASTVisitor遍历AST,收集变量的声明、引用、赋值;
步骤32:使用ASTRewrite删掉AST所有关于变量声明的ASTNode;
步骤33:每当变量被赋值,就为该变量赋予一个新的变量名(对应AST中的SimpleName节点),使之成为一个新变量,该次赋值之后到下一次赋值之前对变量的引用均用新的变量名替换,在程序的开头添加新变量的声明;
步骤34:将上述修改操作写回到源代码。
本发明有益效果:这是一个源代码层面的借助于JDT AST提取Java代码中的单路径然后将其转化为SSA格式的静态分析辅助工具,利用这种工具,Java程序被简化成了一条条SSA格式的单路径代码,从而降低了直接从源代码进行分析的复杂性。
附图说明
图1本发明实施例的Java代码转化为SSA单路径示意图。
图2本发明实施例的输入目录结构示意图。
图3本发明实施例的输出目录结构示意图。
图4本发明实施例的处理条件分支语句获得单路径示意图。
图5本发明实施例的单路径代码转换为SSA格式示意图。
具体实施方式
以下结合附图和具体实施例对本发明作进一步详细说明。
本发明方法工作流程如图1-图5所示。
图1所示为本方法实施的整体结构和工作原理。本方法的目的是提供一个源代码层面的借助于JDT AST提取Java代码中的单路径然后将其转化为SSA格式的静态分析辅助工具,利用这种工具,Java程序被简化成了一条条SSA格式的单路径代码,从而降低了直接从源代码进行分析的复杂性。
本实施例的基于AST的Java代码SSA单路径的生成方法,包括如下步骤:
步骤10:输入存放.java文件的src目录的路径;
步骤11:使用ASTParser获得Java代码的AST;
步骤12:使用ASTVisitor处理所有的MethodDeclaration,将每一个方法都拆分成若干条单路径代码;
步骤13:使用JDT AST修改单路径代码的AST,将单路径转化为SSA的格式;
步骤14:将SSA格式的单路径封装成符合Java语法规范的Java类,存放在path目录下,作为输出。
图2表示的是步骤10所输入的Java工程源代码所在src目录的目录结构。
TestCase类的包名为testcase,有test和test2两个方法,经过步骤14之后,最终的输出结果如下(图3表示的是经过步骤14之后,存放单路径代码的path目录所具有的目录结构),其中每一个类中均包含若干条path_no方法,其参数和返回值均与路径所在方法相同,no为路径编号:
图4表示的是在步骤12中将每一个方法都拆分成若干条单路径时对条件分支语句的处理示意图,使用ASTVisitor处理所有的MethodDeclaration,将每一个方法都拆分成若干条单路径代码的过程包括:
步骤20:获得MethodDeclaration的Body语句块Block;
步骤21:依次处理Block中的每一条Statement,将条件分支语句如IfStatement,WhileStatement,ForStatement等拆分成一组平行的分支;
步骤22:在不同组的平行分支各选一条分支进行组合,得到一条单路径;
步骤23:穷举所有的分支间的组合情况,得到所有的单路径。
以下面的代码为例,作为步骤20要处理的函数体:
步骤21会涉及到对Block的递归处理,最终得到如下所示的中间结构:
步骤22可以得到其中一条单路径,一共有六条这样的单路径:
int i;
System.out.println(″=======″);
i=5;
System.out.println(i);
int j=i,z=4;
j=3;
if(j==5);
j++;
if(j==3);
System.out.println(j);
z=i+j;
if(z==4);
System.out.println(z);
return;。
图5表示的是在步骤13中,将单路径转化为SSA格式的处理示意图,执行的过程包括:
步骤30:使用ASTParser获得单路径代码的AST;
步骤31:使用ASTVisitor遍历AST,收集变量的声明、引用、赋值;
步骤32:使用ASTRewrite删掉AST所有关于变量声明的ASTNode;
步骤33:每当变量被赋值,就为该变量赋予一个新的变量名(对应AST中的SimpleName节点),使之成为一个新变量,该次赋值之后到下一次赋值之前对变量的引用均用新的变量名替换,在程序的开头添加新变量的声明;
步骤34:将上述修改操作写回到源代码。
下面给出一个转换前后对比的例子:
以上所述,仅为本发明的较佳实施例而已,并非对本发明作任何形式上的限制,虽然本发明已以较佳实施例揭露如上,然而并非用以限定本发明,任何熟悉本专业的技术人员,在不脱离本发明技术方案范围内,当可利用上述揭示的技术内容作出些许更改或修饰为等同变化的等效例,则仍属于本发明技术方案的保护范围内。