2011-05-26 23 views
12

我使用checkstyle來檢查我的java代碼是否符合我們項目的指導原則。允許使用簡單的if語句,而無需在代碼樣式中使用大括號

但是,我們有一個指導原則,我無法弄清楚如何使用此工具進行檢查。我們希望允許簡單,如果(明白,如果沒有其他人,並在它沒有其他有條件的結構)有沒有支柱,就像這個例子:

// valid 
if(condition) callFunction(); 

// invalid 
if(condition) for(int i = 0; i < someValue; i++) callFunction(i); 

// valid 
if(condition) { 
    for(int i = 0; i < someValue; i++) { 
     callFunction(i); 
    } 
} 

// invalid 
if(condition) callFunction(); 
else callOtherFunction(); 

這種約定可以討論,但是這是我們選擇的一個。它允許減少非常微不足道的情況下的語法,但確保我們對更復雜的結構具有良好的縮進和塊劃界。

任何幫助,將非常感激。

我也準備做一些代碼來執行這個檢查,如果沒有可用的,但真的不知道從哪裏開始。在上次重新編輯中,有關這方面的一些提示也將被讚賞。

+12

我嚴肅的建議是改變你的指導方針。你花時間尋找一個解決方案,使你的風格指南*劣勢*。內聯if語句(不使用塊)會導致錯誤。真的,真的很討厭的錯誤。 – 2011-05-26 17:06:38

+1

@Mark我不知道如何使用內聯ifs來進行簡單的函數調用,但我認爲使用它們來檢查一些條件並在條件不滿足時拋出異常是合理的。 – 2011-05-26 17:15:28

+6

這個問題不是關於指導是否合理。這個問題是關於如何修改checkstyle以支持這些準則。我認爲我們應該避免在這個問題上自己討論準則。 – 2011-05-26 17:25:59

回答

5

最後,我確實實現了checkstyle的自定義檢查。這裏是源代碼,如果別人有興趣的話:

import com.puppycrawl.tools.checkstyle.api.Check; 
import com.puppycrawl.tools.checkstyle.api.DetailAST; 
import com.puppycrawl.tools.checkstyle.api.TokenTypes; 

public class IfBracesCheck extends Check { 

    @Override 
    public int[] getDefaultTokens() { 
     return new int[] { 
      TokenTypes.LITERAL_ELSE, 
      TokenTypes.LITERAL_IF, 
     }; 
    } 

    @Override 
    public void visitToken(DetailAST aAST) { 
     final DetailAST slistAST = aAST.findFirstToken(TokenTypes.SLIST); 

     if(aAST.getType() == TokenTypes.LITERAL_ELSE) { 
      // If we have an else, it must have braces, except it is an "else if" (then the if must have braces). 
      DetailAST ifToken = aAST.findFirstToken(TokenTypes.LITERAL_IF); 

      if(ifToken == null) { 
       // This is an simple else, it must have brace. 
       if(slistAST == null) { 
        log(aAST.getLineNo(), "ifBracesElse", aAST.getText()); 
       } 
      } else { 
       // This is an "else if", the if must have braces. 
       if(ifToken.findFirstToken(TokenTypes.SLIST) == null) { 
        log(aAST.getLineNo(), "ifBracesConditional", ifToken.getText(), aAST.getText() + " " + ifToken.getText()); 
       } 
      } 
     } else if(aAST.getType() == TokenTypes.LITERAL_IF) { 
      // If the if uses braces, nothing as to be checked. 
      if (slistAST != null) { 
       return; 
      } 

      // We have an if, we need to check if it has no conditionnal structure as direct child. 
      final int[] conditionals = { 
       TokenTypes.LITERAL_DO, 
       TokenTypes.LITERAL_ELSE, 
       TokenTypes.LITERAL_FOR, 
       TokenTypes.LITERAL_IF, 
       TokenTypes.LITERAL_WHILE, 
       TokenTypes.LITERAL_SWITCH, 
      }; 

      for(int conditional : conditionals) { 
       DetailAST conditionalAST = aAST.findFirstToken(conditional); 

       if (conditionalAST != null) { 
        log(aAST.getLineNo(), "ifBracesConditional", aAST.getText(), conditionalAST.getText()); 

        // Let's trigger this only once. 
        return; 
       } 
      } 
     } 
    } 
} 
0

儘管我同意評論這是一個壞主意,但您可能無法更改準則。所以,你可能想試試這個:

  1. 在CheckStyle的模塊 - >極品牙套,禁用如果關鍵字
  2. 創建模塊的新實例正則表達式 - >RegexpSingleLineJava並設法找到你的無效的病例,但不是你的有效問卷

(模塊吶相匹配的正則表達式mes是來自Eclipse Checkstyle Plugin 5.3.0)

+0

我以爲這樣的東西,但正則表達式不足以處理該規則,即使它可能是解決方案的一部分。 – deadalnix 2011-05-27 09:15:14

+0

Regexp非常強大;)從你的例子中,第二個例子已經失效了,只要for語句需要大括號。第四個例子仍然有效,但我有一個正在工作的正則表達式 - 只是沒有使用checkstyle。也許你可以弄明白:(?s)if。*;。* else – Stephan 2011-05-27 10:14:22

+0

不,這沒有辦法:確保使用正則表達式幾乎不可能存在if中的條件結構,並且各種情況都需要一些邏輯。您的提案將會匹配各種各樣的案例,包括合法使用if。無論如何,我想用一些正則表達式和一些邏輯,可以在這裏管理一些東西。 – deadalnix 2011-05-27 11:13:15

1

只想補充覆蓋某些情況下,現在的CheckStyle支持「allowSingleLineIf」屬性。

<module name="NeedBraces"> 
     <property name="allowSingleLineIf" value="true"/> 
    </module> 
0

CheckStyle的6.14 NeedBracesCheck ROOL支撐allowSingleLineStatement選項

allowSingleLineStatement它允許沒有括號單行語句,例如:

如果(obj.isValid())返回true;

while(obj.isValid())return true;

do this.notify(); while(o!= null);

for(int i = 0;;)this.notify();

documentation