OpenRewrite の AutoFormat レシピで一括コードフォーマットする


はじめに

OpenRewrite の AutoFormat レシピを使ってソースコードを一括整形することができます。

OpenRewrite のレシピは親切なドキュメントが提供されておらず、ソースを見てね という感じなので、OrderImports レシピの使い方を記しておきます。

OpenRewrite については以下を参照してください。

blog1.mammb.com


AutoFormat レシピ

AutoFormat レシピは org.openrewrite.java.format.AutoFormat として提供されています。

type: specs.openrewrite.org/v1beta/recipe
name: com.example.MyFormat
recipeList:
  - org.openrewrite.java.format.AutoFormat

AutoFormat レシピは以下のコードフォーマットを一括で適用します。

スタイル 説明
RemoveTrailingWhitespace 行末スペースの削除
NormalizeLineBreaks 改行の統一
TabsAndIndentsStyle タブ/インデントの整形
BlankLinesStyle 空行数の整形
WrappingAndBracesStyle if文のelse節で改行をいれるかどうか
EmptyForInitializerPadStyle for文の空初期化にスペースを入れるか
EmptyForIteratorPadStyle for文の空イテレータにスペースを入れるか
SpacesStyle 定義箇所にスペースを入れるか


TabsAndIndentsStyle

タブ/インデントのスタイルを定義します。スタイルのデフォルト値は以下のようになっています。

  - org.openrewrite.java.style.TabsAndIndentsStyle:
      useTabCharacter: false
      tabSize: 4
      indentSize: 4
      continuationIndent: 8
      indentsRelativeToExpressionStart: false
      methodDeclarationParameters:
        alignWhenMultiple: true

indentsRelativeToExpressionStart は現在利用されていないため、何を設定しても変化はありません。

methodDeclarationParametersalignWhenMultiple: true がデフォルトになっており、メソッドパラメータを以下のようなスタイルに整形します。

public boolean processRequest(CorsConfiguration config,
                              HttpServletRequest request,
                              HttpServletResponse response) {
}

alignWhenMultiple: false と設定することが多いでしょう。


BlankLinesStyle

空行数のスタイルを定義します。スタイルのデフォルト値は以下のようになっています。

  - org.openrewrite.java.style.BlankLinesStyle:
      keepMaximum:
        inDeclarations: 2
        inCode: 2
        beforeEndOfBlock: 2
        betweenHeaderAndPackage: 2
      minimum:
        beforePackage: 0
        afterPackage: 1
        beforeImports: 3
        afterImports: 1
        aroundClass: 1
        afterClassHeader: 0
        beforeClassEnd: 0
        afterAnonymousClassHeader: 0
        aroundFieldInInterface: 0
        aroundField: 0
        aroundMethodInInterface: 1
        aroundMethod: 1
        beforeMethodBody: 0
        aroundInitializer: 1

各種定義の前後の空白行の数を設定します。多くの場合、デフォルト値のまま利用することになるでしょう。


WrappingAndBracesStyle

if文のelse節で改行をいれるかどうかを定義します。スタイルのデフォルト値は以下のようになっています。

  - org.openrewrite.java.style.WrappingAndBracesStyle:
      ifStatement:
        elseOnNewLine: false

つまり、デフォルトは以下のように整形されます。

if (isFoo) {
    
} else {
    
}

true とした場合は以下のように整形されます。

if (isFoo) {
    
}
else {
    
}


EmptyForInitializerPadStyle

for文の空初期化にスペースを入れるかどうかを定義します。スタイルのデフォルト値は以下のようになっています。

  - org.openrewrite.java.style.EmptyForInitializerPadStyle:
      space: false

デフォルトは for(; i < 10; i++) のように整形されます。 true とした場合は for ( ; i < 10; i++) のように整形されます。


EmptyForIteratorPadStyle

for文の空イテレータにスペースを入れるかどうかを定義します。スタイルのデフォルト値は以下のようになっています。

  - org.openrewrite.java.style.EmptyForIteratorPadStyle
      space: false

デフォルトは for(int i = 0; i < 10;) のように整形されます。 true とした場合は for (int i = 0; i < 10; ) のように整形されます。


SpacesStyle

定義箇所にスペースを入れるかを定義します。スタイルのデフォルト値は以下のようになっています。

  - org.openrewrite.java.style.SpacesStyle:
      beforeParentheses:
        methodDeclaration: false
        methodCall: false
        ifParentheses: true
        forParentheses: true
        whileParentheses: true
        switchParentheses: true
        tryParentheses: true
        catchParentheses: true
        synchronizedParentheses: true
        annotationParameters: false
      aroundOperators:
        assignment: true
        logical: true
        equality: true
        relational: true
        bitwise: true
        additive: true
        multiplicative: true
        shift: true
        unary: false
        lambdaArrow: true
        methodReferenceDoubleColon: false
      beforeLeftBrace:
        classLeftBrace: true
        methodLeftBrace: true
        ifLeftBrace: true
        elseLeftBrace: true
        forLeftBrace: true
        whileLeftBrace: true
        doLeftBrace: true
        switchLeftBrace: true
        tryLeftBrace: true
        catchLeftBrace: true
        finallyLeftBrace: true
        synchronizedLeftBrace: true
        arrayInitializerLeftBrace: false
        annotationArrayInitializerLeftBrace: false
      beforeKeywords:
        elseKeyword: true
        whileKeyword: true
        catchKeyword: true
        finallyKeyword: true
      within:
        codeBraces: false
        brackets: false
        arrayInitializerBraces: false
        emptyArrayInitializerBraces: false
        groupingParentheses: false
        methodDeclarationParentheses: false
        emptyMethodDeclarationParentheses: false
        methodCallParentheses: false
        emptyMethodCallParentheses: false
        ifParentheses: false
        forParentheses: false
        whileParentheses: false
        switchParentheses: false
        tryParentheses: false
        catchParentheses: false
        synchronizedParentheses: false
        typeCastParentheses: false
        annotationParentheses: false
        angleBrackets: false
        recordHeader: false
      ternaryOperator:
        beforeQuestionMark: true
        afterQuestionMark: true
        beforeColon: true
        afterColon: true
      typeArguments:
        afterComma: true
        beforeOpeningAngleBracket: false
        afterClosingAngleBracket: false
      other:
        beforeComma: false
        afterComma: true
        beforeForSemicolon: false
        afterForSemicolon: true
        afterTypeCast: true
        beforeColonInForEach: true
        insideOneLineEnumBraces: false
      typeParameters:
        beforeOpeningAngleBracket: false
        aroundTypeBounds: true

