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>[];

  for (final src in project.source.entries) {
    final sourcePh = IcuMessage.extractPlaceholders(src.value);

    for (final entry in project.translations.entries) {
      final locale = entry.key;
      final arb = entry.value;
      final translated = arb.entryFor(src.key);
      if (translated == null) continue; // covered by missing_keys

      final translatedPh = IcuMessage.extractPlaceholders(translated.value);
      final missing = sourcePh.difference(translatedPh);
      final extra = translatedPh.difference(sourcePh);

      if (missing.isNotEmpty) {
        issues.add(
          Issue(
            severity: defaultSeverity,
            ruleName: name,
            message:
                'Translation drops placeholder(s) '
                '${_listPlaceholders(missing)} for key `${src.key}`.',
            locale: locale,
            key: src.key,
            file: arb.sourcePath,
            line: arb.entryLines[src.key],
            hint:
                'Preserve placeholder names byte-identically across '
                'translations. Source has '
                '${_listPlaceholders(sourcePh)}.',
          ),
        );
      }
      if (extra.isNotEmpty) {
        issues.add(
          Issue(
            severity: defaultSeverity,
            ruleName: name,
            message:
                'Translation introduces unexpected placeholder(s) '
                '${_listPlaceholders(extra)} for key `${src.key}`.',
            locale: locale,
            key: src.key,
            file: arb.sourcePath,
            line: arb.entryLines[src.key],
            hint:
                'Use the exact placeholder names from the source — '
                '${_listPlaceholders(sourcePh)}. Do not localize names.',
          ),
        );
      }
    }
  }

  return issues;
}