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,
) {
  context.addCompilationUnit((CompilationUnit node) {
    // Count significant top-level declarations
    int classCount = 0;
    int enumCount = 0;
    int mixinCount = 0;
    ClassDeclaration? secondClass;

    for (final CompilationUnitMember member in node.declarations) {
      if (member is ClassDeclaration) {
        classCount++;
        if (classCount == 2) {
          secondClass = member;
        }
      } else if (member is EnumDeclaration) {
        enumCount++;
      } else if (member is MixinDeclaration) {
        mixinCount++;
      }
    }

    // Report if there are multiple major declarations
    final int majorDeclarations = classCount + enumCount + mixinCount;
    if (majorDeclarations > 1 && secondClass != null) {
      // Skip if it looks like a private helper class
      if (secondClass.nameToken.lexeme.startsWith('_')) return;

      // Skip if all classes are abstract final with only static members
      // (pure constant / utility namespaces co-located for discoverability)
      if (enumCount == 0 &&
          mixinCount == 0 &&
          _allClassesAreStaticNamespaces(node)) {
        return;
      }

      reporter.atNode(secondClass);
    }
  });
}