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
This commit is contained in:
ayazhafiz 2020-09-25 11:45:46 -05:00 committed by Joey Perrott
parent bc69182bdd
commit 57f8dd2978
1 changed files with 11 additions and 5 deletions

View File

@ -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);