]> git.kaiwu.me - njs.git/commitdiff
Parser: allow await expressions in tagged templates.
authorDmitry Volyntsev <xeioex@nginx.com>
Wed, 4 Mar 2026 23:16:15 +0000 (15:16 -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 998ce5e77df9ba3ca0d80b1334a0087d8fd6e07d..93811746679f9739b7c947c4b362a7bc58a5d843 100644 (file)
@@ -2274,8 +2274,6 @@ static njs_int_t
 njs_parser_tagged_template_literal_after(njs_parser_t *parser,
     njs_lexer_token_t *token, njs_queue_link_t *current)
 {
-    parser->scope->in_tagged_template--;
-
     return njs_parser_stack_pop(parser);
 }
 
@@ -2359,8 +2357,6 @@ njs_parser_property(njs_parser_t *parser, njs_lexer_token_t *token,
 
         parser->node = node;
 
-        parser->scope->in_tagged_template++;
-
         njs_parser_next(parser, njs_parser_template_literal);
 
         return njs_parser_after(parser, current, node, 1,
@@ -3888,12 +3884,6 @@ njs_parser_await(njs_parser_t *parser, njs_lexer_token_t *token,
         return NJS_ERROR;
     }
 
-    if (parser->scope->in_tagged_template > 0) {
-        njs_parser_syntax_error(parser,
-                                "await in tagged template not supported");
-        return NJS_ERROR;
-    }
-
     node = njs_parser_node_new(parser, NJS_TOKEN_AWAIT);
     if (njs_slow_path(node == NULL)) {
         return NJS_ERROR;
index 387ff2b61387e3d0e25a34395febd0af3b2adaf2..1e760454dedc6598ac7cdd5404e1d4bfc11010a5 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_tagged_template;
 };
 
 
index 868f9a5909d59e93f94359eac2a47cc4ce16d653..c9f77cdd3a331d050acaf0ad759341462cd0dfb2 100644 (file)
@@ -20778,10 +20778,16 @@ static njs_unit_test_t  njs_test[] =
       njs_str("undefined") },
 
     { njs_str("(async () => (function (){}) `${(async () => 1)(await 1)}`)()"),
-      njs_str("SyntaxError: await in tagged template not supported") },
+      njs_str("[object Promise]") },
 
     { njs_str("(async () => (function (){}) `${await 1}`)()"),
-      njs_str("SyntaxError: await in tagged template not supported") },
+      njs_str("[object Promise]") },
+
+    { njs_str("(async () => ({"
+              "    x: 7,"
+              "    t(...a) { return this.x + ':' + a[1]; }"
+              "}).t`${await 2}`)()"),
+      njs_str("[object Promise]") },
 
     { njs_str("async function af() {await encrypt({},}"),
       njs_str("SyntaxError: Unexpected token \"}\"") },
@@ -21588,6 +21594,46 @@ static njs_unit_test_t  njs_externals_test[] =
               "f().then($r.retval)"),
       njs_str("9") },
 
+    { njs_str("async function f() {"
+              "    return ((...a) => a[1])`${await Promise.resolve(1)}`;"
+              "}"
+              "f().then($r.retval)"),
+      njs_str("1") },
+
+    { njs_str("async function f() {"
+              "    return ((...a) => a[1])`${await Promise.resolve(2)}`"
+              "           + ':' +"
+              "           ((...a) => a[1])`${await Promise.resolve(3)}`;"
+              "}"
+              "f().then($r.retval)"),
+      njs_str("2:3") },
+
+    { njs_str("async function f() {"
+              "    return ({"
+              "        x: 'X',"
+              "        t(...a) { return this.x + ':' + a[1]; }"
+              "    }).t`${await Promise.resolve(4)}`;"
+              "}"
+              "f().then($r.retval)"),
+      njs_str("X:4") },
+
+    { njs_str("async function f() {"
+              "    return ((...a) => a[1] + ':' + a[2] + ':' + a[0].length)"
+              "           `a${await Promise.resolve(2)}b"
+              "${await Promise.resolve(3)}c`;"
+              "}"
+              "f().then($r.retval)"),
+      njs_str("2:3:3") },
+
+    { njs_str("async function f() {"
+              "    var log = '';"
+              "    function p(v) { log += v; return Promise.resolve(v); }"
+              "    function t() { log += 'T'; return log; }"
+              "    return t`${await p('A')}${await p('B')}`;"
+              "}"
+              "f().then($r.retval)"),
+      njs_str("ABT") },
+
     { njs_str("$r.retval(Promise.all([async () => [await x('X')]]))"),
       njs_str("[object Promise]") },