run method

  1. @override
void run(
  1. CustomLintResolver resolver,
  2. DiagnosticReporter reporter,
  3. CustomLintContext context
)

Emits lints for a given file.

run will only be invoked with files respecting filesToAnalyze

Implementation

@override
void run(
  CustomLintResolver resolver,
  DiagnosticReporter reporter,
  CustomLintContext context,
) {
  final filePath = resolver.path;
  if (isGeneratedFile(filePath)) return;
  if (!RigidConfig.forFile(filePath).isEnabled(code.name)) return;
  if (isTestFile(filePath)) return;

  // Only check files under lib/.
  if (!filePath.contains('${p.separator}lib${p.separator}')) return;

  // Extract the path relative to lib/.
  final libIndex = filePath.indexOf('${p.separator}lib${p.separator}');
  final projectRoot = filePath.substring(0, libIndex);
  final relativePath =
      filePath.substring(libIndex + '${p.separator}lib${p.separator}'.length);

  // Skip the root library file (e.g., lib/my_package.dart).
  if (!relativePath.contains(p.separator)) {
    // Root-level lib file — skip.
    return;
  }

  // Compute expected test file path.
  final baseName = p.basenameWithoutExtension(relativePath);
  final dirName = p.dirname(relativePath);
  final testPath =
      p.join(projectRoot, 'test', dirName, '${baseName}_test.dart');

  if (!File(testPath).existsSync()) {
    // Report at the library/compilation-unit level (first line).
    context.registry.addCompilationUnit((node) {
      // Skip barrel/export-only files — they have no logic to test.
      if (node.declarations.isEmpty) return;

      reporter.atNode(
        node,
        LintCode(
          name: 'rigid_require_tests',
          problemMessage:
              'This file has no corresponding test file. '
              'Create test/$dirName/${baseName}_test.dart '
              '(mkdir -p the directory if needed) with adversarial tests.',
          errorSeverity: DiagnosticSeverity.WARNING,
        ),
      );
    });
  }
}