通过重构自动简化代码 [英] Automatic code simplification via refactoring

查看:99
本文介绍了通过重构自动简化代码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否存在用于通过重构自动简化Java代码的工具?

Is there a tool for automatic java code simplification via refactoring?

有用于Python和C的此类工具:

There are such tools for Python and C:

  • Automatically simplifying/refactoring Python code (e.g. for loops -> list comprehension)?
  • Is there a tool to test the conciseness of c program?)

但我不知道有任何此类Java程序。

but I'm not aware of any such program for Java.

在很多情况下,工具可以自动简化代码,例如:

There are many cases where a tool could automatically simplify code, like e.g.:


  • 循环: for(String s:a){b.add( s); } b.addAll(a);

  • 如果/返回:如果(x)返回true;否则返回false; return x;

  • 三元运算符: if( x){结果= a;}其他{结果= b;} 结果= x? a:b;

  • 自动重构为钻石算子/异常多捕获/ lambdas

  • 还有更多...

  • loops: for (String s: a) { b.add(s); }b.addAll(a);
  • if/return: if (x) return true; else return false;return x;
  • ternary operator: if (x) {result = a;} else {result = b;}result = x ? a : b;
  • automatic refactor to diamond operator / exception multi catch / lambdas
  • lots more...

这种自动重构的优点是删除了许多样板代码行,使其更加简洁明了。

The advantage of such automatic refactor is removal of lots of boilerplate lines of code, making it more clean and conceise.

推荐答案

可以。查看程序转换工具(PTS)。此类工具提供了一种定义语法,使用该语法将源文本解析为AST以及将AST漂亮打印回文本的方法。更重要的是,使用相同的语法读取源到源转换规则,该规则允许您直接表达转换(或根据重写集表达复合转换)。这种转换使用表达的模式与AST进行匹配,并修改AST;这些转换是基于结构的,不会与布局或空格混淆。

Sure. Check out Program Transformation Tools (PTS). Such tools provide a means to define a grammar, use that grammar to parse source text to ASTs, and prettyprint ASTs back to text. More importantly, the same grammar is used to read source-to-source transformation rules, that allow you to express transformations directly (or express compound transformations in terms of sets of rewrites). Such transformations use the expressed patterns to match against the ASTs, and modify the ASTs; these transformations, being structure based, are not confused by layout or whitespace.

例如,我们的DMS软件再造工具包允许您以 if形式编写规则您会看到,将其替换为,并采用以下一般形式:

As an example, our DMS Software Reengineering Toolkit let you write rules in the form if you see this, replace it by that, taking the general form:

 rule rule_name(pattern_variables)
   : pattern_syntax_category -> replacement_syntax_category
 = metaquote  pattern_text_in_specified_language metaquote
 => metaquote replacement_text_in_specified_language metaquote
 if condition_over_bound_pattern_variables;

其中


  • 规则是引入规则的语法,

  • rule_name 为该规则赋予了一个名称,以区别于其他规则,

  • pattern_variables 是模式
    变量名 n 和语法的成对 n:c 的列表 n 必须满足的类别 c

  • pattern_syntax_category pattern_text的语法类别必须满足,

  • replacement_syntax_category replacement_text 必须满足的语法类别。通常,在此处给出的所有示例中,
    pattern_syntax_category 相同;使用重写规则在语言之间进行翻译时,这些语言通常会有所不同,因为语言的语法类别有所不同。

  • metaquote 是字符,用于分隔规则语言模式或替换语言语法的语法

  • pattern_text_in_specified_language 是源语言的格式良好的片段,包含模式变量 n 写为\n;任何模式匹配都将模式变量绑定到子树。如果\n在模式中出现两次,则两个实例必须相同。

  • replacement_text_in_specified_language 是目标语言的格式良好的片段,将找到的样式替换为替换样式,替换中的所有样式变量都替换为绑定的样式变量值

  • if 是引入条件的语法

  • condition_over_bound_pattern_variables 是模式变量的约束找到模式匹配后必须满足。这通常用于检查必须满足的上下文条件。

  • rule is syntax introducing a rule,
  • rule_name gives the rule a name to distinguish it from other rules,
  • pattern_variables is a list of pairs n:c of a pattern variable name n and syntax category c which n must satisfy,
  • pattern_syntax_category is a syntax category that the pattern_text must satisfy,
  • replacement_syntax_category is a syntax category that the replacement_text must satisfy. Usually, and in all examples given here, the same as pattern_syntax_category ; when using rewrite rules to translate between languages, these often differ because the syntax categories in the languages differ.
  • metaquote is the " character, which seperates the rule language syntax from that of the pattern or replacement language syntax
  • pattern_text_in_specified_language is a well-formed fragment of the source language, containing pattern variables n written as \n; any match of pattern binds the pattern variables to subtrees. If \n occurs twice in pattern, both instances must be identical.
  • replacement_text_in_specified_language is a well-formed fragment of the target langauge. A found pattern is replaced by the replacement, with any pattern variables in the replacement substitued by the bound pattern variable value
  • if is syntax introducing a condition
  • condition_over_bound_pattern_variables is a constraint that the pattern variables must satisfy after a pattern match has been found. This is often used to check context conditions that must be satisified.

