LoginSignup
3
2

【Flutter】custom_lint:nullableな変数に対するアンラップは避けよう

Posted at

こちらは以下の続きになります。

背景

APIなどを用いて実装する場合、nullableな変数を扱うことは多いと思います。
その際、当然nullチェックをすると思うのですがよく以下のような書き方をしていませんか?

if (state.user != null) {
  print(state.user!.name);
}

このように、state.user!とアンラップしていますが、一応事前にnullチェックをしているので問題はありません。
しかし、全体でこういうのも変数に入れて避けていきたいという方針があったためlintルールを自作することにしました。

ルール設定後は以下のように回避できます。

final user = state.user;

if (user != null) {
  print(user.name);
}

一度変数に格納することでnullチェック後にアンラップする必要がなくなります。

実装

import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/error/listener.dart';
import 'package:custom_lint_builder/custom_lint_builder.dart';

class NullableUnwrapWarning extends DartLintRule {
  const NullableUnwrapWarning()
      : super(
          code: _code,
        );

  static const _code = LintCode(
    name: 'nullable_unwrap_warning',
    problemMessage:
        'nullableな変数に対して!演算子を使用してアンラップしています。nullチェックを行うか、?演算子を使用することを検討してください。',
    errorSeverity: ErrorSeverity.WARNING,
  );

  @override
  void run(
    CustomLintResolver resolver,
    ErrorReporter reporter,
    CustomLintContext context,
  ) {
    context.registry.addPostfixExpression((node) {
      if (node.operator.type == TokenType.BANG) {
        final operandType = node.operand.staticType;
        if (operandType != null &&
            operandType.nullabilitySuffix == NullabilitySuffix.question) {
          reporter.reportErrorForNode(_code, node);
        }
      }
    });
  }
}

設定したらgetLintRulesに入れてflutter pub getをして適応しましょう。

PluginBase createPlugin() => _MyCustomLinter();

class _MyCustomLinter extends PluginBase {
  @override
  List<LintRule> getLintRules(CustomLintConfigs configs) => [
        // 各lintルールを定義したクラスを配置していく
        const NullableUnwrapWarning(),
      ];
}
3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2