多くの場合、デフォルト値のまま利用することになるでしょう。


AutoFormat で適用されるデフォルトスタイル

以上をまとめると、AutoFormat で適用されるデフォルトスタイルは以下のようになります。

type: specs.openrewrite.org/v1beta/recipe
name: com.example.MyFormat
recipeList:
  - org.openrewrite.java.format.AutoFormat
---
type: specs.openrewrite.org/v1beta/style
name: com.example.MyStyle
styleConfigs:
  - org.openrewrite.java.style.TabsAndIndentsStyle:
      useTabCharacter: false
      tabSize: 4
      indentSize: 4
      continuationIndent: 8
      indentsRelativeToExpressionStart: false
      methodDeclarationParameters:
        alignWhenMultiple: true
  - org.openrewrite.java.style.BlankLinesStyle:
      keepMaximum:
        inDeclarations: 2
        inCode: 2
        beforeEndOfBlock: 2
        betweenHeaderAndPackage: 2
      minimum:
        beforePackage: 0
        afterPackage: 1
        beforeImports: 3
        afterImports: 1
        aroundClass: 1
        afterClassHeader: 0
        beforeClassEnd: 0
        afterAnonymousClassHeader: 0
        aroundFieldInInterface: 0
        aroundField: 0
        aroundMethodInInterface: 1
        aroundMethod: 1
        beforeMethodBody: 0
        aroundInitializer: 1
  - org.openrewrite.java.style.WrappingAndBracesStyle:
      ifStatement:
        elseOnNewLine: false
  - org.openrewrite.java.style.EmptyForInitializerPadStyle:
      space: false
  - org.openrewrite.java.style.EmptyForIteratorPadStyle
      space: false
  - org.openrewrite.java.style.SpacesStyle:
      beforeParentheses:
        methodDeclaration: false
        methodCall: false
        ifParentheses: true
        forParentheses: true
        whileParentheses: true
        switchParentheses: true
        tryParentheses: true
        catchParentheses: true
        synchronizedParentheses: true
        annotationParameters: false
      aroundOperators:
        assignment: true
        logical: true
        equality: true
        relational: true
        bitwise: true
        additive: true
        multiplicative: true
        shift: true
        unary: false
        lambdaArrow: true
        methodReferenceDoubleColon: false
      beforeLeftBrace:
        classLeftBrace: true
        methodLeftBrace: true
        ifLeftBrace: true
        elseLeftBrace: true
        forLeftBrace: true
        whileLeftBrace: true
        doLeftBrace: true
        switchLeftBrace: true
        tryLeftBrace: true
        catchLeftBrace: true
        finallyLeftBrace: true
        synchronizedLeftBrace: true
        arrayInitializerLeftBrace: false
        annotationArrayInitializerLeftBrace: false
      beforeKeywords:
        elseKeyword: true
        whileKeyword: true
        catchKeyword: true
        finallyKeyword: true
      within:
        codeBraces: false
        brackets: false
        arrayInitializerBraces: false
        emptyArrayInitializerBraces: false
        groupingParentheses: false
        methodDeclarationParentheses: false
        emptyMethodDeclarationParentheses: false
        methodCallParentheses: false
        emptyMethodCallParentheses: false
        ifParentheses: false
        forParentheses: false
        whileParentheses: false
        switchParentheses: false
        tryParentheses: false
        catchParentheses: false
        synchronizedParentheses: false
        typeCastParentheses: false
        annotationParentheses: false
        angleBrackets: false
        recordHeader: false
      ternaryOperator:
        beforeQuestionMark: true
        afterQuestionMark: true
        beforeColon: true
        afterColon: true
      typeArguments:
        afterComma: true
        beforeOpeningAngleBracket: false
        afterClosingAngleBracket: false
      other:
        beforeComma: false
        afterComma: true
        beforeForSemicolon: false
        afterForSemicolon: true
        afterTypeCast: true
        beforeColonInForEach: true
        insideOneLineEnumBraces: false
      typeParameters:
        beforeOpeningAngleBracket: false
        aroundTypeBounds: true

methodDeclarationParameters を以下のように変えて整形することが多いと思います。

type: specs.openrewrite.org/v1beta/recipe
name: com.example.MyFormat
recipeList:
  - org.openrewrite.java.format.AutoFormat
---
type: specs.openrewrite.org/v1beta/style
name: com.example.MyStyle
styleConfigs:
  - org.openrewrite.java.style.TabsAndIndentsStyle:
      methodDeclarationParameters:
        alignWhenMultiple: true