📖

detektのルール 日本語訳

2023/08/31に公開

はじめに

この記事は、筆者がdetektのルールをカスタムするに当たって、理解するために書き出したものになります。
この記事を見ながら公式ドキュメントを読むと少し楽に読めるかもしれません。

  • detekt.ymlで設定できるルールを書き出しています。
  • セクションタイトルが、そのまま公式の該当場所へのリンクとなっています。
  • 翻訳した上で、概要を噛み砕いて書いております。

https://detekt.dev/

Comments Rule Set

AbsentOrWrongFileLicense

Kotlinのソースファイルが必要なライセンスヘッダーを持っていない場合にそれを報告するものです。

  • licenseTemplate
    ライセンスヘッダーのテンプレートとなるファイルへのパスです。相対パスで指定します。
  • licenseTemplateIsRegex
    licenseTemplateIsRegex = falseまたは設定されていない場合
    入力ファイルのヘッダーが、licenseTemplateFileで指定されたファイルのテキストで始まるかどうかをチェックします。
    licenseTemplateIsRegex = true
    ヘッダーが、licenseTemplateFileで指定されたファイルから生成された正規表現と一致するかどうかをマッチングします。

CommentOverPrivateFunction

private関数に追加されたドキュメント報告します。
private関数は自己説明的でないと行けないので、コメントが追加されているとそれは自己説明的でないということを示しています。
private関数はコメントがなくとも分かるようにしようというルールです。

CommentOverPrivateProperty

privateプロパティに追加されたドキュメント報告します。
CommentOverPrivateFunctionのプロパティ版です。

DeprecatedBlockTag

KDocコメントで@deprecatedタグの使用を報告します。
@deprecatedは非推奨なので@Deprecatedを使うべきです。

EndOfSentenceFormat

KDocコメントの最初の文の終わりを検証します。
正しい句読点で終わるか、正しいURLで終わる必要があります。

  • endOfSentenceFormat
    KDoc の最初の文の末尾に一致する正規表現

KDocReferencesNonPublicProperty

このルールは、クラスのprivateプロパティを参照するKDocコメントを報告します。
クライアントは実装の詳細を知る必要はありません。

OutdatedDocumentation

宣言シグネチャと一致しないKDocを持つクラス、関数、コンストラクタを報告します。
型と値、宣言の順序などが一致しない場合報告します。

  • matchTypeParameters
    型パラメーターが一致するかどうかを検査します。
  • matchDeclarationsOrder
    宣言の順序が一致するかどうかを検査します。
  • allowParamOnConstructorProperties
    クラスのプロパティのKDocで@paramを使用することを許容します。

UndocumentedPublicClass

必要なドキュメントを持たないpublicなクラス、オブジェクト、およびインターフェイスを報告します。
デフォルトでは、このルールはネストされた内部クラスとオブジェクトも検査します。

  • searchInNestedClass
    ネストされたクラスを検索します。
  • searchInInnerClass
    内部クラスを検索します。
  • searchInInnerObject
    内部オブジェクトを検索します。
  • searchInInnerInterface
    内部インターフェイスを検索します。
  • searchInProtectedClass
    保護されたクラスを検索します。

UndocumentedPublicFunction

必要なドキュメントを持たないパブリック関数を報告します。

  • searchProtectedFunction
    保護された関数を検索します。

UndocumentedPublicProperty

必要なドキュメントを持たないパブリック・プロパティを報告します。これには、一次コンストラクタで定義されたパブリックプロパティも含まれます。

  • searchProtectedProperty
    保護された関数を検索します。

Complexity Rule Set

CognitiveComplexMethod

このルールは、Sonasource の Cognitive Complexity メトリックを通してメソッドの複雑さを測定し、制限します。

  • threshold
    報告されるのに必要なメソッドの認知的複雑度を指定します。
    数値が小さいほど厳格になります
    この複雑度の計算方法は以下のステートメントがでてくるごとに+1されます。
    またifwhenなどのネストが発生するたびに+1されます。
    if, when, for, while, do while, catch,
    labeled break, labeled continue, labeled return, recursion call, &&, ||
    
    以下の例ですと、合計の複雑度は6になります。
    if (a) {              // +1
        if (b) {          // +2 (ifで+1、ネストで+1)される
            while (c) {   // +3 (ifで+1、2つ目のネストのため+2)
                // do something
            }
        }
    }
    

ComplexCondition

複雑な条件では、どのような場合にその条件が真になるのか、あるいは偽になるのかを理解するのが難しくなります。
複雑な条件を読みやすく理解しやすくするために、適切な名前のついた関数や変数に抽出し、代わりにそれらを呼び出すことが求められます。

  • threshold
    報告されるのに必要な条件の数を指定します。

ComplexInterface

インターフェイスの複雑度度を検査します。
インターフェイスは単一責任の原則に従うべきです。

  • threshold
    報告されるのに必要なインターフェイス内の定義の数のを指定します。
  • includeStaticDeclarations
    静的宣言を含めます。
  • includePrivateDeclarations
    プライベート宣言を含めます。
  • ignoreOverloaded
    オーバーロードされたメソッドを無視します。

CyclomaticComplexMethod

