自动将花括号添加到java代码库中的所有if/else/for/while等
我想减少大型遗留java代码库中sonar违规的数量,而将所有这些条件语句更新为大括号似乎是一个“快速胜利”。这似乎是一件容易做到的事情,我不明白为什么它不容易自动化 有人知道有一种工具可以执行这样的批量操作吗?或者为什么在我自己去写东西之前做这样的事情可能是个坏主意?如果我自己写一本,那么最好的工具是什么?理想情况下,它应该是java语言感知的,这样我就不必处理格式化角落案例之类的事情自动将花括号添加到java代码库中的所有if/else/for/while等,java,formatting,sonarqube,Java,Formatting,Sonarqube,我想减少大型遗留java代码库中sonar违规的数量,而将所有这些条件语句更新为大括号似乎是一个“快速胜利”。这似乎是一件容易做到的事情,我不明白为什么它不容易自动化 有人知道有一种工具可以执行这样的批量操作吗?或者为什么在我自己去写东西之前做这样的事情可能是个坏主意?如果我自己写一本,那么最好的工具是什么?理想情况下,它应该是java语言感知的,这样我就不必处理格式化角落案例之类的事情 顺便说一句,该规则是不可协商的,因此这确实是最好的方法。最简单的方法是使用并在整个项目上单击清理。在清理配置
顺便说一句,该规则是不可协商的,因此这确实是最好的方法。最简单的方法是使用并在整个项目上单击
清理
。在清理
配置文件配置中,选择代码样式
选项卡。在那里,您可以选择if/while/for/do语句中的使用块作为始终这让我觉得可能非常危险。你有全面的单元测试覆盖范围吗
我可以看到一些很难立即解决的案例
if (x) doMethodA(); doMethodB();
及
有两个问题让人想到,不能天真地处理(你应该有语言意识来解决这些问题)。除非你有语言意识和可靠的工具,否则我不会尝试自动化这样一项任务,而是强制执行一项策略,当你出于其他原因更改代码时,你可以修改代码,并且可以在更改代码之前通过单元测试断言代码覆盖率。虽然这可能是sonar的快速胜利,但你正在做一些危险的事情。建议的方法是仅在必须重新访问遗留代码时修复该代码。这些笼统的方法可能会导致非常微妙的错误。由于政策已发生变化,您的管理团队需要了解这是一项艰巨的任务,并应确保所有未来的代码都按照标准进行开发。首先在检查设置中启用无括号的控制流语句
IntelliJ Idea->Run Code Inspection->Quick Fix(至少在商业版本中有效)虽然建议谨慎使用遗留代码,但检测遗留代码中的错误也是一件好事。。。或者至少让bug更容易被发现
让我们来考虑Brian Agnew的疑难案件:
// Case #1
if (x) doMethodA(); doMethodB();
事实上,就JLS和Java编译器而言,这意味着
因此,当转换器将代码重写为:
if (x) {
doMethodA();
}
doMethodB();
它不是改变代码的含义,而是纠正一个可能导致某人误读代码、错过代码中已经存在的潜在错误的问题;i、 e.如果第二次呼叫是有条件的
// Case #2
if (x)
// doMethodA();
doMethodB();
同样,当重写时,您应该得到:
if (x) {
// doMethodA();
doMethodB();
}
这和原作的意思是一样的。此外,这很可能反映了程序员的意图。。。如果压痕是可信的。但是考虑一下:
// Case #2a
if (x)
// doMethodA();
doMethodB();
当我们把它改写为
if (x) {
// doMethodA();
doMethodB();
}
代码的实际含义不会改变,错误的缩进也不会再误导用户。如果程序员决定取消对第一个调用的注释,他可能没有意识到前面的注释有一个意外的结果。(原始压痕中的证据表明我们已经“修复了”。)但有一个潜在的解决方案;见下文
如果我们假设代码转换工具在正确理解Java的语法和语义的情况下运行,那么它不会破坏任何尚未破坏的东西,并且(在一定程度上)会使任何现有的破坏对阅读代码的人来说更加明显。对我来说,这是一个零风险的胜利,即使对于遗留代码也是如此
现在,如果我们让transformer变得更智能,它可以检测到一些原始缩进指示可能存在错误的情况(如上面的案例1和案例2a),并标记它们以便更仔细地检查代码。Robert在评论中说:“@ira我也有兴趣听到这个真正有语言意识的工具!”
对不起,我开玩笑了。关于这个笑话的原因,请查看我的简历
未经检验:视为基础发动机。这对组合构成了一个完全支持语言的源到源程序转换系统
我们可以使用DMS完成这项任务,DMS有两个源到源转换规则:
rule curlies_for_then_statement:(c:expression, s: statement}:
statement->statement
" if (\c) \s " -> "if (\c) { \s } ";
rule curlies_for_else_statement:(c:expression, b: block, s: statement}:
statement->statement
" if (\c) \b else \s " -> "if (\c) \b else { \s } ";
这是可靠的,因为DMS完全由形式语法驱动(在本例中为Java),并且不是对原始文本进行操作,而是对抽象语法树进行操作;这也使得在独立的布局。(理解“block”、“expression”和“statement”是语法非终结符的规则可能很有用。Intellij 2017通过重新格式化代码来支持这一点,前提是您首先在编辑器设置中设置了正确的编码样式
File -> Settings -> Editor -> Code Style -> Java -> Wrapping and Braces
顺便说一句,这个规则是不可协商的,所以这确实是最好的方法
有趣
您有一个充满样式错误的遗留代码库,必须修复样式错误是不可协商的
这个练习的价值主张(至少可以说)是可疑的。“遗留代码库”通常是一种礼貌的说法,表示应该扔掉并重写代码……但你负担不起。然而,显然,你可以花费钱纠正缺少的大括号,这不太可能对可维护性产生任何实际影响
正如前面的答案所指出的。如果您正确地自动化了此样式更正:
- 它实际上不会修复任何bug,但也不会引入任何新bug
- 它可能会删除作为现有bug标志的“线索”(例如可疑的缩进)
但如果手动执行样式更正:
- 您可能会注意到一些bug。这些bug可以添加到您的问题跟踪器中,以便
rule curlies_for_then_statement:(c:expression, s: statement}:
statement->statement
" if (\c) \s " -> "if (\c) { \s } ";
rule curlies_for_else_statement:(c:expression, b: block, s: statement}:
statement->statement
" if (\c) \b else \s " -> "if (\c) \b else { \s } ";
File -> Settings -> Editor -> Code Style -> Java -> Wrapping and Braces