私がコードレビューをするとき、文字や文体の誤りや不備はあまり重視していません。それらを確認するのは IDE や静的解析ツールの責務として考えているので、人間は API の使い方やアルゴリズムなどを確認すれば良いと考えています(ただ実際は見る場合も多い)。静的解析で解決できる問題は、機械にやらしたい。そのために Lint は整備したい、Linterに指摘して欲しい。本記事は Lint 関連で私がやることを紹介します。
Xcode
開発を進めていくと、非推奨の関数が発生することがあります。いま入れ替える必要はないけど、いつか入れ替えたい。そのときは、Xcode の機能を利用します。
@available(*, deprecated, message: "show() を使ってください", renamed: "show")
func showDog() {
print("name: \(name)")
}
func show() {
print("name: \(name)")
}
ありがとう、Xcode。関数の置換が分かりやすいですね。
SwiftLint
上記例は自作した関数に対してですが、標準ライブラリが提供する API に同様の制約を付けるのは難しいです。その場合は、サードパーティーの Lint ツールでカスタムルールで対応します。
例として、ある架空の開発チームにおいて、配列の要素を追加する場合に append()
ではなく append(contentsOf: )
を使うという独自のチームルールがあったと仮定します。
class LintRule {
var list: [Int] = []
func append() {
// NG にしたい
list.append(1)
list.append(2)
list.append(3)
// OK にしたい
list.append(contentsOf: [1, 2, 3])
}
}
このルールの厄介なところは、append()
でも append(contentsOf: )
でもビルドはできるので、ビルドエラーで検出できません。目視が必要になります。しかし人間には限界があります。
そこで、Lintを使って自動検出しましょう。今回は SwiftLint を使用しました。append
を contentsOf
なしで使用している箇所を表す正規表現を書いてあげれば、大丈夫です。
# カスタムルール
custom_rules:
# append() ではなく append(contentsOf: ) を使うように設定する
must_use_append_contentsOf:
included: "LintDrivenDevSample\/.+\\.swift"
name: "must use append(contentsOf: )"
regex: "\\.append\\((?![\\s]*contentsOf)"
match_kinds:
- identifier
message: "要素追加は append() ではなく append(contentsOf: ) を使ってください"
severity: error
無事に Lint エラーがでたので、append()
を append(contentsOf: )
を置換箇所が静的解析で分かりました。ありがとう、Lint。
まとめ
最近は Apple Silicon の登場でビルド時間が短縮されて開発環境はよくなりました。ただ、ビルド前に分かれば、より時間の短縮に繋がります。事前の静的解析でよい開発体験をしましょう。今回のサンプルは mitsuharu/LintDrivenDevSample で公開しています。
おまけ
このサンプルプロジェクトを作る際に SwiftLint の GitHub を覗いてたところ、つい最近 (11/30) に Swift Package Manager Plugin に対応してました。やったね!