[njs] Added async support for object initializer.
Alexander Borisov
alexander.borisov at nginx.com
Thu Sep 2 16:35:05 UTC 2021
details: https://hg.nginx.org/njs/rev/68f8f7ead0fc
branches:
changeset: 1704:68f8f7ead0fc
user: Alexander Borisov <alexander.borisov at nginx.com>
date: Thu Sep 02 19:33:32 2021 +0300
description:
Added async support for object initializer.
diffstat:
src/njs_async.c | 14 +++---
src/njs_generator.c | 3 +-
src/njs_lexer.h | 1 +
src/njs_parser.c | 86 ++++++++++++++++++++++++++++++++++++++++++++---
src/test/njs_unit_test.c | 6 +++
5 files changed, 96 insertions(+), 14 deletions(-)
diffs (229 lines):
diff -r 502be9e80244 -r 68f8f7ead0fc src/njs_async.c
--- a/src/njs_async.c Thu Sep 02 19:33:03 2021 +0300
+++ b/src/njs_async.c Thu Sep 02 19:33:32 2021 +0300
@@ -174,13 +174,6 @@ static const njs_object_prop_t njs_asyn
{
{
.type = NJS_PROPERTY,
- .name = njs_string("name"),
- .value = njs_string("AsyncFunction"),
- .configurable = 1,
- },
-
- {
- .type = NJS_PROPERTY,
.name = njs_string("length"),
.value = njs_value(NJS_NUMBER, 1, 1.0),
.configurable = 1,
@@ -204,6 +197,13 @@ static const njs_object_prop_t njs_asyn
{
{
.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),
.value = njs_string("AsyncFunction"),
.configurable = 1,
diff -r 502be9e80244 -r 68f8f7ead0fc src/njs_generator.c
--- a/src/njs_generator.c Thu Sep 02 19:33:03 2021 +0300
+++ b/src/njs_generator.c Thu Sep 02 19:33:32 2021 +0300
@@ -666,6 +666,7 @@ njs_generate(njs_vm_t *vm, njs_generator
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_
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 -r 502be9e80244 -r 68f8f7ead0fc src/njs_lexer.h
--- a/src/njs_lexer.h Thu Sep 02 19:33:03 2021 +0300
+++ b/src/njs_lexer.h Thu Sep 02 19:33:32 2021 +0300
@@ -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 -r 502be9e80244 -r 68f8f7ead0fc src/njs_parser.c
--- a/src/njs_parser.c Thu Sep 02 19:33:03 2021 +0300
+++ b/src/njs_parser.c Thu Sep 02 19:33:32 2021 +0300
@@ -58,6 +58,10 @@ static njs_int_t njs_parser_property_def
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_parse
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(
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;
-
- if (token->type == NJS_TOKEN_COLON) {
+ target->right = parser->node;
+
+ 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_
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
return NJS_ERROR;
}
+ parser->scope->async =
+ (parser->node->token_type == NJS_TOKEN_ASYNC_FUNCTION);
+
parser->node = NULL;
parser->target = expr;
diff -r 502be9e80244 -r 68f8f7ead0fc src/test/njs_unit_test.c
--- a/src/test/njs_unit_test.c Thu Sep 02 19:33:03 2021 +0300
+++ b/src/test/njs_unit_test.c Thu Sep 02 19:33:32 2021 +0300
@@ -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]") },
};
More information about the nginx-devel
mailing list