
こんにちは、株式会社ラクスで先行技術検証を行っている技術推進課の@t_okkanです。
今回はFlutterの静的解析を紹介します。
FlutterはDartで実装しているため、静的解析もDartの仕組みを利用します。
Dartは静的型付け言語と動的型付け言語のどちらにも対応しているため、型チェックが比較的ゆるいプログラミング言語です。
そのため、静的解析のルールを定めることで型チェックを厳密にしたり、コードのバグを未然に防ぐことが必要になります。
また、ソースコードに強制的に統一されたコーディングスタイルを適用できます。
Flutterの静的解析の仕組みからできることを紹介しています。
Flutterの静的解析の構成要素
Flutterの実装言語であるDartの静的解析はAnalyzerとLinterから構成されます。
- Analyzer 
- Linter - ソースコードがDartのスタイルガイドラインや設定した他のガイドラインに準拠しているかを解析します。 
FlutterではこのDartの静的解析の仕組みを利用して、ソースコードの静的解析を行います。
静的解析の導入
Flutterのプロジェクトに静的解析を導入するには、analysis_optins.yamlファイルをpubsepc.yamlファイルと同じディレクトリに配置します。
./ sample
    |- android
    |- ios
    |- lib
    |    |- main.dart
    |- analysis_options.yaml  ← ファイルを追加
    |- pubspec.yaml
