run method

  1. @override
List<Issue> run(
  1. DialectProject project
)
override

Inspect project and return findings. May return an empty list. Should NOT throw — turn unexpected conditions into Issues so the report surfaces them rather than crashing.

Implementation

@override
List<Issue> run(DialectProject project) {
  final issues = <Issue>[];
  final overrides = _parseOverrides(project);

  final sourceByKey = <String, ArbEntry>{
    for (final e in project.source.entries) e.key: e,
  };

  for (final entry in project.translations.entries) {
    final locale = entry.key;
    if (locale == project.config.sourceLocale) continue;
    final arb = entry.value;
    final range = overrides[locale] ?? defaultRange;

    for (final t in arb.entries) {
      final src = sourceByKey[t.key];
      if (src == null) continue;
      if (src.value.length < minSourceLength) continue;
      if (t.value.isEmpty) continue; // empty_values rule covers this

      final ratio = t.value.length / src.value.length;
      if (ratio < range[0] || ratio > range[1]) {
        final direction = ratio < range[0] ? 'shorter' : 'longer';
        issues.add(
          Issue(
            severity: defaultSeverity,
            ruleName: name,
            message:
                'Translation for `${t.key}` is '
                '${ratio.toStringAsFixed(2)}× the source length — '
                '$direction than the expected band '
                '[${range[0]}, ${range[1]}].',
            locale: locale,
            key: t.key,
            file: arb.sourcePath,
            line: arb.entryLines[t.key],
            hint:
                'Common causes: truncated UI text, wrong-locale paste, '
                'or an AI hallucinating extra prose. If `$locale` legitimately '
                'expands or contracts this much, add an override under '
                '`length_ratio:` in dialect.yaml.',
          ),
        );
      }
    }
  }

  return issues;
}