こちらは以下の続きになります。
背景
Flutterはenumが充実しており、様々な活用方法が増えてきています。
もちろん条件分岐で考慮漏れが減ることもメリットの一つだと思います。
しかし、条件分岐の際にswitch文(or 式)を用いれば考慮漏れが減るのですがifを用いてしまうとうっかり考慮漏れが発生してしまう場合があります。
そのため、これをルールで弾くことにしました。
実装
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/error/listener.dart';
import 'package:custom_lint_builder/custom_lint_builder.dart';
class PreferSwitchOverIfWithEnum extends DartLintRule {
const PreferSwitchOverIfWithEnum() : super(code: _code);
static const _code = LintCode(
name: 'prefer_switch_over_if_with_enum',
problemMessage: 'Use switch instead of if when comparing enums',
errorSeverity: ErrorSeverity.WARNING,
);
@override
void run(
CustomLintResolver resolver,
ErrorReporter reporter,
CustomLintContext context,
) {
context.registry.addIfStatement((node) {
// ifでEnumを比較しているかチェック
final condition = node.expression;
if (condition is BinaryExpression) {
final leftOperand = condition.leftOperand;
final rightOperand = condition.rightOperand;
if (leftOperand is Identifier && rightOperand is Identifier) {
final leftElement = leftOperand.staticElement;
final rightElement = rightOperand.staticElement;
if (leftElement is PropertyAccessorElement &&
rightElement is PropertyAccessorElement) {
final leftType = leftElement.variable.type;
final rightType = rightElement.variable.type;
if (leftType is InterfaceType &&
rightType is InterfaceType &&
leftType.element.kind == ElementKind.ENUM &&
rightType.element.kind == ElementKind.ENUM) {
reporter.reportErrorForNode(_code, node);
}
}
}
}
});
}
}
また、ルール設定した際はgetLintRules
への追加もお忘れなく。
PluginBase createPlugin() => _MyCustomLinter();
class _MyCustomLinter extends PluginBase {
@override
List<LintRule> getLintRules(CustomLintConfigs configs) => [
// 各lintルールを定義したクラスを配置していく
const PreferSwitchOverIfWithEnum(),
];
}