run method
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;
}