run method
void
run(
- CustomLintResolver resolver,
- DiagnosticReporter reporter,
- 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);
}
}
}
});
}