Page 41 - 《软件学报》2025年第4期
P. 41
沈阚 等: 基于静态分析的 Python 第三方库 API 兼容性问题检测方法 1447
API 不存在兼容性问题, 不再进行后续检测.
3.2 代码信息提取
代码信息提取从预处理后的规范代码 APIcode 1 和 APIcode 2 中抽取语句匹配信息 (M)、参数信息 (P)、返回
值信息 (R)、异常流信息 (E)、切片信息 (S)、全局语句信息 (G) 以及条件分支信息 (B). 给定 APIcode 1 , 抽取的代
码信息可分别表示为 M 1 , P 1 , R 1 , E 1 , S 1 , G 1 , B 1 . 除提取全局语句信息 (G) 外, 代码信息提取步骤不涉及 API 外部代
码信息, 仅分析 API 内部的源代码. 换句话说, 代码信息提取步骤仅涉及过程内分析, 而不涉及过程间分析.
3.2.1 语句匹配信息 (M)
本方法使用 GumTree 工具 [28] 在两个版本中同一个 API 的抽象语法树上进行语句级别的匹配, 得到的语句匹
配信息 M 可以表示为一个四元组<add, del, change, unchange>. 其中, add、del、change、unchange 分别表示新增
语句集合、删减语句集合、更新语句集合以及未变语句集合. 本文用 s i 表示源代码 APIcode 中存在的语句, i 表示
其所在的行号. 特别地, 对于 if、for 等控制语句, 方法根据其逻辑条件进行匹配并记录对应的行号. 集合 M.change、
M.unchange 中的元素可以表示为二元组<s a , s b >, 表明 v1 版本中的语句 s a 和 v2 版本中的语句 s b 存在匹配关系.
记 M 1 .change 和 M 2 .change 表示 v1 版本和 v2 版本中的更新语句集合, M 1 .unchange 和 M 2 .unchange 表示 v1 版本
和 v2 版本中的未变语句集合.
3.2.2 参数信息 (P)
参数信息包括参数顺序、参数名称、参数类别和参数默认值. 参数信息 P 可以表示为五元组<pst, dft, abt,
key, kwargs>, 分别记录位置参数、默认参数、可变参数、命名关键字参数以及关键字参数的信息. 此外, 用
Name(P) 记录 API 所有参数的名称, 同理用 Name(P.pst) 记录 API 所有位置参数的名称.
(1) pst 集合记录位置参数的名称与顺序间的对应关系, 由 Map 类型 name: idx 组成, 从字符串类型映射到整数
类型.
(2) dft 集合记录默认参数的名称与顺序、默认值间的对应关系, 由 Map 类型 name: <idx, value> 组成, 从字符
串类型映射到一个二元组.
(3) abt 变量记录可变参数的信息, 若 API 有可变参数, P.abt 变量记录可变参数的名称, 否则记 P.abt 变量为 NA.
(4) key 集合记录命名关键字参数的名称与默认值间的对应关系, 由 Map 类型 name: value 组成. 特别地, 若命
名关键字参数无默认值, value 为 NA. TryStmts 是记录
(5) kwargs 变量记录关键字参数的信息, 若 API 有关键字参数, P.kwargs 变量记录关键字参数的名称, 否则记
P.kwargs 变量为 NA.
3.2.3 返回值信息 (R)
返回值信息 R 是包含了所有返回语句 (return) 的集合.
3.2.4 异常流信息 (E)
异常流信息由两部分组成, 分别是抛出异常信息 E.R 和捕获异常信息 E.C.
(1) 抛出异常信息 E.R: 集合 E.R 记录抛出异常语句 s i 与抛出异常类型、抛出异常条件的对应关系, 由 Map 类
型 s i : <exception, condition> 组成. 元素 exception 是记录 s i 抛出异常类型的变量, 元素 condition 是记录 s i 抛出异常
的触发条件的变量. 注意, Python 中的异常分为解释器自动抛出和开发者利用 raise 语句主动抛出两种, 均用 E.R
记录.
(2) 捕获异常信息 E.C: 集合 E.C 记录 try-except 结构进行异常捕获的信息, 由 Map 类型 s i : <TryStmts,
AllStmts> 组成. s i 记录 try 语句, 元素 try 语句所处理代码块的语句集合, 元素 AllStmts 是记录 try-
except 结构中所有语句的集合.
3.2.5 切片信息 (S)
给定参数信息 P 和返回值信息 R, 本方法使用工具 [29] 对代码进行切片 (slicing), 抽取与 P、R 相关的切片语
句. 切片分为前向切片 (forward slicing) 与后向切片 (backward slicing). 具体来说, 本方法将预处理后的 API 代码输
入给工具 [29] , 并指定切片的方向以及切片入口, 则工具 [29] 会输出与指定参数或返回值有关的控制流、数据流语句