From fced8ee40e08854c85cb46e5cfa26f995892cde9 Mon Sep 17 00:00:00 2001 From: Sonu Kapoor Date: Wed, 18 Mar 2020 07:39:48 -0400 Subject: [PATCH] fix(localize): allow ICU expansion case to start with any character except `}` (#36123) Previously, an expansion case could only start with an alpha numeric character. This commit fixes this by allowing an expansion case to start with any character except `}`. The [ICU spec](http://userguide.icu-project.org/formatparse/messages) is pretty vague: > Use a "select" argument to select sub-messages via a fixed set of keywords. It does not specify what can be a "keyword" but from looking at the surrounding syntax it appears that it can indeed be any string that does not contain a `}` character. Closes #31586 PR Close #36123 --- packages/compiler/src/ml_parser/lexer.ts | 2 +- .../test/ml_parser/html_parser_spec.ts | 20 +++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/packages/compiler/src/ml_parser/lexer.ts b/packages/compiler/src/ml_parser/lexer.ts index af02426e53..98ff8f423b 100644 --- a/packages/compiler/src/ml_parser/lexer.ts +++ b/packages/compiler/src/ml_parser/lexer.ts @@ -747,7 +747,7 @@ function isNamedEntityEnd(code: number): boolean { } function isExpansionCaseStart(peek: number): boolean { - return peek === chars.$EQ || chars.isAsciiLetter(peek) || chars.isDigit(peek); + return peek !== chars.$RBRACE; } function compareCharCodeCaseInsensitive(code1: number, code2: number): boolean { diff --git a/packages/compiler/test/ml_parser/html_parser_spec.ts b/packages/compiler/test/ml_parser/html_parser_spec.ts index 3cc1b89353..9972bd690e 100644 --- a/packages/compiler/test/ml_parser/html_parser_spec.ts +++ b/packages/compiler/test/ml_parser/html_parser_spec.ts @@ -313,6 +313,26 @@ import {humanizeDom, humanizeDomSourceSpans, humanizeLineColumn} from './ast_spe expect(p.errors.length).toEqual(0); }); + it(`should support ICU expressions with cases that contain any character except '}'`, + () => { + const p = parser.parse( + `{a, select, b {foo} % bar {% bar}}`, 'TestComp', {tokenizeExpansionForms: true}); + expect(p.errors.length).toEqual(0); + }); + + it('should error when expansion case is not properly closed', () => { + const p = parser.parse( + `{a, select, b {foo} % { bar {% bar}}`, 'TestComp', {tokenizeExpansionForms: true}); + expect(humanizeErrors(p.errors)).toEqual([ + [ + 6, + 'Unexpected character "EOF" (Do you have an unescaped "{" in your template? Use "{{ \'{\' }}") to escape it.)', + '0:36' + ], + [null, 'Invalid ICU message. Missing \'}\'.', '0:22'] + ]); + }); + it('should error when expansion case is not closed', () => { const p = parser.parse( `{messages.length, plural, =0 {one`, 'TestComp', {tokenizeExpansionForms: true});