Учитывая, что проблема:
Найти все блоки вида:
try { ... }
catch (Exception e) { ... }
с
try { ... }
catch ( T1 e ) { ... }
....
catch ( Tn e ) { ... }
для всех T1, ... Таким образом, система преобразования программ, которая может вносить изменения в код и рассуждать об исключениях, выглядит как решение.
Наш инструментарий реинжиниринга программного обеспечения 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);
Синтаксис для преобразования - это код в * мета * кавычках "...", чтобы отделить его от синтаксиса правил перезаписи. Правило перезаписи состоит из нескольких частей. Это указывает имя (у нас часто есть сотни). Он предоставляет набор именованных заполнителей (b_try, E, b_recover, ...), представляющих конкретные именованные синтаксические формы на целевом языке (в данном случае Java) и записанные в голой форме вне мета-цитаты и экранированной (с обратной косой чертой) формы внутри мета-кавычек. c_pre - это имя серии конструкций catch; мы можем сделать это, потому что «ловит» формирует ассоциативный список в аннотации, и аналогично для c_post. Он предусматривает вызовы мета-функций (например, наименьшей_специализированной, существует_специализированной_эксклюзии), которые могут вызывать пользовательские механизмы DMS для вычисления результатов (логические значения или новый синтаксис [деревья]). Вы заметите, что вызов метафункции для less_specialized даже содержит синтаксис экранированного вызова метафункции (например, запятые и скобки), поскольку они не являются частью языка Java; вне Java-кода такие вызовы метафункций не нужно экранировать. И самое главное, он имеет левую часть («сопоставить это», связывая метавариабельные переменные) и правую часть («заменить на это», если условие правила истинно.
Метафункции less_specialized и exist_specialized вычисляют для исключений, которые может генерировать основной кодовый блок b_try, и тех, которые обрабатываются существующими уловами c_pre и текущим типом исключения E, наиболее общим исключением выше c_pre и ниже E, и новый блок захвата вставлен. Если ничего не существует, происходит сбой if и больше не производится вставка исключений. Возможно, вам понадобятся дополнительные преобразования для клонирования дублированного блока b_recover.
Я, очевидно, не реализовал это и, возможно, не продумал это полностью. Но я вижу в этом путь к возможному решению. YMMV.
Я скажу, что для 700 случаев это, вероятно, довольно незначительно, делать это с DMS. Если лично вам потребовалось 10 минут (редактировать, компилировать, упс ...), это 7000 минут или ~ 100 часов, около 2 недель. Я сомневаюсь, что вы могли бы настроить DMS, чтобы сделать это так быстро, особенно никогда раньше. (У меня есть опытные пользователи DMS в моей компании, для которых это, вероятно, приемлемый период времени).
Но утверждается, что инструмент, скорее всего, существует.