12
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Flutter】custom_lint:enumはifではなくswitchを用いよう

Posted at

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

背景

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(),
      ];
}
12
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
12
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?