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,
) {
  if (isGeneratedFile(resolver.path)) return;
  if (!RigidConfig.forFile(resolver.path).isEnabled(code.name)) return;
  if (isTestFile(resolver.path)) return;

  // Skip l10n/intl files.
  final path = resolver.path.toLowerCase();
  if (path.contains('l10n') || path.contains('intl') ||
      path.contains('string') || path.contains('constants')) {
    return;
  }

  context.registry.addInstanceCreationExpression((node) {
    final typeName = node.constructorName.type.name.lexeme;

    // Check Text('hardcoded') — first positional arg.
    if (_textWidgets.contains(typeName)) {
      final args = node.argumentList.arguments;
      if (args.isNotEmpty) {
        final first = args.first;
        if (first is! NamedExpression) {
          if (first is SimpleStringLiteral && _isUserVisible(first.value)) {
            reporter.atNode(first, code);
          } else if (first is StringInterpolation) {
            _checkInterpolation(first, reporter);
          }
        }
      }
    }

    // Check named params like labelText, hintText, message, etc.
    for (final arg in node.argumentList.arguments) {
      if (arg is NamedExpression &&
          _textParams.contains(arg.name.label.name)) {
        final expr = arg.expression;
        if (expr is SimpleStringLiteral && _isUserVisible(expr.value)) {
          reporter.atNode(expr, code);
        } else if (expr is StringInterpolation) {
          _checkInterpolation(expr, reporter);
        }
      }
    }
  });

  // Also check method calls: Tooltip(message: '...') etc.
  context.registry.addMethodInvocation((node) {
    for (final arg in node.argumentList.arguments) {
      if (arg is NamedExpression &&
          _textParams.contains(arg.name.label.name)) {
        final expr = arg.expression;
        if (expr is SimpleStringLiteral && _isUserVisible(expr.value)) {
          reporter.atNode(expr, code);
        } else if (expr is StringInterpolation) {
          _checkInterpolation(expr, reporter);
        }
      }
    }
  });
}