runWithReporter method

  1. @override
void runWithReporter(
  1. SaropaDiagnosticReporter reporter,
  2. SaropaContext context
)
override

Override this method to implement your lint rule.

Use context to register callbacks for AST node types:

context.addMethodInvocation((node) {
  if (condition) {
    reporter.atNode(node);
  }
});

Implementation

@override
void runWithReporter(
  SaropaDiagnosticReporter reporter,
  SaropaContext context,
) {
  // A class named `...State` is only a genuine BLoC state if it participates
  // in a Bloc/Cubit state hierarchy (referenced as a `Bloc<_, ThisState>` /
  // `Cubit<ThisState>` type argument). The previous version reported any
  // concrete `...State`-named class in a bloc file purely by name, so a plain
  // domain object such as `RequestState` was a false positive. Because a
  // Bloc/Cubit declaration may textually precede OR follow its state class,
  // gating needs the whole unit in hand — so we visit the compilation unit
  // once (a single visitor that the native registry supports; the v4
  // addPostRunCallback is a no-op here and cannot be used) and run two passes
  // over its top-level declarations.
  context.addCompilationUnit((CompilationUnit unit) {
    // Pass 1: collect every name used as a `Bloc<...>` / `Cubit<...>` type
    // argument anywhere in the unit. We collect ALL type arguments (not just
    // the state position) so the gate is robust to `Bloc<Event, State>` vs
    // `Cubit<State>` shapes; a `...State` name only matters when it actually
    // appears here.
    final Set<String> blocStateTypeArgNames = <String>{};
    for (final CompilationUnitMember member in unit.declarations) {
      if (member is ClassDeclaration) {
        _collectBlocStateTypeArgs(member, blocStateTypeArgNames);
      }
    }

    // Pass 2: report mutable `...State` classes that participate as a
    // Bloc/Cubit state type argument.
    for (final CompilationUnitMember member in unit.declarations) {
      if (member is ClassDeclaration) {
        _checkStateClass(member, blocStateTypeArgNames, reporter);
      }
    }
  });
}