こちらは以下の続きになります。
背景
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(),
];
}