]> git.kaiwu.me - njs.git/commitdiff
Parser: allow await expressions in call arguments.
authorDmitry Volyntsev <xeioex@nginx.com>
Wed, 4 Mar 2026 07:22:59 +0000 (23:22 -0800)
committerDmitry Volyntsev <xeioexception@gmail.com>
Thu, 12 Mar 2026 22:26:01 +0000 (15:26 -0700)
src/njs_parser.c
src/njs_parser.h
src/test/njs_unit_test.c

index 0ca33486a5121867f766db03933a96dddfe1db10..998ce5e77df9ba3ca0d80b1334a0087d8fd6e07d 100644 (file)
@@ -3079,8 +3079,6 @@ njs_parser_arguments(njs_parser_t *parser, njs_lexer_token_t *token,
         return njs_parser_stack_pop(parser);
     }
 
-    parser->scope->in_args++;
-
     njs_parser_next(parser, njs_parser_argument_list);
 
     return njs_parser_after(parser, current, NULL, 1,
@@ -3092,8 +3090,6 @@ static njs_int_t
 njs_parser_parenthesis_or_comma(njs_parser_t *parser, njs_lexer_token_t *token,
     njs_queue_link_t *current)
 {
-    parser->scope->in_args--;
-
     if (token->type == NJS_TOKEN_CLOSE_PARENTHESIS) {
         njs_lexer_consume_token(parser->lexer, 1);
         return njs_parser_stack_pop(parser);
@@ -3892,11 +3888,6 @@ njs_parser_await(njs_parser_t *parser, njs_lexer_token_t *token,
         return NJS_ERROR;
     }
 
-    if (parser->scope->in_args > 0) {
-        njs_parser_syntax_error(parser, "await in arguments not supported");
-        return NJS_ERROR;
-    }
-
     if (parser->scope->in_tagged_template > 0) {
         njs_parser_syntax_error(parser,
                                 "await in tagged template not supported");
index 8a1bd9dfe50bbbf2e14375fb96da5fc59eb5d4eb..387ff2b61387e3d0e25a34395febd0af3b2adaf2 100644 (file)
@@ -26,7 +26,6 @@ struct njs_parser_scope_s {
     uint8_t                         arrow_function;
     uint8_t                         dest_disable;
     uint8_t                         async;
-    uint32_t                        in_args;
     uint32_t                        in_tagged_template;
 };
 
index e718c147f2a2431e15f6d074cd2215fe1b43d117..868f9a5909d59e93f94359eac2a47cc4ce16d653 100644 (file)
@@ -20754,31 +20754,31 @@ static njs_unit_test_t  njs_test[] =
       njs_str("ReferenceError: \"AsyncFunction\" is not defined") },
 
     { njs_str("(async function() {console.log(await 111)})"),
-      njs_str("SyntaxError: await in arguments not supported") },
+      njs_str("[object AsyncFunction]") },
 
     { njs_str("(async function() {console.log('Number: ' + await 111)})"),
-      njs_str("SyntaxError: await in arguments not supported") },
+      njs_str("[object AsyncFunction]") },
 
     { njs_str("(async function() {f(await 111)})"),
-      njs_str("SyntaxError: await in arguments not supported") },
+      njs_str("[object AsyncFunction]") },
 
     { njs_str("(async function() {f(f(1), await 111)})"),
-      njs_str("SyntaxError: await in arguments not supported") },
+      njs_str("[object AsyncFunction]") },
 
     { njs_str("async () => [await x(1)(),]; async () => [await x(1)()]"),
       njs_str("[object AsyncFunction]") },
 
     { njs_str("(async function() {f(1, 'a', await 111)})"),
-      njs_str("SyntaxError: await in arguments not supported") },
+      njs_str("[object AsyncFunction]") },
 
     { njs_str("(async function() {f('Number: ' + await 111)})"),
-      njs_str("SyntaxError: await in arguments not supported") },
+      njs_str("[object AsyncFunction]") },
 
     { njs_str("async function f1() {try {f(await f1)} catch(e) {}}"),
-      njs_str("SyntaxError: await in arguments not supported") },
+      njs_str("undefined") },
 
     { njs_str("(async () => (function (){}) `${(async () => 1)(await 1)}`)()"),
-      njs_str("SyntaxError: await in arguments not supported") },
+      njs_str("SyntaxError: await in tagged template not supported") },
 
     { njs_str("(async () => (function (){}) `${await 1}`)()"),
       njs_str("SyntaxError: await in tagged template not supported") },
@@ -21540,6 +21540,54 @@ static njs_unit_test_t  njs_externals_test[] =
               "f(1).then($r.retval)"),
       njs_str("1") },
 
+    { njs_str("async function f() {"
+              "    function g(v) { return v; }"
+              "    return g(await Promise.resolve(1));"
+              "}"
+              "f().then($r.retval)"),
+      njs_str("1") },
+
+    { njs_str("async function f() {"
+              "    return ({"
+              "        g(v) { return v; }"
+              "    }).g(await Promise.resolve(2));"
+              "}"
+              "f().then($r.retval)"),
+      njs_str("2") },
+
+    { njs_str("async function f() {"
+              "    function g(a, b) { return a + b; }"
+              "    return g(await Promise.resolve(1),"
+              "             await Promise.resolve(2));"
+              "}"
+              "f().then($r.retval)"),
+      njs_str("3") },
+
+    { njs_str("async function f() {"
+              "    return ({"
+              "        k: 10,"
+              "        g(a, b) { return this.k + a + b; }"
+              "    }).g(await Promise.resolve(1),"
+              "         await Promise.resolve(2));"
+              "}"
+              "f().then($r.retval)"),
+      njs_str("13") },
+
+    { njs_str("async function f() {"
+              "    function C(v) { this.v = v; }"
+              "    return (new C(await Promise.resolve(7))).v;"
+              "}"
+              "f().then($r.retval)"),
+      njs_str("7") },
+
+    { njs_str("async function f() {"
+              "    return ({"
+              "        g(v) { return v; }"
+              "    })?.g(await Promise.resolve(9));"
+              "}"
+              "f().then($r.retval)"),
+      njs_str("9") },
+
     { njs_str("$r.retval(Promise.all([async () => [await x('X')]]))"),
       njs_str("[object Promise]") },