From 57f8dd2978a3d98ec7ee356573cc51d58b343a9f Mon Sep 17 00:00:00 2001 From: ayazhafiz Date: Fri, 25 Sep 2020 11:45:46 -0500 Subject: [PATCH] test(compiler): add tests for parsing of malformed property reads (#38998) The expression parser already has support for recovering on malformed property reads, but did not have tests describing the recovered ast in such cases. This commit adds tests to demonstrate such cases; in particular, the recovered ast is a full PropertyRead but with an empty property name. This is likely the most preferred option, as it does not constrain consumers of the AST to what the property name should look like. Furthermore, we cannot mark the property name as empty in any other way (e.g. an EmptyExpr) because the property name, as of present, is a string field rather than an AST itself. Note that tokens past a malformed property read are not preserved in the AST (for example in `foo.1234`, `1234` is not preserved in the AST). This is because the extra tokens do not belong to the singular expression created by the property read, and there is not a meaningful way to interpret a secondary expression in a single parsed expression. Part of #38596 PR Close #38998 --- .../test/expression_parser/parser_spec.ts | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/packages/compiler/test/expression_parser/parser_spec.ts b/packages/compiler/test/expression_parser/parser_spec.ts index 0c1f33c8f2..91a7de4621 100644 --- a/packages/compiler/test/expression_parser/parser_spec.ts +++ b/packages/compiler/test/expression_parser/parser_spec.ts @@ -128,15 +128,22 @@ describe('parser', () => { }); it('should only allow identifier or keyword as member names', () => { - expectActionError('x.(', 'identifier or keyword'); - expectActionError('x. 1234', 'identifier or keyword'); - expectActionError('x."foo"', 'identifier or keyword'); + checkActionWithError('x.', 'x.', 'identifier or keyword'); + checkActionWithError('x.(', 'x.', 'identifier or keyword'); + checkActionWithError('x. 1234', 'x.', 'identifier or keyword'); + checkActionWithError('x."foo"', 'x.', 'identifier or keyword'); }); it('should parse safe field access', () => { checkAction('a?.a'); checkAction('a.a?.a'); }); + + it('should parse incomplete safe field accesses', () => { + checkActionWithError('a?.a.', 'a?.a.', 'identifier or keyword'); + checkActionWithError('a.a?.a.', 'a.a?.a.', 'identifier or keyword'); + checkActionWithError('a.a?.a?. 1234', 'a.a?.a?.', 'identifier or keyword'); + }); }); describe('method calls', () => { @@ -1013,8 +1020,7 @@ function expectBindingError(text: string, message: string) { } /** - * Check that an malformed action parses to a recovered AST while emitting an - * error. + * Check that a malformed action parses to a recovered AST while emitting an error. */ function checkActionWithError(text: string, expected: string, error: string) { checkAction(text, expected);