Flutterの新規プロジェクトを作成した時に、プロジェクトのルートにanalysis_options.yamlファイルを追加することをお勧めします。
analysis_options.yamlは以下のような実装になります。
include: package:pedantic/analysis_options.yaml analyzer: exclude: [build/**] strong-mode: implicit-casts: false linter: rules: - camel_case_types
analysis_options.yamlでは以下の設定が可能です。
- inculde - 他の - analysis_options.yamlファイルを取り込むことで、定義されている静的解析のルールを取り込む。
- analyzer - Analyzerや静的解析全体のカスタマイズを設定する。 
- linter - Linterのルールをカスタマイズを設定する。 
それぞれの設定でできることを詳しく説明していきます。
includeの設定
includeにはすでに定義済みの外部のanalysis_options.yamlファイルをプロジェクトに取り込むことができます。
これにより静的解析を手軽に導入することができます。
また、analyzerやlinterを独自で設定して1から静的解析のルールを構築することも可能ですが、Flutterのプラグインとして定義済みのルールを適用することができます。
主なプラグインには以下のようなものがあります。
- effective_dart - Dartを効率的に実装するために定めたルールであるEffective Dartに準拠したLinterのルールを適用できる。 
- pedantic - Googleが内部で使用している静的解析のルールを取り込むことができる。Flutter SDKを実装するプロジェクトで利用されているルール。Effective Dartよりもより厳密なルールが設定がされている。 
それぞれのプラグインのリポジトリのanalysis_options.yamlから、どのようなルールが設定されているのか確認できます。
静的解析のプラグインを導入する場合は、pubspec.yamlにプラグインを追加し、analysis_options.yamlのincludeにプラグインで定義されているanalysis_options.yamlを設定します。
例えば、pedanticを導入する場合は以下のようになります。
- pubspec.yaml
dev_dependencies: flutter_test: sdk: flutter # プラグインを追加 pedantic: ^1.11.0
- analysis_options.yaml
# pedanticのanalysis_options.yamlを設定 include: package:pedantic/analysis_options.yaml
analyzerの設定
analyzerではDartの型システムのカスタマイズや、静的解析を適用する範囲の設定などができます。
厳密な型チェックを有効にする
Dartは部分的に動的片付け言語になるため、デフォルトでは暗黙的型変換が有効であったり、比較的ゆるめの型チェックになります。
Dartのデフォルトの型チェックよりも厳密な型チェックが必要な場合は、analyzerのオプションでstrong-modeを指定することで有効にできます。strong-modeでは以下のような設定が可能です。
- implicit-casts - falseにすることで暗黙的型変換の実装を禁止できます。
- implicit-dynamic - falseにすることで動的な型宣言で使用する- dynamic型の使用を禁止できます。
analysis_options.yamlは以下のように設定します。
analyzer: strong-mode: implicit-casts: false implicit-dynamic: false
コンパイル時の型チェックが厳密になり、より堅牢なコードになるので、できるだけ厳密な型チェックは有効にすることをおすすめします。
一部のファイルを解析の対象から除外する
Flutterの実装をしていると、immutableなクラスを自動生成するfreezedパッケージなどで自動生成されたファイルは、静的解析の対象から除外したい場合があります。
また、一部のファイルを解析から除外したい場合は、analyzerのオプションのexcludeに除外するファイルを設定できます。
以下にanalysis_options.yamlの設定の一例を載せておきます。
analyzer: exclude: # ファイルを直接指定 - lib/client.dart # フォルダ内の特定の拡張子を指定 - lib/data/model/*.freezed.dart # フォルダ内の全てのファイルを指定 - test/_data/**
特定のルールをプロジェクトで無効にする
前述した静的解析用のプラグインを導入した際に、特定のルールだけは無効にしたい場合があります。
特定のルールをプロジェクトで無効にするには、analyzerのオプションのerrorsに設定し、errorsのオプションに無視したいルール名、ignoreを設定すると、プロジェクト全体で指定したルールを無効にできます。
なお、AnalyzerとLinterのどちらのルールも無効にできます。
参考として、以下にanalysis_options.yaml設定の一例を載せておきます。
analyzer: errors: # ルール名:ignore # Analyzerの無効化:TODO表記を無視する todo: ignore # Linterの無効化 avoid_empty_else: ignore
解析のルールの重要度を変更する
Flutterの静的解析にはinfo、warning、errorの3種類の重要度があります。
- infoと- warning:静的解析には失敗しないが、警告されるレベル
- error:違反していると静的解析が失敗するレベル
Flutterの静的解析では、特定の解析ルールの重要度をプロジェクト全体で変更することができます。
例えば、Linterルールはデフォルトでinfoレベルに設定されていますが、warningやerrorレベルに引き上げることが可能です。
重要度を変更するにはanalyzerのerrorsオプションに、変更したいルール名と重要度(info、warning、error)を設定します。
以下に、analysis_options.yaml設定の一例を載せておきます。
analyzer: errors: # ルール名:重要度(info、warning、error) # Analyzerの変更:returnの省略を警告する missing_return: warning # Linterの変更 prefer_contains: error
linterの設定
プラグインであるpedanticやeffective_dartを導入することで、Linterを手軽に設定できましたが、もちろん開発者が個別でLinterをカスタマイズすることも可能です。
カスタマイズする項目をlinterのrulesに設定します。
Linterで設定できるルールの一覧は、以下で公開されています。
pedanticとeffective_dart、Flutterでデフォルトで適用されている設定はそれぞれマークされており、設定されているルールを上書きして無効にすることもできます。
例えば、ローカル変数で型推論を使用するようにします。
omit_local_variable_typesを無効にする場合は、以下のようにfalseを設定します。
include: package:pedantic/analysis_options.yaml linter: rules: omit_local_variable_types: false
ファイルや特定のコードを静的解析の対象から除外する
analyzerの設定で、特定のファイルを静的解析の対象から除外することができました。
それに加え、ソースコードの特定の1行だけ特別に静的解析の対象から除外することができます。
また、ファイル内にそのファイルを静的解析の対象から除外する設定ができます。
- 1行のコードで特定のルールを除外する - 特定の1行のコードでルールを除外するにはコードの1行上に - ignore: linterのルールをコメントアウトで追加します。複数のルールを除外する場合はコンマ区切りで指定します。
// ignore: linterのルール名 // 以下実装例 class Point { int x, y; // ignore: empty_constructor_bodies Point(this.x, this.y) {} // 空のコンストラクタが警告されない }
- ファイル内で特定のルールを除外する - ファイル内で特定のルールが適用されないように設定できます。ファイルのどこか(できればパッケージのimportの直下)に - ignore_for_file: linterのルールをコメントアウトで追加します。複数のルールを除外する場合はコンマ区切りで指定します。
// ignore_for_file: linterのルール名 // 以下実装例 // ignore_for_file: omit_local_variable_types, empty_constructor_bodies class Point { int x, y; Point(this.x, this.y) {} // 空のコンストラクタが警告されない }
静的解析の実行
静的解析を実行する方法には、エディタで実行する方法と、コマンドラインで実行する方法があります。
静的解析の実行については、FlutterのリポジトリのWikiに詳しく記載されていますので、合わせてご確認ください。
エディタで静的解析を有効にする
Flutterの開発に対応しているエディタやIDEを使用している場合、各環境のFlutterとDartの拡張プラグインをインストールしていればプロジェクトのanalysis_options.yamlを認識して、ファイル保存時などおいて、自動で静的解析を実行します。
各エディタのセットアップ方法は、以下に紹介されています。
手順に沿って拡張プラグインをインストールしてください。
コマンドラインで静的解析を実行する
コマンドラインからでも静的解析を実行できます。
プロジェクトのルートでflutter analyzeを実行します。
$ flutter analyze Analyzing flutter_analyzer... info • Avoid types as parameter names • lib/main.dart:39:16 • avoid_types_as_parameter_names 1 issue found. (ran in 4.2s)
まとめ
Flutterの静的解析についてまとめました。
Lintルールなど設定値が多く、いきなり一つ一つを自分で設定するのハードルが高いかと思います。
ですのでまずは、pedanticやeffective_dartなどのプラグインを導入することをお勧めします。
また、別の方法としてはFlutterのリポジトリにあるanalysis_options.yamlファイルをコピーする方法もお勧めです。
あとは、Effective Dartをしっかり読み、Flutterの実装を進めて気になることがあれば個別でルールを追加していくと良いかと思います。
そして、ある程度ルールが固まってきたらテンプレート化し、複数のプロジェクトで使いまわせるようになるかと思います。
- エンジニア中途採用サイト 
 ラクスでは、エンジニア・デザイナーの中途採用を積極的に行っております!
 ご興味ありましたら是非ご確認をお願いします。
  
 https://career-recruit.rakus.co.jp/career_engineer/
- カジュアル面談お申込みフォーム 
 どの職種に応募すれば良いかわからないという方は、カジュアル面談も随時行っております。
 以下フォームよりお申込みください。
 rakus.hubspotpagebuilder.com
- ラクスDevelopers登録フォーム 
  
 https://career-recruit.rakus.co.jp/career_engineer/form_rakusdev/
- イベント情報 
 会社の雰囲気を知りたい方は、毎週開催しているイベントにご参加ください!
◆TECH PLAY
techplay.jp
◆connpass
rakus.connpass.com
