Created
February 8, 2019 18:19
-
-
Save xeioex/1664cc5c76a6e8da12cc4e5d8abcfbeb to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # HG changeset patch | |
| # User Dmitry Volyntsev <[email protected]> | |
| # Date 1549649826 -10800 | |
| # Fri Feb 08 21:17:06 2019 +0300 | |
| # Node ID 964ddb99f52d383b9e3f024bab64501c73da8eb8 | |
| # Parent 4e8940c1bef19a4b0a4e6d5206b3884f42739126 | |
| Added support for shorthand property names for Object literals. | |
| diff --git a/njs/njs_lexer.c b/njs/njs_lexer.c | |
| --- a/njs/njs_lexer.c | |
| +++ b/njs/njs_lexer.c | |
| @@ -459,7 +459,9 @@ njs_lexer_next_token(njs_lexer_t *lexer) | |
| static njs_token_t | |
| njs_lexer_word(njs_lexer_t *lexer, u_char c) | |
| { | |
| - u_char *p; | |
| + u_char *p; | |
| + njs_token_t token; | |
| + | |
| /* TODO: UTF-8 */ | |
| @@ -498,11 +500,14 @@ njs_lexer_word(njs_lexer_t *lexer, u_cha | |
| lexer->start = p; | |
| lexer->text.length = p - lexer->text.start; | |
| + token = njs_lexer_keyword(lexer); | |
| + | |
| if (lexer->property) { | |
| + lexer->property_token = token; | |
| return NJS_TOKEN_NAME; | |
| } | |
| - return njs_lexer_keyword(lexer); | |
| + return token; | |
| } | |
| diff --git a/njs/njs_parser.c b/njs/njs_parser.c | |
| --- a/njs/njs_parser.c | |
| +++ b/njs/njs_parser.c | |
| @@ -2167,13 +2167,28 @@ njs_parser_builtin_function(njs_vm_t *vm | |
| } | |
| +/* | |
| + * ES6: 12.2.6 Object Initializer | |
| + * Supported syntax: | |
| + * PropertyDefinition: | |
| + * PropertyName : AssignmentExpression | |
| + * IdentifierReference | |
| + * PropertyName: | |
| + * IdentifierName, StringLiteral, NumericLiteral. | |
| + */ | |
| static njs_token_t | |
| njs_parser_object(njs_vm_t *vm, njs_parser_t *parser, njs_parser_node_t *obj) | |
| { | |
| + uint32_t hash; | |
| + nxt_str_t name; | |
| + njs_ret_t ret; | |
| + nxt_bool_t identifier; | |
| + njs_lexer_t *lexer; | |
| njs_token_t token; | |
| - njs_parser_node_t *stmt, *assign, *object, *propref, *left; | |
| + njs_parser_node_t *stmt, *assign, *object, *propref, *left, *expression; | |
| left = NULL; | |
| + lexer = parser->lexer; | |
| object = njs_parser_node_new(vm, parser, NJS_TOKEN_OBJECT_VALUE); | |
| if (nxt_slow_path(object == NULL)) { | |
| @@ -2183,6 +2198,8 @@ njs_parser_object(njs_vm_t *vm, njs_pars | |
| object->u.object = obj; | |
| for ( ;; ) { | |
| + identifier = 0; | |
| + | |
| token = njs_parser_property_token(parser); | |
| switch (token) { | |
| @@ -2191,6 +2208,12 @@ njs_parser_object(njs_vm_t *vm, njs_pars | |
| return njs_parser_token(parser); | |
| case NJS_TOKEN_NAME: | |
| + if (lexer->property_token == NJS_TOKEN_NAME) { | |
| + identifier = 1; | |
| + name = lexer->text; | |
| + hash = lexer->key_hash; | |
| + } | |
| + | |
| token = njs_parser_property_name(vm, parser); | |
| break; | |
| @@ -2216,14 +2239,32 @@ njs_parser_object(njs_vm_t *vm, njs_pars | |
| propref->left = object; | |
| propref->right = parser->node; | |
| - token = njs_parser_match(vm, parser, token, NJS_TOKEN_COLON); | |
| - if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) { | |
| - return token; | |
| - } | |
| - | |
| - token = njs_parser_assignment_expression(vm, parser, token); | |
| - if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) { | |
| - return token; | |
| + if (identifier | |
| + && (token == NJS_TOKEN_COMMA || token == NJS_TOKEN_CLOSE_BRACE)) | |
| + { | |
| + expression = njs_parser_node_new(vm, parser, NJS_TOKEN_NAME); | |
| + if (nxt_slow_path(expression == NULL)) { | |
| + return NJS_TOKEN_ERROR; | |
| + } | |
| + | |
| + ret = njs_variable_reference(vm, parser->scope, expression, &name, | |
| + hash, NJS_REFERENCE); | |
| + if (nxt_slow_path(ret != NXT_OK)) { | |
| + return NJS_TOKEN_ERROR; | |
| + } | |
| + | |
| + } else { | |
| + token = njs_parser_match(vm, parser, token, NJS_TOKEN_COLON); | |
| + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) { | |
| + return token; | |
| + } | |
| + | |
| + token = njs_parser_assignment_expression(vm, parser, token); | |
| + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) { | |
| + return token; | |
| + } | |
| + | |
| + expression = parser->node; | |
| } | |
| assign = njs_parser_node_new(vm, parser, NJS_TOKEN_ASSIGNMENT); | |
| @@ -2233,7 +2274,7 @@ njs_parser_object(njs_vm_t *vm, njs_pars | |
| assign->u.operation = njs_vmcode_move; | |
| assign->left = propref; | |
| - assign->right = parser->node; | |
| + assign->right = expression; | |
| stmt = njs_parser_node_new(vm, parser, NJS_TOKEN_STATEMENT); | |
| if (nxt_slow_path(stmt == NULL)) { | |
| diff --git a/njs/njs_parser.h b/njs/njs_parser.h | |
| --- a/njs/njs_parser.h | |
| +++ b/njs/njs_parser.h | |
| @@ -210,7 +210,10 @@ typedef enum { | |
| typedef struct { | |
| njs_token_t token:16; | |
| njs_token_t prev_token:16; | |
| + | |
| uint8_t property; /* 1 bit */ | |
| + njs_token_t property_token:16; | |
| + | |
| uint32_t key_hash; | |
| uint32_t token_line; | |
| diff --git a/njs/test/njs_unit_test.c b/njs/test/njs_unit_test.c | |
| --- a/njs/test/njs_unit_test.c | |
| +++ b/njs/test/njs_unit_test.c | |
| @@ -2770,6 +2770,29 @@ static njs_unit_test_t njs_test[] = | |
| { nxt_string("delete undefined"), | |
| nxt_string("SyntaxError: Delete of an unqualified identifier in 1") }, | |
| + /* Shorthand Object literals. */ | |
| + | |
| + { nxt_string("var a = 1; njs.dump({a})"), | |
| + nxt_string("{a:1}") }, | |
| + | |
| + { nxt_string("var a = 1, b; njs.dump({a,b})"), | |
| + nxt_string("{a:1,b:undefined}") }, | |
| + | |
| + { nxt_string("var a = 1, b = 2; ({a,b,c})"), | |
| + nxt_string("ReferenceError: \"c\" is not defined in 1") }, | |
| + | |
| + { nxt_string("var a = 1, b = 2; njs.dump({a,b,c:3})"), | |
| + nxt_string("{a:1,b:2,c:3}") }, | |
| + | |
| + { nxt_string("var b = 2, c = 3; njs.dump({a:1,b,c})"), | |
| + nxt_string("{a:1,b:2,c:3}") }, | |
| + | |
| + { nxt_string("({default})"), | |
| + nxt_string("SyntaxError: Unexpected token \"}\" in 1") }, | |
| + | |
| + { nxt_string("({this})"), | |
| + nxt_string("SyntaxError: Unexpected token \"}\" in 1") }, | |
| + | |
| /* ES5FIX: "SyntaxError". */ | |
| { nxt_string("delete NaN"), |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment