dart-static-analysis について
Dart プロジェクトで静的解析を設定・実行するためのスキルです。厳密なチェック、Lint の管理、型昇格に失敗する場合の対処を扱います。
主な機能
- 01厳密な解析オプションの設定
- 02推奨 Lint ルールセットの利用
- 03dart fix による自動修正
- 04型昇格失敗への対処
活用シーン
- 01Dart パッケージの静的解析設定
- 02コードのバグやスタイルの確認
- 03一般的な Lint 違反の修正
- 04nullable 型の昇格エラーの解決
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ dart-lang/ skills --skill dart-static-analysisインストール後、Claude Code で/dart-static-analysisを入力して読み込まれたか確認します。
詳細
Dart コードの解析と lint
目次
解析オプションの設定
パッケージのルートに analysis_options.yaml ファイルを配置して、静的解析を制御します。
- 厳密な型チェックを有効にする: コンパイル時に暗黙的な dynamic キャストや型が推論されていない箇所を検出するため、
analyzerセクションでstrict-casts、strict-inference、strict-raw-typesを常に有効にします。 - フォーマットを設定する:
formatterセクション内でdart formatのルールを定義します(例:page_widthやtrailing_commas)。 - 生成コードを除外する: 生成ファイル(例:
**/*.g.dart、**/*.freezed.dart)を無視するにはexcludeキーを使い、誤検出を防ぎます。
Linter ルールの管理
独自のルール一覧を管理するのではなく、コミュニティ標準のルールセットを利用します。
- 標準パッケージを使う: 純粋な Dart プロジェクトでは
package:lints/recommended.yamlを、Flutter プロジェクトではpackage:flutter_lints/flutter.yamlを含めます。 - 手動での無視を避ける: 絶対に必要な場合を除き、lint を手動で無視すること(例:
// ignore: ...)は避けます。lint の根本原因を修正することを優先します。 - 一括修正: コードベース全体にわたる一般的な lint 違反や移行の問題を自動的に解決するには、
dart fix --applyを使います。 - 重大度をカスタマイズする: 特定のルールの通知が多すぎるものの有用性がある場合は、完全に無効にするのではなく、
errorsマップで重大度を変更します(例:todo: info)。
型昇格の失敗を解決する
フロー解析によって nullable 変数が null ではないと確認された場合、型昇格が発生します。チェックと使用の間で値が安定していることをコンパイラーが保証できない場合、型昇格は失敗します。
型昇格が失敗する一般的な原因は次のとおりです。
- 公開フィールドまたは final ではないフィールド: 外部ライブラリによって公開フィールドがオーバーライドされる可能性があり、final ではないフィールドは変更される可能性があります。
- ゲッター: ゲッターが呼び出されるたびに同じ値を返すことをコンパイラーが保証できません。
- 書き込みキャプチャ: クロージャまたは関数式内で変数が変更されると、それまでのチェックが無効になります。
解決策: 「型昇格しない」理由を解決するには、null チェックまたは型チェックを行う前に、フィールド、ゲッター、またはキャプチャされた変数をローカルな final 変数に代入します。ローカル変数は安定していることが保証されるため、コンパイラーは安全に型を昇格できます。
ワークフロー:静的解析のセットアップと実行
このチェックリストを使って、Dart プロジェクトで静的解析を初期化し、徹底します。
- タスクの進捗:解析のセットアップ
-
dart pub add --dev lints(またはflutter_lints)を実行します。 - プロジェクトのルートに
analysis_options.yamlを作成します。 - 推奨ルールセットを含めます(
include: package:lints/recommended.yaml)。 - 厳密な言語モード(
strict-casts、strict-inference、strict-raw-types)を有効にします。
-
- タスクの進捗:実行と修正
-
dart analyzeを実行して、潜在的なバグやスタイル違反を早期に検出します。 -
dart fix --applyを実行して、機械的に修正できる lint の問題を自動的に解決します。 - 残りのエラーを手動で確認します。バリデーターを実行 -> エラーを確認 ->
// ignoreを使わずに根本原因を修正します。
-
型の昇格を修正するワークフロー
dart analyze でプロパティまたはフィールドを昇格できないと報告された場合:
- タスクの進捗:昇格の修正
- 問題が発生している変数を特定します(例:パブリックフィールド、ゲッター、または書き込みによってキャプチャされた変数)。
- 条件チェックの直前で、ローカルの
final変数を宣言します。 - 昇格できないフィールドまたはゲッターを、新しいローカル変数に代入します。
- ローカル変数に対して
!= nullまたはis Typeのチェックを行います。 - 条件ブロック内のすべての参照を、ローカル変数を使うように更新します。
-
dart analyzeを実行し、昇格の問題が解決したことを確認します。
例
高忠実度の analysis_options.yaml
include: package:lints/recommended.yaml
analyzer:
exclude:
- "**/*.g.dart"
- "**/*.freezed.dart"
language:
strict-casts: true
strict-inference: true
strict-raw-types: true
errors:
todo: info
invalid_assignment: error
formatter:
page_width: 80
trailing_commas: preserve
linter:
rules:
# Disable specific rules if they conflict with project architecture
avoid_classes_with_only_static_members: false
# Enable additional strict rules
always_declare_return_types: true
cancel_subscriptions: true
ローカル変数による型の昇格の修正
アンチパターン: ゲッターまたはパブリックフィールドを直接チェックします。_value はゲッターであり、2回目の呼び出しで異なる結果を返す可能性があるため、コンパイラーはエラーを出します。
abstract class Example {
int? get _value => Random().nextBool() ? 123 : null;
}
void printParity(Example x) {
if (x._value != null) {
// ERROR: '_value' refers to a getter so it couldn't be promoted.
print(x._value.isEven);
}
}
ベストプラクティス: ローカルの final 変数に代入して、値が安定するようにします。
abstract class Example {
int? get _value => Random().nextBool() ? 123 : null;
}
void printParity(Example x) {
final localValue = x._value; // 1. Assign to local final variable
if (localValue != null) { // 2. Check the local variable
print(localValue.isEven); // 3. Use the promoted local variable (OK)
}
}
関連スキル:dart-effective-style、dart-api-design