鉴于问题是:
查找表格的所有块:
try { ... }
catch (Exception e) { ... }
和
try { ... }
catch ( T1 e ) { ... }
....
catch ( Tn e ) { ... }
对于所有 T1,... Tn e,一个可以进行代码更改以及引发异常的原因的程序转换系统似乎是一个解决方案。
我们的DMS 软件再造工具包及其Java 前端可能会做到这一点。
您需要一个可以计算从主块内部抛出的异常集的分析器。您可能还想根据对象层次结构对这些异常进行分类;如果 Tm 是 Tn 的特化,您可能希望为 Tm 和 Tn 生成一个处理程序作为嵌套尝试。DMS 具有完整的类型分析,因此它可以确定代码中的类型,并由代码块抛出。必须编写自定义 DMS 代码来计算异常的对象层次结构。
您需要一个调用图,以便可以将调用图中发现的异常传播到尝试站点。我们有,但它需要为 Java 1.7 做一些工作。
您需要一个转换应用程序来修改代码。我认为您需要担心链式捕获来处理一般情况。使用 DMS,它应该如下所示:
rule specialize_catch(b_try: block,
E: qualifed_identifer, e: IDENTIFIER, b_recover: block,
c_pre: catches, c_post: catches):
statement -> statement
" try { \b_try }
\c_pre
catch ( \E \e ) { \b_recover }
\c_post "
->
" try { \b_try }
\c_pre
catch ( \least_specialized\(\E\,\b_try\,\c_pre\) \e ) { \b_recover }
catch ( \E e ) { \b_recover }
\c_post "
if exists_specialized_exception(E,b_try,c_pre);
要转换的语法是 *meta*quotes "..." 中的代码,以将其与重写规则的语法分开。重写规则有很多部分。它指定了一个名称(我们通常有数百个)。它提供了一组命名占位符(b_try、E、b_recover、...),表示目标语言(在本例中为 Java)中的特定命名句法形式,并以元引用之外的裸形式和转义(反斜杠)形式编写在元引号内。c_pre 是一系列 catch 结构的名称;我们可以这样做,因为“捕获”在摘要中形成了一个关联列表,对于 c_post 也是如此。它提供了可以调用自定义 DMS 机器来计算结果(布尔值或新语法 [树])的元函数调用(例如,least_specialized、exists_specialized_exception)。你' 请注意对 least_specialized 的元函数调用甚至对元函数调用的语法进行了转义(例如,逗号和括号),因为它们不是 Java 语言的一部分;在 Java 代码之外,这样的元函数调用不需要转义。最重要的是它有一个左侧(“匹配这个”,绑定元变量)和一个右侧(如果规则条件为真,则“用这个替换”。
元函数 least_specialized 和 exists_specialized 将计算主代码块 b_try 可能抛出的异常,以及由现有捕获 c_pre 处理的异常,以及当前异常类型 E、c_pre 之上和 E 之下最一般的异常,以及一个新的 catch块被插入。如果不存在,则 if 失败并且不再插入异常。您可能需要额外的转换来取消克隆重复的 b_recover 块。
我显然没有实现这一点,也可能没有完全考虑清楚。但我可以将此视为可能解决方案的途径。YMMV。
我会说对于 700 个实例,使用 DMS 执行此操作可能非常微不足道。如果您亲自花费 10 分钟(编辑、编译、哎呀……),那就是 7000 分钟或 ~ 100 小时,大约 2 周。我怀疑您是否可以将 DMS 配置为如此快速地执行此操作,尤其是以前从未这样做过。(我的公司有专业的 DMS 用户,这可能是一个可行的时间框架)。
但声称是一种工具可能确实存在。