From: Alexander Borisov Date: Thu, 2 Sep 2021 16:33:32 +0000 (+0300) Subject: Added async support for object initializer. X-Git-Tag: 0.7.0~22 X-Git-Url: http://www.kaiwu.me/postgresql/commit/?a=commitdiff_plain;h=5a7ea47e82e9c1f922f31c8dac433ad17bc4f6b5;p=njs.git Added async support for object initializer. --- diff --git a/src/njs_async.c b/src/njs_async.c index 97ce87ff..f27c2eeb 100644 --- a/src/njs_async.c +++ b/src/njs_async.c @@ -172,13 +172,6 @@ njs_async_context_free(njs_vm_t *vm, njs_async_ctx_t *ctx) static const njs_object_prop_t njs_async_constructor_properties[] = { - { - .type = NJS_PROPERTY, - .name = njs_string("name"), - .value = njs_string("AsyncFunction"), - .configurable = 1, - }, - { .type = NJS_PROPERTY, .name = njs_string("length"), @@ -202,6 +195,13 @@ const njs_object_init_t njs_async_constructor_init = { static const njs_object_prop_t njs_async_prototype_properties[] = { + { + .type = NJS_PROPERTY, + .name = njs_string("name"), + .value = njs_string("AsyncFunction"), + .configurable = 1, + }, + { .type = NJS_PROPERTY, .name = njs_wellknown_symbol(NJS_SYMBOL_TO_STRING_TAG), diff --git a/src/njs_generator.c b/src/njs_generator.c index eb32411c..f2e3bde9 100644 --- a/src/njs_generator.c +++ b/src/njs_generator.c @@ -666,6 +666,7 @@ njs_generate(njs_vm_t *vm, njs_generator_t *generator, njs_parser_node_t *node) return njs_generate_function_expression(vm, generator, node); case NJS_TOKEN_FUNCTION: + case NJS_TOKEN_ASYNC_FUNCTION: return njs_generate_function(vm, generator, node); case NJS_TOKEN_REGEXP: @@ -3100,7 +3101,7 @@ njs_generate_function(njs_vm_t *vm, njs_generator_t *generator, njs_generate_code(generator, njs_vmcode_function_t, function, NJS_VMCODE_FUNCTION, 1, node); function->lambda = lambda; - function->async = 0; + function->async = (node->token_type == NJS_TOKEN_ASYNC_FUNCTION); node->index = njs_generate_object_dest_index(vm, generator, node); if (njs_slow_path(node->index == NJS_INDEX_ERROR)) { diff --git a/src/njs_lexer.h b/src/njs_lexer.h index b20c5934..e3bd1dc8 100644 --- a/src/njs_lexer.h +++ b/src/njs_lexer.h @@ -148,6 +148,7 @@ typedef enum { NJS_TOKEN_ARGUMENT, NJS_TOKEN_RETURN, + NJS_TOKEN_ASYNC_FUNCTION, NJS_TOKEN_ASYNC_FUNCTION_DECLARATION, NJS_TOKEN_ASYNC_FUNCTION_EXPRESSION, diff --git a/src/njs_parser.c b/src/njs_parser.c index 8ea51c26..cc366320 100644 --- a/src/njs_parser.c +++ b/src/njs_parser.c @@ -58,6 +58,10 @@ static njs_int_t njs_parser_property_definition_after(njs_parser_t *parser, njs_lexer_token_t *token, njs_queue_link_t *current); static njs_int_t njs_parser_computed_property_name_after(njs_parser_t *parser, njs_lexer_token_t *token, njs_queue_link_t *current); +static njs_int_t njs_parser_computed_property_async_after(njs_parser_t *parser, + njs_lexer_token_t *token, njs_queue_link_t *current); +static njs_int_t njs_parser_computed_property_name_handler(njs_parser_t *parser, + njs_lexer_token_t *token, njs_queue_link_t *current, njs_bool_t async); static njs_int_t njs_parser_initializer(njs_parser_t *parser, njs_lexer_token_t *token, njs_queue_link_t *current); @@ -1931,6 +1935,38 @@ njs_parser_property_definition(njs_parser_t *parser, njs_lexer_token_t *token, case NJS_TOKEN_ELLIPSIS: return njs_parser_not_supported(parser, token); + case NJS_TOKEN_ASYNC: + token = njs_lexer_peek_token(parser->lexer, token, 0); + if (token == NULL) { + return NJS_ERROR; + } + + if (token->type == NJS_TOKEN_OPEN_BRACKET) { + njs_lexer_consume_token(parser->lexer, 2); + + njs_parser_next(parser, njs_parser_assignment_expression); + + return njs_parser_after(parser, current, temp, 1, + njs_parser_computed_property_async_after); + } + + if (!njs_lexer_token_is_identifier_name(token)) { + return njs_parser_failed(parser); + } + + next = njs_lexer_peek_token(parser->lexer, token, 0); + if (next == NULL) { + return NJS_ERROR; + } + + if (next->type == NJS_TOKEN_OPEN_PARENTHESIS) { + goto method_definition; + } + + njs_lexer_consume_token(parser->lexer, 1); + + return njs_parser_failed(parser); + default: if (!njs_lexer_token_is_identifier_name(token)) { return njs_parser_reject(parser); @@ -2044,7 +2080,24 @@ static njs_int_t njs_parser_computed_property_name_after(njs_parser_t *parser, njs_lexer_token_t *token, njs_queue_link_t *current) { - njs_parser_node_t *expr; + return njs_parser_computed_property_name_handler(parser, token, current, 0); +} + + +static njs_int_t +njs_parser_computed_property_async_after(njs_parser_t *parser, + njs_lexer_token_t *token, njs_queue_link_t *current) +{ + return njs_parser_computed_property_name_handler(parser, token, current, 1); +} + + +static njs_int_t +njs_parser_computed_property_name_handler(njs_parser_t *parser, + njs_lexer_token_t *token, njs_queue_link_t *current, njs_bool_t async) +{ + njs_token_type_t type; + njs_parser_node_t *expr, *target; if (token->type != NJS_TOKEN_CLOSE_BRACKET) { return njs_parser_failed(parser); @@ -2057,20 +2110,24 @@ njs_parser_computed_property_name_after(njs_parser_t *parser, return NJS_ERROR; } + target = parser->target; + /* * For further identification. * In njs_parser_property_definition_after() index will be reset to zero. */ parser->node->index = NJS_TOKEN_OPEN_BRACKET; - parser->target->right = parser->node; + target->right = parser->node; - if (token->type == NJS_TOKEN_COLON) { + if (!async && token->type == NJS_TOKEN_COLON) { return njs_parser_property_name(parser, current, 1); /* MethodDefinition */ } else if (token->type == NJS_TOKEN_OPEN_PARENTHESIS) { - expr = njs_parser_node_new(parser, NJS_TOKEN_FUNCTION); + type = (async) ? NJS_TOKEN_ASYNC_FUNCTION : NJS_TOKEN_FUNCTION; + + expr = njs_parser_node_new(parser, type); if (expr == NULL) { return NJS_ERROR; } @@ -7196,9 +7253,23 @@ static njs_int_t njs_parser_method_definition(njs_parser_t *parser, njs_lexer_token_t *token, njs_queue_link_t *current) { + njs_token_type_t type; njs_lexer_token_t *next; njs_parser_node_t *expr; + type = NJS_TOKEN_FUNCTION; + + if (token->type == NJS_TOKEN_ASYNC) { + njs_lexer_consume_token(parser->lexer, 1); + + token = njs_lexer_token(parser->lexer, 0); + if (token == NULL) { + return NJS_ERROR; + } + + type = NJS_TOKEN_ASYNC_FUNCTION; + } + switch (token->type) { /* PropertyName */ case NJS_TOKEN_STRING: @@ -7225,7 +7296,7 @@ njs_parser_method_definition(njs_parser_t *parser, njs_lexer_token_t *token, return njs_parser_failed(parser); } - expr = njs_parser_node_new(parser, NJS_TOKEN_FUNCTION); + expr = njs_parser_node_new(parser, type); if (expr == NULL) { return NJS_ERROR; } @@ -7453,6 +7524,9 @@ njs_parser_function_lambda(njs_parser_t *parser, return NJS_ERROR; } + parser->scope->async = + (parser->node->token_type == NJS_TOKEN_ASYNC_FUNCTION); + parser->node = NULL; parser->target = expr; diff --git a/src/test/njs_unit_test.c b/src/test/njs_unit_test.c index 3e0d4dcc..5dd2318c 100644 --- a/src/test/njs_unit_test.c +++ b/src/test/njs_unit_test.c @@ -20520,6 +20520,12 @@ static njs_unit_test_t njs_test[] = { njs_str("async function af() {await encrypt({},}"), njs_str("SyntaxError: Unexpected token \"}\" in 1") }, + + { njs_str("let x = {async af() {await Promise.resolve(1)}}; x.af"), + njs_str("[object AsyncFunction]") }, + + { njs_str("let name = 'af', x = {async [name]() {await Promise.resolve(1)}}; x.af"), + njs_str("[object AsyncFunction]") }, };