このルールは、McCabe の循環複雑性 (MCC) メトリックを使用して、関数のソース コード (https://www.ndepend.com/docs/code-metrics#CC) を通る線形独立パスの数を測定します。独立したパスの数が増えるほど、メソッドはより複雑になります。よくある複雑なメソッドでは、次のステートメントが多く含まれています。それぞれの複雑さのカウントに 1 が追加されます。

線形独立パスとは、例えばifなどで条件ごとに生まれる異なる経路のことです。
以下のステートメントで複雑度が計算されます。

Conditional statements - if, else if, when
Jump statements - continue, break
Loops - for, while, do-while, forEach
Operators &&, ||, ?:
Exceptions - catch, use
Scope Functions - let, run, with, apply, and also -> Reference
  • threshold
    報告されるのに必要なメソッドの循環複雑度を指定します。
  • ignoreSingleWhenExpression
    複雑なメソッドに when 式が 1 つしか含まれていない場合は、複雑度の計算に含めないようにします。
  • ignoreSimpleWhenEntries
    ↓単純 (括弧なし) エントリを複雑度の計算に含めないようにします。
    if (isFlag) doSomething()
    
  • nestingFunctions
    複雑さを増す関数名のカンマ区切りリストです。
    おそらく計算に含めるかどうかをリストするものだと思います。

LabeledExpression

ラベル付きの式を報告します。
Kotlin では内部クラスから外部クラスのインスタンスを取得する方法がないため、内部クラスのラベルを使用して外部クラスを参照するラベル付き式は許可されます。

  • ignoredLabels
    このルールで無視されるラベル名のリストを指定できます。

LargeClass

大規模なクラスを報告します。通常、クラスは 1 つの責任を負う必要があります。大規模なクラスは、そのクラスが複数の責任を代わりに処理していることを示している可能性があります。

  • threshold
    報告されるのに必要なクラスの行数を指定します。

LongMethod

大きなメソッドを報告します。
メソッドが長い場合は、メソッドが一度に処理するケースが多すぎることを示している可能性があります。

  • threshold
    報告されるのに必要なメソッドの行数を指定します。

LongParameterList

指定数値以上のパラメータを持つ関数やコンストラクタを報告します。

  • functionThreshold
    報告されるのに必要な関数のパラメータの数を指定します
  • constructorThreshold
    報告されるのに必要なコンストラクタのパラメータの数を指定します
  • ignoreDefaultParameters
    デフォルト値を持つパラメータを無視する
    true 検査に含めない。
    false 検査に含める。
    fun exampleMethod(id: String = "1")
    
  • ignoreDataClasses
    データクラスの長いコンストラクターパラメータリストを無視します。
    true 検査に含めない。
    false 検査に含める。
  • ignoreAnnotatedParameter
    カウントの注釈付きパラメータを無視します (例: fun foo(@Value bar: Int) はカウントされません)

MethodOverloading

頻繁にオーバーロードされるメソッドを報告します。メソッドのオーバーロードでは、これらのメソッドが緊密に結合されるため、コードが理解しにくくなる可能性があります。

  • threshold
    報告されるのに必要なオーバーロードの数を指定します。

NamedArguments

指定値より多くの引数を持ち、名前付きでない関数の呼び出しを報告します。
引数が多すぎる呼び出しは理解するのが難しいので、名前付き引数は助けになります。

  • threshold
    報告されるのに必要な、名前付きでない引数の数を指定します。
  • ignoreArgumentsMatchingNames
    引数の値がパラメータ名と同じ場合は無視します。

NestedBlockDepth

関数内の過剰なネストの深さを報告します。コードが過度にネストされていると、読みにくくなり、隠れた複雑さが増大します。

  • threshold
    報告されるのに必要なネストの深さを指定します。

NestedScopeFunctions

スコープ関数はコードをより簡潔にする方法ですが、過度に使用しないでください。コードの可読性が低下し、エラーが発生する可能性があります。

  • threshold
    許可される、ネストされたスコープ関数の数を指定します。
  • functions
    ルールが適用されるスコープ関数を指定します。

ReplaceSafeCallChainWithRun

null安全のチェックを行う?.(セーフコール)は、非null型に対して連続して使用するのは冗長です。その場合にrun{}を使うことを提案します。

StringLiteralDuplication

重複した文字列リテラルを検出して報告します。

  • thresholds
    報告されるのに必要な重複の数を指定します。
  • ignoreAnnotations
    注釈の値を無視する場合に有効にします。
  • excludeStringsWithLessThan5Characterss
    5文字未満の文字列を除外します。
  • ignoreStringsRegexs
    無視すべき文字列の正規表現を指定します。

TooManyFunctions

沢山の関数を含むファイル、クラス、インターフェイス、オブジェクト、列挙型を報告します。

  • 報告されるのに必要な関数の数
    thresholdInFiless = ファイル
    thresholdInClassess = クラス
    thresholdInInterfacess = インターフェイス
    thresholdInObjectss = オブジェクト
    thresholdInEnumss = Enum

  • ignoreDeprecated
    非推奨の関数を無視します。

  • ignoreDeprecated
    プライベートの関数を無視します。

  • ignoreDeprecated
    オーバーロードされた関数を無視します。

Coroutines Rule Set

GlobalCoroutineUsage

GlobalScope.launch および GlobalScope.async の使用を報告します。
上記の2つはKotlinで非推奨になっています。

InjectDispatcher

テストを容易にするために、ディスパッチャを注入するには常に依存性注入を使用してください。
このルールは、coroutines-best-practices#inject-dispatcher の推奨事項に基づいています。

  • dispatcherNames
    このルールで検出するディスパッチャの名前を指定します。

RedundantSuspendModifier

suspend修飾子は必要な場合のみ使用すべきであり、そうでなければその関数は他のサスペンド関数からしか使用できません。
これは不必要に関数の使用を制限してしまうので、必要ない場所ではsuspend修飾子を削除して避けるべきです。

SleepInsteadOfDelay

関数とコルーチン・ブロックのサスペンドにおけるThread.sleepの使用法を報告します。
コルーチンは軽量であるため、スレッドには一度に複数のコルーチンを含めることができます。
そのため、1つのコルーチンがThread.sleepを呼び出すと、無関係なコルーチンの実行が停止し、予測不可能な動作を引き起こす可能性があります。

SuspendFunSwallowedCancellation

suspend関数は、runCatchingのラムダ・ブロックの中では呼ばないでください。
コルーチンがすべてのケースで機能するためには、開発者はCancellationException例外を伝播するようにしなければなりません。
runCatching を使用すると、キャンセルを誤って処理するリスクが高まります。
すべての CancelException をキャッチして再スローしない場合、CoroutineScope をキャンセルしてもコルーチンはキャンセルされません。

SuspendFunWithCoroutineScopeReceiver

CoroutineScopeをレシーバーとして使用するサスペンド関数は、サスペンドとしてマークされるべきではありません。
CoroutineScope は coroutineContext を介して構造化された同時実行を提供します。

SuspendFunWithFlowReturnType

SuspendFunWithFlowReturnType kotlinx.coroutines.flow からフローを返す関数は、サスペンドとしてマークしないでください。

Empty-blocks Rule Set

EmptyCatchBlock

空の catch ブロックを報告します。
空の catch ブロックは、例外が無視され、処理されないことを示します。

  • allowedExceptionNameRegex
    この正規表現に一致する例外タイプを無視します。

EmptyClassBlock

空のクラスを報告します。

EmptyDefaultConstructor

空のデフォルトコンストラクターを報告します。

EmptyDoWhileBlock

空の do/while ループを報告します。

EmptyElseBlock

空のelseブロックを報告します。

EmptyFinallyBlock

空のfinallyブロックを報告します。

EmptyForBlock

空の for ループを報告します。

EmptyFunctionBlock

空の関数を報告します。
このルールは、本体内容のみがコメントである override 修飾子を持つ関数 (未使用のリスナー関数の // no-op コメントなど) はレポートしません。

  • ignoreOverridden
    オーバーライドされた関数をすべて除外します。

EmptyIfBlock

からのifブロックを報告します。

EmptyInitBlock

空のinitを報告します。

EmptyKtFile

空の Kotlin (.kt) ファイルを報告します。

EmptySecondaryConstructor

空の二次コンストラクターを報告します。

EmptyTryBlock

空の try ブロックを報告します。

EmptyWhenBlock

空の when 式を報告します。

EmptyWhileBlock

空の while 式を報告します。

Exceptions Rule Set

ExceptionRaisedInUnexpectedLocation

このルールは、例外をスローすべきではない関数を報告します。

  • methodNames
    例外をスローすべきでないメソッドを指定します。

InstanceOfCheckForException

チェックまたはキャストによって例外のタイプをチェックする catch ブロックを報告します。

NotImplementedDeclaration

このルールは、スローされた NotImplementedError タイプのすべての例外を報告します。

ObjectExtendsThrowable

このルールは、Throwableを拡張したコンパニオンオブジェクトを含む全てのオブジェクトを報告します。
Throwable インスタンスはステートフルであり、特定の例外やエラーに関する変更可能な情報を含んでいるため、再利用を意図したものではありません。

PrintStackTrace

このルールは、例外のスタックトレースを出力しようとするコードを報告します。
単純にスタックトレースを出力するのではなく、より優れたロギング ソリューションを使用する必要があります。

RethrowCaughtException

キャッチされ、その後変更せずに再スローされたすべての例外を報告します。
大文字と小文字の区別は無視されます。

ReturnFromFinally

finallyブロック内のreturn文をすべて報告します。
finally ブロックで return 文を使用すると、try ブロックでスローされた例外を破棄して隠すことができます。
さらにこのルールは、対応する try が式として使用されている場合、finally ブロックからの値を報告します。

SwallowedException

例外がキャッチされ、新しくスローされた例外に正しく渡されなかったすべてのインスタンスを (原因としてなど) 報告します。

  • ignoredExceptionTypes
    無視する必要がある例外タイプ (catch 句と本体の両方)を指定します。
  • allowedExceptionNameRegex
    この正規表現に一致する汎用すぎる例外タイプを無視します。

ThrowingExceptionFromFinally

このルールは、finally ブロックから例外がスローされるすべてのケースを報告します。
混乱や例外の破棄につながる可能性があるため、finally ブロックから例外をスローすることは避けてください。

ThrowingExceptionInMain

main メソッドでスローされたすべての例外を報告します。

ThrowingExceptionsWithoutMessageOrCause

引数や詳細な説明なしでスローされたすべての例外を報告します。
例外は常にコンストラクター オーバーロードの 1 つを呼び出して、メッセージまたは原因を提供する必要があります。

  • exceptions
    メッセージや原因なしにスローされるべきでない例外を指定します。

ThrowingNewInstanceOfSameException

例外を同じ例外タイプ内にラップして再スローしないでください。

TooGenericExceptionCaught

汎用すぎる型を持つ例外の catch ブロックを報告します。
現在処理されているケースに対する特定の例外をキャッチすることを優先する必要があります。

  • exceptionNames
    捕捉すべきでない例外を指定します。
  • allowedExceptionNameRegex
    この正規表現に一致する汎用すぎる例外タイプを無視します。

TooGenericExceptionThrown

汎用すぎる型を持つスローされた例外を報告します。
現在発生しているケースに対しては、特定の例外をスローすることが望ましいはずです。

  • exceptionNames
    スローすべきではない例外を指定します。

Naming Rule Set

BooleanPropertyNaming

指定された命名規則に従っていないBooleanプロパティ名を報告します。

  • allowedPattern
    プロパティ名のパターンを指定します。

ClassNaming

指定された命名規則に従っていないクラス名またはオブジェクト名を報告します。

  • classPattern
    クラス名のパターンを指定します。

ConstructorParameterNaming

指定された命名規則に従っていないコンストラクター パラメーター名を報告します。

  • parameterPattern
    コンストラクター パラメーター名を指定します。
  • privateParameterPattern
    プライベートコンストラクターパラメーター名を指定します。
  • excludeClassPattern
    この正規表現に一致するクラス内の変数を無視します。

EnumNaming

指定された命名規則に従っていない列挙(Enum)名を報告します。

  • enumEntryPattern
    列挙(Enum)名のパターンを指定します。

ForbiddenClassName

構成ごとに禁止されているクラス名を報告します。

  • forbiddenName
    禁止するクラス名を指定します。

FunctionMaxLength

非常に長い関数名が使用されている場合に報告します。

  • maximumFunctionNameLength
    最大の関数名の長さを指定します。

FunctionMinLength

非常に短い関数名が使用されている場合に報告します。

  • minimumFunctionNameLength
    最小の関数名の長さを指定します。

FunctionNaming

指定された命名規則に従っていない関数名を報告します。

  • functionPattern
    関数の命名規則を指定します。
  • excludeClassPattern
    この正規表現に一致するクラス内の関数を無視します。

FunctionParameterNaming

指定された命名規則に従っていない関数パラメータ名を報告します。

  • parameterPattern
    パラメータの命名規則を指定します。
  • excludeClassPattern
    この正規表現に一致するクラス内の変数を無視します。

InvalidPackageDeclaration

ファイルの場所が宣言されたパッケージと一致しない場合に報告します。

  • rootPackage
    指定した場合、パッケージ構造のこの部分は無視されます。
  • requireRootInDeclaration
    指定された rootPackage で始まる宣言が必要です。

LambdaParameterNaming

指定された命名規則に従っていないラムダ パラメーター名を報告します。

  • parameterPattern
    ラムダパラメーター名の命名規則を指定します。

MatchingDeclarationName

Kotlinファイルにプライベートでないクラスが1つだけ含まれる場合(関連するトップレベル宣言が含まれる可能性がある)、ファイル名とクラス名が違う場合に報告されます。

  • mustBeFirst
    名前は、ファイルがクラスまたはオブジェクトで始まる場合にのみチェックされます。

MemberNameEqualsClassName

クラスまたはオブジェクトと同じ命名のメンバを報告します。

  • ignoreOverridden
    オーバーライドされた関数やプロパティを無視します。

NoNameShadowing

シャドウイング変数宣言を報告します。
以下のような場合です。

fun test(i: Int, j: Int, k: Int) {
    val i = 1

NonBooleanPropertyPrefixedWithIs

「is」プレフィックスが付いたプロパティがBoolean型でない場合に報告します。

ObjectPropertyNaming

指定された命名規則に従っていないオブジェクト内のプロパティ名を報告します。

  • constantPattern
    定数の命名規則を指定します。
  • propertyPattern
    プロパティの命名規則を指定します。
  • privatePropertyPattern
    プライベートプロパティの命名規則を指定します。

PackageNaming

指定された命名規則に従っていないパッケージ名を報告します。

  • packagePattern
    パッケージの命名規則を指定します。

TopLevelPropertyNaming

指定された命名規則に従っていない最上位の定数を報告します

  • constantPattern
    最上位の定数の命名規則を指定します。
  • propertyPattern
    最上位のプロパティの命名規則を指定します。
  • privatePropertyPattern
    最上位のプライベートプロパティの命名規則を指定します。

VariableMaxLength

非常に長い変数名が使用されている場合に報告します。

  • maximumVariableNameLength
    変数名の最大の長さを指定します。

VariableMinLength

非常に短い変数名が使用されている場合に報告します。

  • minimumVariableNameLength
    変数名の最小の長さを指定します。

VariableNaming

指定された命名規則に従っていない変数名を報告します。

  • variablePattern
    変数の命名規則を指定します。
  • privateVariablePattern
    プライベート変数の命名規則を指定します。
  • excludeClassPattern
    この正規表現に一致するクラス内の変数を無視します。

Performance Rule Set

ArrayPrimitive

Array<Primitive>を報告します。
暗黙のボックス化が起こり、パフォーマンスが低下します。

- fun example(array: Array<Int>)
+ fun example(array: IntArray)

CouldBeSequence

コレクション操作の長いチェーンを報告します。
これは呼び出すたびに新しいリストが作成されるため、パフォーマンスが低下します。

  • threshold
    報告されるのに必要なコレクション操作の数を指定します。

ForEachOnRange

Rangeに対してforEachを使用すると報告します。
単純な for ループと比較してパフォーマンスが大幅に低下する可能性があります。

SpreadOperator

スプレッド演算子を使用すると報告します。
スプレッド演算子を使用すると、ほとんどの場合、メソッドを呼び出す前に配列の完全なコピーが作成されます。これにより、パフォーマンスの低下が大きくなります。

UnnecessaryPartOfBinaryExpression

不必要なバイナリ式を報告します。
if および when 条件を含むすべてのバイナリ式で機能します。

UnnecessaryTemporaryInstantiation

プリミティブ型をStringに変換する際に、一時的なオブジェクトを使用すると報告します。

- val number = 123
- val numberToString = Integer(number).toString()

+ val number = 123
+ val numberToString = number.toString()

Potential-bugs Rule Set

AvoidReferentialEquality

StringListなどで参照等価性のチェックを行われた場合に報告します。
=== オペレータを使用すると、2つのオブジェクトが同じ参照(つまり、メモリ上の同じ位置)を指しているかどうかを確認します。
しかし、メモリ上で同じ位置にあるかどうかは保証されません。
予測しない結果が返される可能性があるので使用は控えるべきです。

  • forbiddenTypePatterns
    参照等価性チェックがルール違反とみなされる型を指定します。

CastNullableToNonNullableType

null 許容変数を null 以外の型にキャストしたときに報告します。

CastToNullableType

null 許容型への安全でないキャストを報告します。

Deprecation

非推奨の要素を報告します。

DontDowncastCollectionTypes

kotlin.collections から不変型をダウンキャストするときに報告します。

DoubleMutabilityForCollection

可変コレクションまたは値ホルダーを宣言するときに var を使用すると報告します。
これは二重可変性が生じます。
代わりに、変数を val で宣言するか、不変型を使用するように宣言を切り替えることを検討してください。

  • mutableTypes
    var で定義したときに報告する可変タイプのリストを定義します。

ElseCaseInsteadOfExhaustiveWhen

完全なケースのセットがあるにもかかわらず、else ケースを含む式を報告します。
これは、 when 式の主語が enum クラス、sealed クラス、または boolean 型の場合に発生します。
主語をもつとは、評価する値をもつwhen(x)のときのことです。

  • ignoredSubjectTypes
    主語を持つ式で無視されるべき完全修飾型のリストを指定します。

EqualsAlwaysReturnsTrueOrFalse

常に true または false を返すquals() メソッドを報告します。

EqualsWithHashCodeExist

クラスがequals()メソッドをオーバーライドした場合、hashCode()メソッドをオーバーライドしていないと報告します。

ExitOutsideMain

System.exit()、Runtime.exit()、Runtime.halt()、KotlinのexitProcess()がmain関数の外部で使用されている場合に報告します。

ExplicitGarbageCollectionCall

ガベージ コレクターを明示的にトリガーするすべての呼び出しを報告します。

HasPlatformType

パブリックAPIでプラットフォーム型を明示的に宣言していない場合に報告します。
予期せぬエラーを防ぐため、型を明示するべきです。

IgnoredReturnValue

このルールは、@CheckReturnValue または @CheckResult のいずれかの注釈が付けられた関数が値を返しても、その値がまったく使用されないインスタンスに対して警告します。

  • restrictToConfig
    設定に一致するメソッドのみをチェックするか、すべてのメソッドをチェックする必要があるかを指定します。
  • returnValueAnnotations
    検査注釈として使用するグロブパターンのリストを指定します。
  • ignoreReturnValueAnnotations
    報告されない注釈を指定します。
  • returnValueTypes
    報告されない戻り値の型のリストを指定します。
  • ignoreFunctionCall
    報告されない関数シグネチャのリストを指定します。

ImplicitDefaultLocale

文字列をフォーマットしたり大文字と小文字を変換したりする場合に[java.util.Locale] を明示的に渡すしていない場合に報告します。

ImplicitUnitReturnType

式を返り値とした関数で、返り値の型を明示的にしていない場合に報告します。

  • allowExplicitReturnType
    明示的な Unit 戻り型を持つ関数を許可します。

InvalidRange

無効なRange型を報告します。
10..9のように無効な場合に報告します。

IteratorHasNextCallsNextMethod

Iterator インターフェースのhasNext()内で、Iteratorのnext()を呼び出した場合に報告します。

IteratorNotThrowingNoSuchElementException

next() メソッドの実装で NoSuchElementException をスローしない Iterator インターフェイスの実装を報告します。

LateinitUsage

lateinit 修飾子の使用を報告します。

  • ignoreOnClassesPattern
    クラスのリストに対してルールを無効にすることができます。

MapGetWithNotNullAssertionOperator

null 以外のアサーション演算子 !! を使用したmap アクセス メソッド、map[] または map.get() の呼び出しを報告します。

MissingPackageDeclaration

パッケージ宣言が欠落している場合に報告します。

NullCheckOnMutableProperty

if ステートメントの実行後にこれらのプロパティの値が変更される可能性があるため、変更可能なプロパティの null チェックを報告します。

- if (x ! = null) print(x!!)
+ if (x ! = null) print(x)

NullableToStringCall

nullを返す可能性のある null 許容レシーバーを使用した toString() 呼び出しを報告します。

var a: Int?
- a.toString()
+ a.toString() ?: "a"

PropertyUsedBeforeDeclaration

宣言前に使用されるプロパティを報告します。

UnconditionalJumpStatementInLoop

条件に関係なくジャンプするジャンプ ステートメントを含むループを報告します。
以下のような場合です。

- for (i in 1..10) break

UnnecessaryNotNullCheck

requireNotNull または checkNotNull を使用した不要な not-null チェックを報告します。

UnnecessaryNotNullOperator

不要な非 null 演算子の使用 !! を報告します。

UnnecessarySafeCall

不要な安全な呼び出し演算子 ?. を報告します。

UnreachableCatchBlock

到達できない catch ブロックを報告します。

UnreachableCode

到達不能なコードを報告します。

UnsafeCallOnNullableType

null 許容型での安全でない呼び出しを報告します。

UnsafeCast

成功しないキャストを報告します。

- print("hello" as Int)

UnusedUnaryOperator

未使用の単項演算子を報告します。

UselessPostfixExpression

未使用の不要な後置式 (++、--) を報告します。

WrongEqualsTypeParameter

Any?以外のパラメーターを受け取る、equals() メソッドを報告します。

Style Rule Set

AlsoCouldBeApply

also ブロックに it-started 式のみが含まれているときに報告します。

BracesOnIfStatements

指定されたルールに準拠しない if ステートメントを報告します。

  • singleLine
    一行でifを書く場合に報告するルールを指定します。
  • multiLine
    複数行でifを書く場合に報告するルールを指定します。

以下設定値です。コード例は公式を御覧ください。
always -> すべてにおいて中括弧を強制します。
consistent -> 中括弧をつけるか、つけないかを一貫させます。
necessary -> 複数のステートメントが入る場合を除いて、中括弧をつけません。
never -> どのような場合にも中括弧をつけません。

BracesOnWhenStatements

指定されたルールに準拠しない when ステートメントを報告します。

  • singleLine
    一行でwhenを書く場合に報告するルールを指定します。
  • multiLine
    複数行でwhenを書く場合に報告するルールを指定します。

以下設定値です。コード例は公式を御覧ください。
never -> どのような場合にも中括弧をつけません。
need -> 複数のステートメントが入る場合を除いて、中括弧をつけません。
consistent -> 中括弧をwhen内でつけるか、つけないかを一貫させます。
always -> すべてにおいて中括弧を矯正します。

CanBeNonNullable

null許容型で宣言された変数を報告する。

CascadingCallWrapping

メソッドのチェインで1つ前の呼び出しが新しい行にある場合、それに続くすべての呼び出しが新しい行に配置されていないときに報告します。

  • includeElvis
    末尾のelvis式を改行で折り返す必要があります。

ClassOrdering

Kotlin コーディング規約で推奨されているように、クラスのコンテンツが次のように順序付けされるようになります。

  1. プロパティ宣言とイニシャライザー・ブロック
  2. 二次コンストラクタ
  3. メソッド宣言
  4. コンパニオン・オブジェクト

CollapsibleIfStatements

折りたたむことができる if ステートメントを検出します。

DataClassContainsFunctions

変換関数としてマークされていないデータクラス内の関数を報告します。
オブジェクト間の変換を支援する関数以外の余分な関数を含めるべきではないことを前提としています。

  • conversionFunctionPrefix
    許可される変換関数名を指定します。
  • allowOperatorss
    演算子のオーバーロードを許可します

DataClassShouldBeImmutable

データ クラス内の変更可能なプロパティを報告します。
データクラス内のプロパティは不変である必要があります。

DestructuringDeclarationWithTooManyEntries

エントリが多すぎる分割宣言を報告します。

  • maxDestructuringEntries
    最大宣言数を指定します。

DoubleNegativeLambda

二重の否定を含むラムダブロック(例:takeUnlessの中での否定)を報告します。
二重否定は可読性が下がります。

  • negativeFunctions
    二重否定を形成する可能性がある否定形で表現された関数名を指定します。
  • negativeFunctionNameParts
    ラムダに負の値が含まれているかどうかを判断するときに、ラムダブロック内で検索する関数名の部分指定です。

EqualsNullCall

値と null を比較するために、equals() メソッドが使用されているコード内のインスタンスを検出し、報告します。

EqualsOnSignatureLine

式スタイル関数の等号が関数シグネチャと同じ行にない場合を報告します。

ExplicitCollectionElementAccessMethod

mapやlistの要素へのアクセスや挿入で、getやsetメソッドの代わりにインデックスアクセス演算子[]を使用していない場合を報告します。

ExplicitItLambdaParameter

大きなまたはネストされたコード内で、暗黙的なitパラメータのみを使用して意味が不明確になるラムダ式を報告します。

ExpressionBodySyntax

return ステートメントのみを含む関数を報告します。

ForbiddenAnnotation

許可されていないアノテーションの使用を報告します。

  • annotations
    禁止するアノテーションを指定します。

ForbiddenComment

問題のあるコードコメントを報告します。

  • comments
    禁止する文字列を指定します。
  • allowedPatterns
    指定された正規表現に一致するコメントを無視します。

ForbiddenImport

禁止されているすべてのimportを報告します。

  • imports
    禁止するimportを指定します。
  • forbiddenPatterns
    指定された正規表現にマッチするインポートを報告します。

ForbiddenMethodCall

禁止されているすべてのメソッドまたはコンストラクターの呼び出しを報告します。

  • methods
    禁止するメソッドの完全修飾シグネチャを指定します。

ForbiddenSuppress

禁止されたSuppressを使用した場合に報告します。

  • rules
    禁止するSuppressを指定します。

ForbiddenVoid

Void の使用を検出し、報告します。
KotlinではUnitを使用する必要があります。

  • ignoreOverridden
    オーバーライドされた関数を無視します。
  • ignoreUsageInGenerics
    ジェネリックの引数としてのvoidタイプを無視します。

FunctionOnlyReturningConstant

単一の定数だけを返す関数を報告します。
代わりに、定数をconst valとして宣言することをお勧めします。

  • ignoreOverridableFunction
    オーバーライドされた関数を無視します。
  • ignoreActualFunction
    実際の関数を無視します。
  • excludedFunctions
    無視する関数を指定します。

LoopWithTooManyJumpStatements

複数のbreakまたはcontinue文を含むループを報告します。

  • maxJumpCount
    ループ内で許可される最大ジャンプ数を指定します。

MagicNumber

コード内のマジック ナンバーの使用を検出して報告します。

  • ignoreNumbers
    マジックナンバーとしてカウントされない数字を指定します。
  • ignoreHashCodeFunction
    ハッシュコード関数を無視します。
  • ignorePropertyDeclaration
    プロパティ宣言内のマジックナンバーを無視します。
  • ignoreLocalVariableDeclaration
    ローカル変数宣言内のマジックナンバーを無視します。
  • ignoreConstantDeclaration
    定数宣言内のマジックナンバーを無視します。
  • ignoreCompanionObjectPropertyDeclaration
    コンパニオンオブジェクト宣言内のマジックナンバーを無視します。
  • ignoreAnnotation
    アノテーションのマジックナンバーを無視します。
  • ignoreNamedArgument
    名前付き引数内のマジックナンバーを無視します。
  • ignoreEnums
    列挙型のマジックナンバーを無視します。
  • ignoreRanges
    Rangeのマジックナンバーを無視します。
  • ignoreExtensionFunctions
    拡張関数の対象としてのマジックナンバーを無視します。

MandatoryBracesLoops

中括弧のない複数行の for および while ループを報告します。

MaxChainedCallsOnSameLine

一行に配置できるチェーン呼び出しの数を報告します。

  • maxChainedCalls
    一行で許可されるチェーンコール数を指定します。

MaxLineLength

定義された一行の最大文字数を超えるコード行を報告します。

  • maxLineLength
    一行の最大の文字数を指定します。
  • excludePackageStatements
    パッケージステートメントを無視します。
  • excludeImportStatements
    importステートメントを無視します。
  • excludeCommentStatements
    コメントを無視します。
  • excludeRawStrings
    文字列を無視します。

MayBeConst

const val として宣言可能な val プロパティを報告します。

ModifierOrder

コード内で修飾子が正しい順序ではないケースを報告します。

- lateinit internal val str: String
+ internal lateinit val str: String

MultilineLambdaItParameter

複数のステートメントを含むラムダで「it」を使わずに明確なパラメータ名を指定しないコードを報告します。

MultilineRawStringIndentation

複数行の生の文字列のインデントが一貫していない場合を報告します。

  • indentSize
    インデントのサイズを指定します。
  • trimmingMethod
    複数行の文字列をトリミングするメソッドのリストを指定します。

NestedClassesVisibility

内部クラスのネストされたクラスで不要な公開修飾子を使用している場合を報告します。

NewLineAtEndOfFile

ファイルの最後が空白行でない場合に報告します。

NoTabs

Kotlin ファイルでタブが使用されていると報告します。

NullableBooleanCheck

== ではなく elvis 式 ?: を使用する、null 許容のBoolean値チェックを報告します。

ObjectLiteralToLambda

単一のメソッドのみを実装する匿名オブジェクトをラムダとして使用していない場合に報告します。

OptionalAbstractKeyword

不要で削除できる抽象修飾子を報告します。

OptionalUnit

関数にUnitの返り値を明示的に指定する、または単独のUnit文を使用する場合を報告します。
オーバーライドされた no-op 関数は許可されます。

PreferToOverPairSyntax

値のペアを作成するための、Pair コンストラクターを使用している場合に報告します。

ProtectedMemberInFinalClass

Kotlinのデフォルトでfinalなクラスがprotectedなメンバーを持つ場合に報告します。

RedundantExplicitType

推論される型が明示的な型と一致するときに、ローカルプロパティで型を明示的にしている場合に報告します。

RedundantHigherOrderMapUsage

コードに複雑さを追加し、何もしない冗長なmapがある場合に報告します。

RedundantVisibilityModifierRule

冗長な可視性修飾子を報告します。

ReturnCount

関数内に多数のreturn文が存在すると、コードの可読性に影響を与えるため、その場合に報告します。

  • max
    関数ごとに許可される return ステートメントの最大数を定義します。
  • excludedFunctions
    無視される関数名のリストを定義します。
  • excludeLabeled
    ラベル付きのreturn文は無視されます。
  • excludeReturnFromLambda
    ラムダからのラベル付きreturnは無視されます。
  • excludeGuardClauses
    メソッドの最初の部分での「true」を条件とする早期リターンを無視します。

SafeCast

安全なキャストに置き換え可能なキャストを使用している場合に報告します。

SerialVersionUIDInSerializableClass

Serializableインターフェースを実装するクラスが正しいprivateなserialVersionUIDを宣言していない場合に報告します。

SpacingBetweenPackageAndImports

パッケージとインポート文、またインポート文とクラス宣言の間の行間が不適切な場合に報告します。

StringShouldBeRawString

エスケープ文字がKotlinの生文字列に変換できる場合に報告します。

  • maxEscapedCharacterCount
    許可される最大エスケープ文字を指定します。
  • ignoredCharacters
    無視する文字を指定します。

ThrowsCount

多数のthrow文を持つ関数を報告します。

  • max
    許可される最大のthrowステートメントを指定します。
  • excludeGuardClauses
    ガード句を無視します。

TrailingWhitespace

末尾の空白を無視します。

TrimMultilineRawString

複数行の文字列がtrimMargin()やtrimIndent()で続かない場合に報告します。

  • trimmingMethods
    複数行の文字列トリミング方法を指定します。

UnderscoresInNumericLiterals

10進数の長い数字がアンダースコアで区切られていない場合に報告します。

  • acceptableLength
    許可される最大の桁数を指定します。
  • allowNonStandardGrouping
    false -> 3桁区切りを強制します。
    true -> どこで区切っても報告されません。

UnnecessaryAbstractClass

抽象クラスが具象メンバを持たない場合や、抽象メンバを定義していない抽象クラスを報告します。

UnnecessaryAnnotationUseSiteTarget

Annotationのuse-site Targetが不要な場合に報告します。

UnnecessaryApply

apply式が頻繁に使用されるときに、視覚的な複雑さを減少させるために通常のメソッドや拡張関数の呼び出しに置き換えるべき場合に報告します。

UnnecessaryBackticks

不要なバッククォートを報告します。

UnnecessaryBracesAroundTrailingLambda

関数の最後のラムダパラメーターが関数である場合、対応する引数として渡されるラムダ式をかっこの外側に配置できる場合に報告します。

UnnecessaryFilter

不必要なfilterを報告します。

UnnecessaryInheritance

不要なスーパータイプを報告します。
Any または Object からの継承は不要なので、削除する必要があります。

UnnecessaryInnerClass

不要な内部クラスを報告します。

UnnecessaryLet

let式がnullチェックや関数の連鎖のために頻繁に使用されている場合、その使用が視覚的な複雑さを増すことがあるため、通常のメソッドや拡張関数の呼び出しに置き換えるべき場合に報告します。

UnnecessaryParentheses

式の周囲にある不要な括弧を報告します。

UntilInsteadOfRangeTo

範囲演算子 '..' の代わりに 'until' 関数の呼び出しを使用すべき場合に報告します。
0 から 9の場合には0 .. 10 - 1ではなく、0 until 10を使用するべきです。

UnusedImports

未使用のimportを報告します。

UnusedParameter

未使用のパラメーターを報告します。

  • allowedNames
    この正規表現に一致する未使用のパラメータ名は無視されます。

UnusedPrivateClass

未使用のプライベートクラスを報告します。

UnusedPrivateMember

未使用のプライベート関数を報告します。

  • allowedNames
    正規表現に一致する未使用のプライベート関数名は無視されます。

UnusedPrivateProperty

未使用のプライベートプロパティを報告します。

  • allowedNames
    正規表現に一致する未使用のプライベートプロパティは無視されます。

UseAnyOrNoneInsteadOfFind

find 関数の呼び出しで行われている null チェックが、any 関数や none 関数の呼び出しに置き換え可能な場合に報告します。

UseArrayLiteralsInAnnotations

配列リテラル [...] 構文の代わりに arrayOf(...) 構文を使用するアノテーションを報告します。

UseCheckNotNull

checkNotNull 呼び出しに置き換えることができる not-null チェックを報告します。

UseCheckOrError

事前条件と事後条件だけでなく、不変条件をチェックする簡潔な方法を使用できる場合に報告します。

UseDataClass

データを保持するだけのクラスを報告します。
これはデータクラスに置き換える必要があります。

  • allowVars
    一つ以上のvarを含むクラスを無視します。

UseEmptyCounterpart

オブジェクトの空のインスタンスを報告します。
空を表現するインスタンスを使用するべきです。

UseIfEmptyOrIfBlank

isEmpty や isBlank メソッドを使用してデフォルト値を代入するコードがある場合に報告されます。

UseIfInsteadOfWhen

when 式を使用して二項式の条件分岐を行っているコードがある場合に報告されます。
代わりに if 式を使用して表現する方が適切です。

UseIsNullOrEmpty

変数が null または空かどうかのチェックが、x == null || x.isEmpty() や同様の条件式を x.isNullOrEmpty() の呼び出しに置き換えることができる場合に報告されます。

UseLet

変数がnullでないことをチェックしてから、その変数を使用して処理をする場合に?.let{}に置き換えられる場合に報告します。

UseOrEmpty

orEmpty() 呼び出しで置き換えることができる ?: emptyList() を報告します。

UseRequire

IllegalArgumentException をスローするよりも簡潔な、前提条件を確認する方法がある場合に報告します。

UseRequireNotNull

require 関数を使用して変数が null でないことをチェックしている場合に、requireNotNull 関数を使用することができる場合に報告されます。

UseSumOfInsteadOfFlatMapSize

flatMap 関数と size または count 関数を組み合わせて使用している箇所を検出し、それを sumOf 関数で置き換えることができる場合に報告されます。

UselessCallOnNotNull

Nullableな参照に対して使用されるべき関数が、Nullableでない参照や空のコレクションに対して不必要に呼び出されている場合に報告されます。

UtilityClassWithPublicConstructor

ユーティリティクラスが具体的な実装を持たず、パブリックなコンストラクタを持っている場合や、ユーティリティクラスがfinalでない場合に報告されます。

VarCouldBeVal

再代入されることがない変数宣言(ローカル変数やプライベートクラスのプロパティ)がvarで宣言されている場合に報告されます。

  • ignoreLateinitVar
    初期化されていない lateinit varを無視します。

WildcardImport

ワイルドカードを使用したワイルドカードインポート文を報告します。
完全修飾クラス名を使用したインポート文に置き換えるように促します。

  • excludeImports
    ワイルドカードインポートで使用が許可されるべきパッケージ名を指定します。

まとめ

detektを読み解くことで、今まで知らなかったkotlinのベストプラクティスを知ることができました。
それと同時に、ベストプラクティスを自動で教えてくれるdetektに感動しました。
この記事が少しでもお役に立てれば幸いです。

Discussion