diff --git a/packages/flutter_tools/lib/src/localizations/message_parser.dart b/packages/flutter_tools/lib/src/localizations/message_parser.dart index b4fbb139164a..47afdb835d96 100644 --- a/packages/flutter_tools/lib/src/localizations/message_parser.dart +++ b/packages/flutter_tools/lib/src/localizations/message_parser.dart @@ -70,6 +70,7 @@ Map>> grammar = >>{ ], ST.selectPart: >[ [ST.identifier, ST.openBrace, ST.message, ST.closeBrace], + [ST.number, ST.openBrace, ST.message, ST.closeBrace], [ST.other, ST.openBrace, ST.message, ST.closeBrace], ], }; @@ -408,6 +409,7 @@ class Parser { case ST.selectParts: if (tokens.isNotEmpty && ( tokens[0].type == ST.identifier || + tokens[0].type == ST.number || tokens[0].type == ST.other )) { parseAndConstructNode(ST.selectParts, 0); @@ -418,8 +420,10 @@ class Parser { case ST.selectPart: if (tokens.isNotEmpty && tokens[0].type == ST.identifier) { parseAndConstructNode(ST.selectPart, 0); - } else if (tokens.isNotEmpty && tokens[0].type == ST.other) { + } else if (tokens.isNotEmpty && tokens[0].type == ST.number) { parseAndConstructNode(ST.selectPart, 1); + } else if (tokens.isNotEmpty && tokens[0].type == ST.other) { + parseAndConstructNode(ST.selectPart, 2); } else { throw L10nParserException( 'ICU Syntax Error: Select parts must be of the form "identifier { message }"', @@ -581,6 +585,10 @@ class Parser { checkExtraRules(syntaxTree); return syntaxTree; } on L10nParserException catch (error) { + // For debugging purposes. + if (logger == null) { + rethrow; + } logger?.printError(error.toString()); return Node(ST.empty, 0, value: ''); } diff --git a/packages/flutter_tools/test/general.shard/message_parser_test.dart b/packages/flutter_tools/test/general.shard/message_parser_test.dart index 851d4ad59809..5c36d59391b4 100644 --- a/packages/flutter_tools/test/general.shard/message_parser_test.dart +++ b/packages/flutter_tools/test/general.shard/message_parser_test.dart @@ -503,4 +503,15 @@ void main() { contains(expectedError3), ))); }); + + testWithoutContext('parser allows select cases with numbers', () { + final Node node = Parser('numberSelect', 'app_en.arb', '{ count, select, 0{none} 100{perfect} other{required!} }').parse(); + final Node selectExpr = node.children[0]; + final Node selectParts = selectExpr.children[5]; + final Node selectPart = selectParts.children[0]; + expect(selectPart.children[0].value, equals('0')); + expect(selectPart.children[1].value, equals('{')); + expect(selectPart.children[2].type, equals(ST.message)); + expect(selectPart.children[3].value, equals('}')); + }); }