Page 18 - 《软件学报》2026年第7期
P. 18

赵英全 等: 基于大语言模型的        Java 新特性测试程序生成                                           2703


                 用的局部变量. TraverseAST   首先将插入点     I 标记为终止节点     stop (第  8  行). 随后, 从  stop  节点开始采用倒序遍历
                 的方式, 识别   stop  节点的父节点   father (第  10  行). 通过对  father 节点的所有子节点进行遍历, 如果在遍历过程中匹
                 配到终止节点     stop, 则会终止对当前子树的遍历        (第  12–14  行); 如果在遍历的过程中识别到变量定义, 则会将该节
                 点所对应的变量名称及类型保存至集合              R  中  (第  15–19  行). 当  father 节点的所有子节点都遍历完成之后, stop  节
                 点将被更新为当前的        father 节点  (第  21  行). 并将继续向上遍历其父节点的子节点, 直至遍历至当前方法               AST  的
                 root 节点为止  (第  22  行). 最终, TraverseAST  将会返回识别到的可复用程序元素集合        R (第  23  行), 用于为代码片段
                 的生成提供上下文信息.

                 算法  1. 可复用程序元素识别.
                 输入: 种子程序    S; 被选中的插入点     I; 插入点所在方法的抽象语法树         T;
                 输出: 可复用的程序元素集合         R.

                 1.   Function IdentifyReuseableElements (S, T, I)
                 2.      R ← []; /*记录可复用程序元素*/
                      R ← R∪GetReuseableGlobalFields(S ); /*识别可复用全局变量*/
                 3.
                 4.      R ← R∪GetReuseableFunctions(S ); /*识别可复用函数定义*/
                      R ← TraverseAST (T.root,I,R); /*识别可复用局部变量*/
                 5.
                 6.    return R;
                 7.   Function  TraverseAST(T.root,I,R)
                 8.    stop = I;
                 9.    do
                 10.   father = stop.father;
                 11.   for each child in father.children do
                 12.    if child == stop then
                 13.     break; /*匹配到终止节点, 终止当前子树遍历*/
                 14.    end
                 15.    if child is a variable declaration then
                 16.     varName  ← child.name;
                 17.     varType  ← child.type;
                 18.       R ← R∪{(varName,varType)}; /*记录变量名称及其类型*/
                 19.    end
                 20.   end
                 21.   stop = father;
                 22.  while stop != T.root /*遍历直至根节点*/
                 23.  return R;
                    为了进一步说明可复用程序元素的提取过程, 图                 6  展示了图  1  中种子程序   (不包含浅蓝色生成代码部分) 可
                 复用元素的提取过程. 为了方便说明, 图           6  中对方法  AST  中的部分节点进行了省略和合并, 以减少庞大的节点数
                 量. 在该示例中, 每个     AST  节点对应种子程序中的一个组成部分. 其中, 标记为              VarDel 的节点表示变量定义, 例如
                 节点  2、3  对应图  1  中种子程序的第    3  行. 需要注意的是, 标记为     Expr 的节点为表达式节点, 例如, 节点        8, 该节点
                 的后继节点为对象       o  创建的一个新的引用      (对应图   1  中的第  5  行). 该节点未声明新的变量定义, 因此节点         8  未被
                 标记为   VarDel 节点.
                    为了提取可复用的程序元素, LumiX          首先在  AST  中随机选择一个节点作为新生成代码的插入点, 即新生成的
   13   14   15   16   17   18   19   20   21   22   23