Skip to content

Commit 117a83a

Browse files
authored
Throw error when plural case had undefined behavior (#116622)
* init * add comment * make error more actionable
1 parent bebea0c commit 117a83a

File tree

2 files changed

+46
-1
lines changed

2 files changed

+46
-1
lines changed

packages/flutter_tools/lib/src/localizations/gen_l10n.dart

+14-1
Original file line numberDiff line numberDiff line change
@@ -1167,7 +1167,20 @@ class LocalizationsGenerator {
11671167
}
11681168
if (!pluralLogicArgs.containsKey(pluralCases[pluralCase])) {
11691169
final String pluralPartExpression = generateVariables(pluralMessage);
1170-
pluralLogicArgs[pluralCases[pluralCase]!] = ' ${pluralCases[pluralCase]}: $pluralPartExpression,';
1170+
final String? transformedPluralCase = pluralCases[pluralCase];
1171+
// A valid plural case is one of "=0", "=1", "=2", "zero", "one", "two", "few", "many", or "other".
1172+
if (transformedPluralCase == null) {
1173+
throw L10nParserException(
1174+
'''
1175+
The plural cases must be one of "=0", "=1", "=2", "zero", "one", "two", "few", "many", or "other.
1176+
$pluralCase is not a valid plural case.''',
1177+
_inputFileNames[locale]!,
1178+
message.resourceId,
1179+
translationForMessage,
1180+
pluralPart.positionInMessage,
1181+
);
1182+
}
1183+
pluralLogicArgs[transformedPluralCase] = ' ${pluralCases[pluralCase]}: $pluralPartExpression,';
11711184
} else if (!suppressWarnings) {
11721185
logger.printWarning('''
11731186
[${_inputFileNames[locale]}:${message.resourceId}] ICU Syntax Warning: The plural part specified below is overridden by a later plural part.

packages/flutter_tools/test/general.shard/generate_localizations_test.dart

+32
Original file line numberDiff line numberDiff line change
@@ -2027,6 +2027,38 @@ import 'output-localization-file_en.dart' deferred as output-localization-file_e
20272027
^'''));
20282028
});
20292029

2030+
testWithoutContext('undefined plural cases throws syntax error', () {
2031+
const String pluralMessageWithUndefinedParts = '''
2032+
{
2033+
"count": "{count,plural, =0{None} =1{One} =2{Two} =3{Undefined Behavior!} other{Hmm...}}"
2034+
}''';
2035+
final Directory l10nDirectory = fs.currentDirectory.childDirectory('lib').childDirectory('l10n')
2036+
..createSync(recursive: true);
2037+
l10nDirectory.childFile(defaultTemplateArbFileName)
2038+
.writeAsStringSync(pluralMessageWithUndefinedParts);
2039+
try {
2040+
LocalizationsGenerator(
2041+
fileSystem: fs,
2042+
inputPathString: defaultL10nPathString,
2043+
outputPathString: defaultL10nPathString,
2044+
templateArbFileName: defaultTemplateArbFileName,
2045+
outputFileString: defaultOutputFileString,
2046+
classNameString: defaultClassNameString,
2047+
logger: logger,
2048+
)
2049+
..loadResources()
2050+
..writeOutputFiles();
2051+
} on L10nException catch (error) {
2052+
expect(error.message, contains('Found syntax errors.'));
2053+
expect(logger.hadErrorOutput, isTrue);
2054+
expect(logger.errorText, contains('''
2055+
[app_en.arb:count] The plural cases must be one of "=0", "=1", "=2", "zero", "one", "two", "few", "many", or "other.
2056+
3 is not a valid plural case.
2057+
{count,plural, =0{None} =1{One} =2{Two} =3{Undefined Behavior!} other{Hmm...}}
2058+
^'''));
2059+
}
2060+
});
2061+
20302062
testWithoutContext('should automatically infer plural placeholders that are not explicitly defined', () {
20312063
const String pluralMessageWithoutPlaceholdersAttribute = '''
20322064
{

0 commit comments

Comments
 (0)