简体   繁体   English

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

[英]Is there any Checkstyle/PMD/Findbugs rule to force “else if” to be on the same line?

In our project for chained if/else/if we would like to have following formatting: 在我们的链接if / else /项目中,如果我们想要进行以下格式化:

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

And forbid following one: 并禁止以下一个:

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

Is there some predefined rule in either of listed above static code analysis tools to force this code style? 上面列出的静态代码分析工具中是否有一些预定义规则来强制执行此代码样式? If no - I know there is an ability to write custom rules in all of those tools, which one would you suggest to implement such a rule (not really familiar with writing custom rules in either of them)? 如果不是 - 我知道有能力在所有这些工具中编写自定义规则,您建议实施这样的规则(不熟悉在其中任何一个中编写自定义规则)?

It can be done with CheckStyle, but you'll have to code a custom check . 它可以使用CheckStyle完成,但您必须编写自定义检查代码

Using a custom check allows you to completely ignore comments. 使用自定义检查可以完全忽略注释。 The line number that a token is on can be determined by calling getLineNo() on the DetailAST. 可以通过在DetailAST上调用getLineNo()来确定令牌所在的行号。 Here's what the AST looks like, with line number information (red circles): 以下是AST的样子,包含行号信息(红色圆圈):

在此输入图像描述

The custom check's code will likely be quite short. 自定义检查的代码可能很短。 You basically register for LITERAL_ELSE tokens and see if LITERAL_IF is their only child. 您基本上注册了LITERAL_ELSE标记,看看LITERAL_IF是否是他们唯一的孩子。 Also remember to handle SLIST s. 还要记得处理SLIST In those cases, LITERAL_IF and RCURLY should be the only children. 在这些情况下, LITERAL_IFRCURLY应该是唯一的孩子。 Both cases are illustrated in the above picture. 两种情况都在上图中说明。


Alternative using a RegExp check 使用RegExp检查的替代方案

For the record, I originally thought one could also configure a regex match using else[ \\t{]*[\\r\\n]+[ \\t{]*if\\b for the format property (based on this post ). 为了记录,我原本以为还可以使用else[ \\t{]*[\\r\\n]+[ \\t{]*if\\b配置正则表达式匹配, else[ \\t{]*[\\r\\n]+[ \\t{]*if\\bformat属性(基于此帖子 )。

Here's the mentioned regex as a railroad diagram: 这是所提到的正则表达式作为铁路图: 正则表达式可视化

This turned out not to be feasible, because it produces false negatives when there are comments between between else and if . 事实证明这是不可行的,因为当elseif之间存在注释时,它会产生错误否定。 Worse, it also produces false positives when the nested if is followed by unrelated code (like else { if() {...} <block of code>} . Thanks @Anatoliy for pointing this out! Since comments and matching braces which are mixed with comments cannot be reliably grasped by regexes, these problems obsolete the RegExp approach. 更糟糕的是,当嵌套的if后面跟着不相关的代码时,它也会产生误报(就像else { if() {...} <block of code>} 。感谢@Anatoliy指出这一点!因为评论和匹配的括号是混合评论不能被正则表达式可靠地掌握,这些问题已经过时了RegExp方法。

This post says you can't do it in Checkstyle. 这篇文章说你不能在Checkstyle中做到这一点。

In PMD you definitely can. 在PMD你绝对可以。 The AST (abstract syntax tree) is different. AST(抽象语法树)是不同的。

For the pattern you don't want 对于你不想要的模式

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

The tree looks like: 树看起来像:

<IfStatement>
  <Expression>...</Expression>
  <Statement>...</Statement>
  <Statement>
    <Block>
      <BlockStatement>
        <IfStatement>...

For the pattern you do want 对于你想要的模式

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

The tree looks like: 树看起来像:

<IfStatement>
  <Expression>...</Expression>
  <Statement>...</Statement>
  <Statement>
    <IfStatement>...

In PMD 4 (which I used to make these trees), you write a rule by writing a XPath expression matching the pattern you don't want to occur. 在PMD 4(我曾经创建这些树)中,您通过编写与您不希望发生的模式匹配的XPath表达式来编写规则。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM