From 3f877f79bfafcac8e067ab6f4ed8a3986d09f3b2 Mon Sep 17 00:00:00 2001 From: Igor Sysoev Date: Wed, 20 Apr 2016 18:30:31 +0300 Subject: [PATCH] Reserverd words can be used as property names. --- njs/njs_lexer.c | 4 ++++ njs/njs_parser.c | 17 ++++++++++++++++- njs/njs_parser.h | 2 ++ njs/njs_parser_expression.c | 22 +++++++++++++--------- njs/test/njs_unit_test.c | 6 ++++++ 5 files changed, 41 insertions(+), 10 deletions(-) diff --git a/njs/njs_lexer.c b/njs/njs_lexer.c index d3d5cb66..211086e5 100644 --- a/njs/njs_lexer.c +++ b/njs/njs_lexer.c @@ -465,6 +465,10 @@ njs_lexer_word(njs_lexer_t *lexer, u_char c) lexer->start = p; lexer->text.len = p - lexer->text.data; + if (lexer->property) { + return NJS_TOKEN_NAME; + } + return njs_lexer_keyword(lexer); } diff --git a/njs/njs_parser.c b/njs/njs_parser.c index 32e62721..f277aea8 100644 --- a/njs/njs_parser.c +++ b/njs/njs_parser.c @@ -1380,6 +1380,21 @@ njs_parser_grouping_expression(njs_vm_t *vm, njs_parser_t *parser) } +njs_token_t +njs_parser_property_token(njs_parser_t *parser) +{ + njs_token_t token; + + parser->lexer->property = 1; + + token = njs_parser_token(parser); + + parser->lexer->property = 0; + + return token; +} + + njs_token_t njs_parser_token(njs_parser_t *parser) { @@ -1711,7 +1726,7 @@ njs_parser_object(njs_vm_t *vm, njs_parser_t *parser, njs_parser_node_t *obj) left = NULL; for ( ;; ) { - token = njs_parser_token(parser); + token = njs_parser_property_token(parser); switch (token) { diff --git a/njs/njs_parser.h b/njs/njs_parser.h index f8347d1d..976d2ab5 100644 --- a/njs/njs_parser.h +++ b/njs/njs_parser.h @@ -183,6 +183,7 @@ typedef enum { typedef struct { njs_token_t token:8; njs_token_t prev_token:8; + uint8_t property; /* 1 bit */ uint32_t key_hash; nxt_str_t text; @@ -328,6 +329,7 @@ njs_token_t njs_parser_terminal(njs_vm_t *vm, njs_parser_t *parser, njs_token_t token); njs_token_t njs_parser_property_name(njs_vm_t *vm, njs_parser_t *parser, njs_token_t token); +njs_token_t njs_parser_property_token(njs_parser_t *parser); njs_token_t njs_parser_token(njs_parser_t *parser); nxt_int_t njs_parser_string_create(njs_vm_t *vm, njs_value_t *value); njs_index_t njs_parser_index(njs_parser_t *parser, uint32_t scope); diff --git a/njs/njs_parser_expression.c b/njs/njs_parser_expression.c index 11bc6d8b..c3536c2d 100644 --- a/njs/njs_parser_expression.c +++ b/njs/njs_parser_expression.c @@ -999,7 +999,6 @@ static njs_token_t njs_parser_property_expression(njs_vm_t *vm, njs_parser_t *parser, njs_token_t token) { - njs_token_t next; njs_parser_node_t *node; for ( ;; ) { @@ -1019,21 +1018,26 @@ njs_parser_property_expression(njs_vm_t *vm, njs_parser_t *parser, node->u.operation = njs_vmcode_property_get; node->left = parser->node; - next = njs_parser_token(parser); - if (nxt_slow_path(next <= NJS_TOKEN_ILLEGAL)) { - return next; - } - if (token == NJS_TOKEN_DOT) { - if (next != NJS_TOKEN_NAME) { + token = njs_parser_property_token(parser); + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) { + return token; + } + + if (token != NJS_TOKEN_NAME) { return NJS_TOKEN_ILLEGAL; } - token = njs_parser_property_name(vm, parser, next); + token = njs_parser_property_name(vm, parser, token); } else { - token = njs_parser_property_brackets(vm, parser, next); + token = njs_parser_token(parser); + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) { + return token; + } + + token = njs_parser_property_brackets(vm, parser, token); } if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) { diff --git a/njs/test/njs_unit_test.c b/njs/test/njs_unit_test.c index 01038d65..052abebd 100644 --- a/njs/test/njs_unit_test.c +++ b/njs/test/njs_unit_test.c @@ -1938,6 +1938,12 @@ static njs_unit_test_t njs_test[] = "var o = { a: 5, '[object Object]': 7 }; o[n]"), nxt_string("7") }, + { nxt_string("var o = {}; o.new = 'OK'; o.new"), + nxt_string("OK") }, + + { nxt_string("var o = { new: 'OK'}; o.new"), + nxt_string("OK") }, + /* Arrays */ /* Empty array to primitive. */ -- 2.47.3