2017-07-26 3 views
1

を出すように自動的にJavaのソースコードに未フォーマットが、それでも一見単純なのCheckstyleの問題を修正することができますコマンドラインツールがあります:は自動的に非書式設定を修正しますが、簡単なのCheckstyleは

  • 避けインライン条件文
  • メイク「xxxは「静的メソッド

私は様々なツールがfix formattingにある知っているし、いくつかのIDEはかなりquick fixersを進めてきたが、これまでのところ、私は再帰的にソースコードの折りたたみ上で実行することができる何かを見つけることができませんでしたまたはコミットフックで統合することができます。

+0

EclipseでもCheckstyleの問題を解決できるようです。https://stackoverflow.com/a/8417213/1694043 Eclipseがプロジェクト全体に対してこれを行うようにしたり、この機能を分離してスタンドアロンのツールから実行することは可能かもしれません。 –

答えて

1

いいチャレンジのような音ですが、これを行うための自動ツールも見つけられませんでした。すでに説明したように、コードの書式を変更するには多くのオプションがあります。その他の小さな問題では、おそらくCheckstyleをコマンドラインから実行し、修正可能な警告をフィルタリングすることができます。 Javaソースコードを解析して変更するためのライブラリは、例えばJavaParserのように実際に変更を加えるのに役立ちます。おそらく、JavaParserのようなJavaソースコード操作ツールを使用して、比較的短時間でカスタムツールを書くことができます。

(使用することができANTLRのような他のツールがありますが、スタックオーバーフロー上のより多くのアイデアのためにこの質問を参照してください。Java: parse java source code, extract methodsRoasterJavaPoetのようないくつかのライブラリは、このような状況では、それらはあまり適してメソッドの本体を解析しません。 。

// Example.java: 

package q45326752; 

public class Example { 
    public static void main(String[] arguments) { 
     System.out.println("Hello Checkstyle..."); 

     int perfectNumber = 1 + 2 + 3; 

     System.out.println("Perfect number: " + perfectNumber); 
    } 
} 


Checkstyle warnings: 

java -jar checkstyle-8.0-all.jar -c checkstyle-checks.xml Example.java 
[ERROR] Example.java:4:29: Parameter arguments should be final. [FinalParameters] 
[ERROR] Example.java:7:13: Variable 'perfectNumber' should be declared final. [FinalLocalVariable] 
:)非常に簡単な例として

は、我々はのCheckstyleのみ)FinalParametersチェックしFinalLocalVariable最小限checkstyle-checks.xml Checkstyle構成ファイルを使用して(2つのメッセージを生成するために小さなJavaクラスを持っていると仮定します

JavaParserを使用すると、このような2つの警告が自動的に修正される可能性があります(コードはそのアイデアを実証しようとします。いくつかの部分)は、今では無視されています:

// AutomaticCheckstyleFix.java: 

package q45326752; 

import com.github.javaparser.JavaParser; 
import com.github.javaparser.ast.*; 
import com.github.javaparser.ast.body.*; 
import com.github.javaparser.ast.expr.*; 
import com.github.javaparser.ast.stmt.*; 

import java.io.File; 
import java.io.FileNotFoundException; 

public class AutomaticCheckstyleFix { 
    private MethodDeclaration bestMatchMethod; 
    private int bestMatchMethodLineNumber; 
    private Statement statementByLineNumber; 

    public static void main(final String[] arguments) { 
     final String filePath = "q45326752\\input\\Example.java"; 

     try { 
      new AutomaticCheckstyleFix().fixSimpleCheckstyleIssues(new File(filePath)); 
     } catch (FileNotFoundException e) { 
      e.printStackTrace(); 
     } 
    } 

    private void fixSimpleCheckstyleIssues(File file) throws FileNotFoundException { 
     CompilationUnit javaClass = JavaParser.parse(file); 
     System.out.println("Original Java class:\n\n" + javaClass); 
     System.out.println(); 
     System.out.println(); 

     // Example.java:4:29: Parameter arguments should be final. [FinalParameters] 
     MethodDeclaration methodIssue1 = getMethodByLineNumber(javaClass, 4); 
     if (methodIssue1 != null) { 
      methodIssue1.getParameterByName("arguments") 
        .ifPresent(parameter -> parameter.setModifier(Modifier.FINAL, true)); 
     } 

     // Example.java:7:13: Variable 'perfectNumber' should be declared final. 
     // [FinalLocalVariable] 
     Statement statementIssue2 = getStatementByLineNumber(javaClass, 7); 
     if (statementIssue2 instanceof ExpressionStmt) { 
      Expression expression = ((ExpressionStmt) statementIssue2).getExpression(); 
      if (expression instanceof VariableDeclarationExpr) { 
       ((VariableDeclarationExpr) expression).addModifier(Modifier.FINAL); 
      } 
     } 

     System.out.println("Modified Java class:\n\n" + javaClass); 
    } 

    private MethodDeclaration getMethodByLineNumber(CompilationUnit javaClass, 
                int issueLineNumber) { 
     bestMatchMethod = null; 

     javaClass.getTypes().forEach(type -> type.getMembers().stream() 
       .filter(declaration -> declaration instanceof MethodDeclaration) 
       .forEach(method -> { 
        if (method.getTokenRange().isPresent()) { 
         int methodLineNumber = method.getTokenRange().get() 
           .getBegin().getRange().begin.line; 
         if (bestMatchMethod == null 
           || (methodLineNumber < issueLineNumber 
           && methodLineNumber > bestMatchMethodLineNumber)) { 
          bestMatchMethod = (MethodDeclaration) method; 
          bestMatchMethodLineNumber = methodLineNumber; 
         } 
        } 
       }) 
     ); 

     return bestMatchMethod; 
    } 

    private Statement getStatementByLineNumber(CompilationUnit javaClass, 
               int issueLineNumber) { 
     statementByLineNumber = null; 

     MethodDeclaration method = getMethodByLineNumber(javaClass, issueLineNumber); 
     if (method != null) { 
      method.getBody().ifPresent(blockStmt 
        -> blockStmt.getStatements().forEach(statement 
        -> statement.getTokenRange().ifPresent(tokenRange -> { 
       if (tokenRange.getBegin().getRange().begin.line == issueLineNumber) { 
        statementByLineNumber = statement; 
       } 
      }))); 
     } 

     return statementByLineNumber; 
    } 
} 

別のアプローチは、あなたがのために自動修正を作成しようとしているものに基づいて新しいのCheckstyleプラグインを作成することができます。警告を出すだけでなく、これらの問題が修正された修正バージョンを生成するのに十分な情報があるかもしれません。

個人的に私は、コミット時に自動的に問題が解決されることを躊躇します。多くの簡単な修正がある場合、自動化は歓迎ですが、これらの変更をコミットする前に確認したいと思います。このようなツールを実行して変更を確認すると、非常に簡単な方法で多くの簡単な問題を解決できます。

Iが自動的に修正することができると思ういくつかのチェック:最終

  • ModifierOrder追加:

  • 関連する問題