From e7f8bcb87408b6f6f9b1f2374a679639f95fab82 Mon Sep 17 00:00:00 2001 From: Sonu Kapoor Date: Wed, 18 Mar 2020 07:39:48 -0400 Subject: [PATCH 1/2] fix(localize): allow ICU expansion case to start with any character except `}` 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 --- 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 af02426e53116..6f4912f1cd39b 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.$EQ || 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 3cc1b893532cd..9972bd690e890 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}); From f3c32ab613f274bb5a7b23bb985f00fedc1ff4fd Mon Sep 17 00:00:00 2001 From: Sonu Kapoor Date: Wed, 18 Mar 2020 07:52:25 -0400 Subject: [PATCH 2/2] fixup! fix(localize): allow ICU expansion case to start with any character except `}` --- packages/compiler/src/ml_parser/lexer.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/compiler/src/ml_parser/lexer.ts b/packages/compiler/src/ml_parser/lexer.ts index 6f4912f1cd39b..98ff8f423b5c4 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 || peek !== chars.$RBRACE; + return peek !== chars.$RBRACE; } function compareCharCodeCaseInsensitive(code1: number, code2: number): boolean {