DMS将使您编写并应用以下示例转换(包括一些示例转换) OP的示例):

DMS will let you write and apply the following example transformations (including some of OP's examples):

 default domain Java~v8; -- specify v8 dialect of Java to manipulate

 rule reduce_strength_squared(e: term):
     :product -> product
 = "\e ^ 2 " ==> "\e * \e "
 if no_side_effects(e);

 rule optimize_divide_by_self(e: term):
     :product -> product
 = " \e / \e " => " 1 " if is_not_zero(e);

 rule accumulate_string(n: IDENTIFIER, a: expression, b: left_hand_side)
   : statement -> statement
 = "for (String \s: \a) { \b.add(\s); }"
 => "\b.addAll(\a);";

 rule eliminate_useless_if(x: expression, s: statement)
    : statement -> statement
 = "if (\x) \s; else \s; " -- generalizes OP's example
 => "\s;";

 rule left_factor_ternary(x: expression; t: left_hand_side; a: expression; b:expression)
      : statement -> statement
 =  "if (\x) { \t = \a;} else {\t = \b;} "
 =>  "\t = \x ? \a : \b ";

 rule convert_to_diamond( T1: qualified_path, T2: qualified_path,
                           C: qualified_path, 
                           i: IDENTIFIER, a: arglist)
       :statement -> statement
 =  "\T1<\T2> \i = new \C<\T2>(\a);"
 => "\T1<\T2> \i = new \C<>(\a);"

 rule merge_multi_catch( b:body, i1: IDENTIFIER, e1: qualified_path,
                                  i2: IDENTIFIER,  eh: body  )
       :statement -> statement
  = "try { \b }
     catch ( \i1: \e1 ) { \eh }
     catch ( \i2: \e1 ) { \eh }";
  => "try { \b }
     catch ( \i1, \i2: \e1 ) { \eh }";

更复杂的转换是可能的,包括那些影响程序中相距甚远甚至不同的部分的转换源文件边界。这些通常需要一些额外的元编程(此处不讨论),并且经常需要对上下文进行一些额外的检查,例如,标识符的类型正确等。[DMS拥有完整的Java符号表来支持此功能。]

More sophisticated transformations are possible, including those that affect parts of the program that are far apart and even across source file boundaries. These usually require some additional metaprogramming (not discussed here) and often some additional checks on the context, e.g., that identifiers are of the right type, etc. [DMS has full symbol tables for Java to support this].

其他PTS可以类似的方式表达规则。尽管它们声称可以自己编写程序,但它们大多数都不支持更深层的语义事实,例如符号表或类型。经验表明,这是很多工作,您确实希望它是正确的。 (谁想要他们的转换破坏代码,因为它对错误的信息进行操作?)。

Other PTS can express rules in similar way. Most of them don't provide support for deeper semantic facts such as symbol tables or types, although the claim is that you can program those yourself. Experience shows this is a lot of work, and you really want it to be right. (Who wants their transformation to damage the code because it is operating on bad information?).

这篇关于通过重构自动简化代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