是否有任何Checkstyle / PMD / Findbugs规则强制“else if”在同一条线上?

在我们的链接if / else /的项目中,如果我们想要进行以下格式化:

if (flag1) { // Do something 1 } else if (flag2) { // Do something 2 } else if (flag3) { // Do something 3 } 

并禁止以下一个:

 if (flag1) { // Do something 1 } else { if (flag2) { // Do something 2 } else { if (flag3) { // Do something 3 } } } 

上面列出的静态代码分析工具中是否有一些预定义规则来强制执行此代码样式? 如果不是 – 我知道有能力在所有这些工具中编写自定义规则,你会建议实施这样的规则(不熟悉在其中任何一个中编写自定义规则)?

它可以使用CheckStyle完成,但您必须编写自定义检查代码 。

使用自定义检查可以完全忽略注释。 可以通过在DetailAST上调用getLineNo()来确定令牌所在的行号。 以下是AST的样子,包含行号信息(红色圆圈):

在此处输入图像描述

自定义检查的代码可能很短。 你基本上注册了LITERAL_ELSE标记,看看LITERAL_IF是否是他们唯一的孩子。 还要记得处理SLIST 。 在这些情况下, LITERAL_IFRCURLY应该是唯一的孩子。 两种情况都在上图中说明。


替代使用RegExp检查

为了记录,我原本以为也可以使用else[ \t{]*[\r\n]+[ \t{]*if\b配置正则表达式匹配, else[ \t{]*[\r\n]+[ \t{]*if\bformat属性(基于此post )。

这是所提到的正则表达式作为铁路图: 正则表达式可视化

结果certificate这是不可行的,因为当elseif之间有注释时,它会产生漏报。 更糟糕的是,当嵌套的if后面跟着不相关的代码时,它也会产生误报(就像else { if() {...} } 。感谢@Anatoliy指出这一点!由于评论和匹配的括号是混合评论不能被正则表达式可靠地掌握,这些问题已经过时了RegExp方法。

这篇文章说你不能在Checkstyle中做到这一点。

在PMD你绝对可以。 AST(抽象语法树)是不同的。

对于你不想要的模式

 if (true) { String a; } else { if (true) { String b; } } 

树看起来像:

  ... ...    ... 

对于你想要的模式

 if (true) { String a; } else if (true) { String b; } 

树看起来像:

  ... ...  ... 

在PMD 4(我曾经制作这些树)中,您通过编写与您不希望发生的模式匹配的XPath表达式来编写规则。