Как определить if(true) и другие проблемы рефакторинга?

В java обычно при использовании «современных» IDE встраиваются значения переменных и выполняется сложный рефакторинг, который может, например, преобразовать этот исходный код.

boolean test = true;
//...
if(test) {
    //...
}

В этот код

if(true) {
    //...
}

Очевидно, этот код можно упростить, но Eclipse не сделает за меня это упрощение.

Итак, есть ли способ (используя Eclipse или, что еще лучше, maven), который может обнаружить и (возможно) упростить этот код? (очевидно, было бы намного лучше, если бы такой инструмент мог обнаруживать другие неправильные конструкции, такие как пустые циклы for,...)


person Riduidel    schedule 11.04.2014    source источник
comment
Исходя из предположения, что Eclipse (изначально) не предоставляет такую ​​функциональность (о которой, я уверен, вы бы знали, если бы она это сделала), я рассматриваю этот вопрос как просьбу порекомендовать или найти инструмент, [плагин,] библиотеку или любимый сторонний ресурс, не относящийся к теме Stack Overflow, согласно справочному центру.   -  person Bernhard Barker    schedule 11.04.2014
comment
@Dukeling Хорошо, есть ли какие-нибудь галактические сайты StackExchange, где этот вопрос (1) был бы по теме (2) имел ли бы шанс быть прочитанным разработчиками? Потому что я боюсь, что рекомендации по программному обеспечению далеко не уведут меня в этом вопросе ...   -  person Riduidel    schedule 11.04.2014
comment
Я думаю, что рекомендации по программному обеспечению будут самыми близкими. Насколько мне известно, такие вещи не обсуждаются больше нигде. Я не могу сказать, насколько успешно вы ответите на вопрос конкретного разработчика, хотя у них есть разработка программного обеспечения. тег (вы можете проверить, были ли похожие вопросы + посмотреть, насколько они были успешными, хотя этот тег может не охватывать их все), и на большинстве сайтов, не предназначенных для разработчиков, обычно много разработчиков. во всяком случае (из того, что я видел).   -  person Bernhard Barker    schedule 11.04.2014
comment
Но вы также можете включить язык(и), с которыми вы хотите это использовать, и, возможно, более конкретно указать, какой именно рефакторинг вы хотите выполнить.   -  person Bernhard Barker    schedule 11.04.2014


Ответы (1)


Вам нужна система трансформации программы (PTS).

Это инструменты, которые считывают исходный код, создают структуры данных компилятора (почти всегда включая как минимум AST), выполняют индивидуальный анализ и модификацию структур данных компилятора, а затем регенерируют исходный текст (для измененной программы) из этих измененных структур данных. .

Многие из PTS позволят вам выражать изменения в коде непосредственно в форме исходного кода в виде правил, выраженных в терминах синтаксиса языка, метапеременных и т. д. Смысл такого языка правил в том, чтобы позволить вам более точно выражать сложные преобразования кода. без труда.

Наш набор инструментов для реинжиниринга программного обеспечения DMS является таким PTS. Вы можете легко упростить код с помощью логических выражений, содержащих логические константы, со следующими простыми правилами:

default domain Java~v7;

simplify_not_true(): primary -> primary
     " ! true" -> "false";

simplify_not_false(): primary -> primary
     " ! false" -> "true";

simplify_not_not(x: primary): primary -> primary
     " ! ! \x " ->  "\x";

simplify_and_right_true(x: term): conjunction -> conjunction ;
   " \x && true " ->  "\x";

simplify_and_left_true(x: term): conjunction -> conjunction ;
   " true && \x " ->  "\x";

simplify_and_left_false(x: term): conjunction -> conjunction ;
   " false && \x " ->  "false";

simplify_and_right_false(x: term): conjunction -> conjunction ;
   " \x && false " ->  "false"
   if no_side_effects_or_exceptions(x);  -- note additional semantic check here

simplify_or_right_false(x: term): disjunction -> disjunction ;
   " \x || false " ->  "\x";

simplify_or_left_false(x: term): disjunction -> disjunction ;
   " false || \x " ->  "\x";

simplify_or_right_true(x: term): disjunction -> disjunction ;
   " \x || true " ->  "true"
   if no_side_effects_or_exceptions(x);

simplify_or_left_true(x: term): disjunction -> disjunction ;
   " true || \x " ->  "true";

(Имена грамматик «термин», «первичный», «союз», «дизъюнкция» взяты непосредственно из BNF, используемого для анализа исходного кода Java.)

Вместе эти правила будут принимать логические выражения, включающие известные логические константы, и иногда упрощать их до просто «истина» или «ложь».

Чтобы исключить операторы if, выражения которых являются булевыми константами, можно было бы написать следующее:

 simplify_if_true(b: block): statement -> statement
    " if (true) \b" -> " \b ";

 simplify_if_false(b: block): statement -> statement
    " if (false) \b" -> ";"  -- null statement

Вместе с логическим упрощением эти два правила избавят вас от условных выражений для заведомо истинных или заведомо ложных условных выражений.

Сделать то, что вы хотите, немного сложнее, потому что вы хотите распространять информацию из одного места в программе в другое место, возможно, «далеко». Для этого вам нужен анализ потока данных, показывающий, куда могут попасть значения из их назначений:

default domain Java~v7;

rule propagate_constant_variables(i:IDENTIFIER): term -> term
     " \i " -> construct_reaching_constant()
     if constant_reaches(i);

Это правило зависит от встроенного анализа, предоставляющего факты о потоках данных, и пользовательской функции интерфейса «constant_reaches», которая проверяет эти данные. (DMS имеет это для C, C++, Java и COBOL и поддерживает это для других языков; насколько мне известно, ни один из других PTS, упомянутых в статье Википедии, не имеет этих доступных фактов о потоке). Также зависит от пользовательского конструктора "contruct_reaching_constant" для построения узла примитивного дерева, содержащего константу достижения. Они будут закодированы на базовом языке метапрограммирования DMS и потребуют нескольких десятков строк кода. Аналогично рассмотренному ранее специальному условию "no_side_effects_or_exceptions"; это может быть намного сложнее, так как вопрос о побочных эффектах может потребовать анализа всей программы.

Есть такие инструменты, как Clang, которые могут до некоторой степени преобразовывать код C++, но Clang не имеет правил перезаписи, как в PTS, это действительно компилятор с дополнительными хуками.

person Ira Baxter    schedule 13.04.2014