Учитывая, что проблема:
Найдите все блоки вида:
try { ... }
catch (Exception e) { ... }
с
try { ... }
catch ( T1 e ) { ... }
....
catch ( Tn e ) { ... }
для всех T1, ... Tn e система преобразования программ, которая может выполнять изменения кода и причины возникновения исключений, кажется решением.
Наш инструментарий реинжиниринга программного обеспечения DMS с его Java Front End, скорее всего, может сделать это.
Вам нужен анализатор, который может вычислить набор исключений, генерируемых внутри основного блока. Вероятно, вы также захотите классифицировать эти исключения в соответствии с иерархией объектов; если 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 для вычисления результатов (булевы значения или новый синтаксис [деревья]). Вы заметите, что в вызове метафункции наименьший_специализированный даже синтаксис для вызова метафункции экранирован (например, запятые и круглые скобки), поскольку они не являются частью языка Java; вне кода Java такие вызовы метафункций не нуждаются в экранировании. И самое главное, у него есть левая часть («сопоставить это», привязка метапеременных) и правая часть («заменить этим», если условие правила истинно.
Метафункции наименьший_специализированный и существующий_специализированный будут вычислять для исключений, которые может генерировать основной блок кода b_try, а также для тех, которые обрабатываются существующими перехватами c_pre и текущим типом исключения E, наиболее общим исключением выше c_pre и ниже E, а также для нового перехвата блок вставлен. Если таковых не существует, то if завершается ошибкой, и вставки исключений больше не выполняются. Возможно, вам понадобятся дополнительные преобразования для деклонирования дублированного блока b_recover.
Я, очевидно, не реализовал это и, возможно, не продумал это полностью. Но я вижу в этом путь к возможному решению. YMMV.
Я скажу, что для 700 экземпляров, вероятно, довольно маргинально делать это с DMS. Если вам лично потребовалось по 10 минут на каждую часть (редактирование, компиляция, упс...), то это 7000 минут или ~~ 100 часов, около 2 недель. Я сомневаюсь, что вы могли бы настроить DMS, чтобы сделать это так быстро, особенно если вы никогда не делали этого раньше. (В моей компании есть опытные пользователи DMS, для которых это, вероятно, приемлемый срок).
Но утверждается, что инструмент, вероятно, существует.
person
Ira Baxter
schedule
28.03.2012
catch
блоков на самом деле перехватят огромное количествоNullPointerException
? Вы не хотите изменять его, чтобы позволитьNullPointerException
пройти без также устранения основной проблемы (проблем). - person ruakh   schedule 29.03.2012try{}
- person andersoj   schedule 29.03.2012try { some code that could throw A,B,C} catch ( Exception ) { lame }
наtry { some code that could throw A,B,C } catch ( A, B, C, RuntimeException ) { lame }
Это бесполезно, кроме как в качестве первого шага в улучшении кода. - person emory   schedule 29.03.2012catch (Exception e) { Log(e); }
Поэтому не могут выполнять поиск/замену без некоторого семантического анализа содержимого блокаtry{}
. - person andersoj   schedule 29.03.2012Log
? Я бы изменил только то исключение, которое вы действительно видите в журналах. - person Peter Lawrey   schedule 29.03.2012