[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