From 4b17dfb98c3d246a9b174de00f22cbc2af46a66c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Vouillon?= Date: Tue, 3 Oct 2023 13:34:22 +0200 Subject: [PATCH 1/3] The async keyword should not be followed by a newline Fixes #1514 --- compiler/lib/js_output.ml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/lib/js_output.ml b/compiler/lib/js_output.ml index ed9042276e..2db393ddc0 100644 --- a/compiler/lib/js_output.ml +++ b/compiler/lib/js_output.ml @@ -444,7 +444,7 @@ struct (match k with | { async = true; generator = false } -> PP.string f "async"; - PP.space f + PP.non_breaking_space f | { async = false; generator = false } -> () | { async = true | false; generator = true } -> assert false); PP.break f; @@ -882,7 +882,7 @@ struct PP.space f | { async = true; generator = false } -> PP.string f "async"; - PP.space f + PP.non_breaking_space f | { async = true; generator = true } -> PP.string f "async*"; PP.space f); From 930234343cc18cd3d640a51656f43f741f3ef728 Mon Sep 17 00:00:00 2001 From: Hugo Heuzard Date: Tue, 3 Oct 2023 15:58:40 +0200 Subject: [PATCH 2/3] more fix for async --- compiler/lib/js_parser.mly | 16 +++++++ compiler/lib/parse_js.ml | 7 +++- compiler/tests-compiler/js_parser_printer.ml | 44 +++++++++++++++++++- 3 files changed, 63 insertions(+), 4 deletions(-) diff --git a/compiler/lib/js_parser.mly b/compiler/lib/js_parser.mly index 8d7d6150a0..b409f84b67 100644 --- a/compiler/lib/js_parser.mly +++ b/compiler/lib/js_parser.mly @@ -260,6 +260,8 @@ decl: { let i,f = $1 in Function_declaration (i,f), p $symbolstartpos } | generator_decl { let i,f = $1 in Function_declaration (i,f), p $symbolstartpos } + | async_generator_decl + { let i,f = $1 in Function_declaration (i,f), p $symbolstartpos } | async_decl { let i,f = $1 in Function_declaration (i,f), p $symbolstartpos } | lexical_decl { $1, p $symbolstartpos } @@ -432,6 +434,18 @@ async_function_expr: | T_ASYNC T_FUNCTION name=ident? args=call_signature "{" b=function_body "}" { EFun (name, ({async = true; generator = false}, args, b, p $symbolstartpos)) } +(*************************************************************************) +(* async generators *) +(*************************************************************************) + +async_generator_decl: + | T_ASYNC T_FUNCTION "*" name=ident args=call_signature "{" b=function_body "}" + { (name, ({async = true; generator = true}, args, b, p $symbolstartpos)) } + +async_generator_expr: + | T_ASYNC T_FUNCTION "*" name=ident? args=call_signature "{" b=function_body "}" + { EFun (name, ({async = true; generator = true}, args, b, p $symbolstartpos)) } + (*************************************************************************) (* Class declaration *) (*************************************************************************) @@ -766,6 +780,7 @@ primary_with_stmt: | generator_expr { $1 } (* es7: *) | async_function_expr { $1 } + | async_generator_expr{ $1 } primary_expr_no_braces: @@ -988,6 +1003,7 @@ primary_for_consise_body: | generator_expr { $1 } (* es7: *) | async_function_expr { $1 } + | async_generator_expr{ $1 } assignment_expr_for_consise_body: | conditional_expr(primary_for_consise_body) { $1 } diff --git a/compiler/lib/parse_js.ml b/compiler/lib/parse_js.ml index 3a9edff265..39af863a4c 100644 --- a/compiler/lib/parse_js.ml +++ b/compiler/lib/parse_js.ml @@ -353,9 +353,12 @@ let rec offer_one t (lexbuf : Lexer.t) = * one LineTerminator, then a semicolon is automatically inserted before the * restricted token. *) match State.Cursor.last_token h, tok with - | ( Some (((T_RETURN | T_CONTINUE | T_BREAK | T_THROW | T_YIELD), _, _), _) + | ( Some + (((T_RETURN | T_CONTINUE | T_BREAK | T_THROW | T_YIELD | T_ASYNC), _, _), _) , (((T_SEMICOLON | T_VIRTUAL_SEMICOLON), _, _) as tok) ) -> tok - | Some (((T_RETURN | T_CONTINUE | T_BREAK | T_THROW | T_YIELD), _, _), _), _ + | ( Some + (((T_RETURN | T_CONTINUE | T_BREAK | T_THROW | T_YIELD | T_ASYNC), _, _), _) + , _ ) when nl_separated h tok && acceptable t T_VIRTUAL_SEMICOLON -> (* restricted token can also appear as regular identifier such as in [x.return]. In such case, feeding a virtual semicolon diff --git a/compiler/tests-compiler/js_parser_printer.ml b/compiler/tests-compiler/js_parser_printer.ml index 53014de09a..a90a260995 100644 --- a/compiler/tests-compiler/js_parser_printer.ml +++ b/compiler/tests-compiler/js_parser_printer.ml @@ -341,6 +341,20 @@ let%expect_test "async/await" = const glslang = await glslangModule.default(); return glslang.compileGLSL(src, "compute"); } + + + async + function test() { } + + async function test() { } + + async + function* test() { } + + async function * test() { } + + 1 + async function * test() { } + |}; [%expect @@ -355,7 +369,14 @@ let%expect_test "async/await" = glslang = await /*<>*/ glslangModule.default(); /*<>*/ return /*<>*/ glslang.compileGLSL (src, "compute"); - /*<>*/ } |}] + /*<>*/ } + /*<>*/ async; + /*<>*/ function test(){ /*<>*/ } + /*<>*/ async function test(){ /*<>*/ } + /*<>*/ async; + /*<>*/ function* test(){ /*<>*/ } + /*<>*/ async function* test(){ /*<>*/ } + /*<>*/ 1 + async function* test(){ /*<>*/ }; |}] let%expect_test "get/set property" = (* GH#1017 *) @@ -948,6 +969,18 @@ a:while(true){ do { x } while (true) y do ; while (true) y + async + function test() { } + + async function test() { } + + async + function* test() { } + + async function * test() { } + + 1 + async function * test() { } + |}; [%expect {| @@ -974,7 +1007,14 @@ a:while(true){ 26: 4:a (identifier), 6:=, 8:b (identifier), 10:+, 12:c (identifier), 27: 4:(, 5:d (identifier), 7:+, 9:e (identifier), 10:), 11:., 12:print (identifier), 17:(, 18:), 0:; (virtual), 29: 4:do, 7:{, 9:x (identifier), 0:; (virtual), 11:}, 13:while, 19:(, 20:true, 24:), 0:; (virtual), 26:y (identifier), 0:; (virtual), - 30: 4:do, 7:;, 9:while, 15:(, 16:true, 20:), 0:; (virtual), 22:y (identifier), 0:; (virtual), |}] + 30: 4:do, 7:;, 9:while, 15:(, 16:true, 20:), 0:; (virtual), 22:y (identifier), 0:; (virtual), + 32: 4:async, 0:; (virtual), + 33: 4:function, 13:test (identifier), 17:(, 18:), 20:{, 22:}, + 35: 4:async, 10:function, 19:test (identifier), 23:(, 24:), 26:{, 28:}, + 37: 4:async, 0:; (virtual), + 38: 4:function, 12:*, 14:test (identifier), 18:(, 19:), 21:{, 23:}, + 40: 4:async, 10:function, 19:*, 21:test (identifier), 25:(, 26:), 28:{, 30:}, + 42: 4:1, 6:+, 8:async, 14:function, 23:*, 25:test (identifier), 29:(, 30:), 32:{, 34:}, 0:; (virtual), |}] let%expect_test _ = parse_print_token From 040b829b77ac2b366b4f2f105162f08441c3959b Mon Sep 17 00:00:00 2001 From: Hugo Heuzard Date: Wed, 4 Oct 2023 10:35:07 +0200 Subject: [PATCH 3/3] Changes --- CHANGES.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 0d4c5ba81d..1ff50f9620 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -9,8 +9,9 @@ ## Bug fixes * Runtime: fix Dom_html.onIE (#1493) -* Compiler: fix global flow analysis (#1494) * Runtime: add conversion functions + strict equality for compatibility with Wasm_of_ocaml (#1492) +* Compiler: fix global flow analysis (#1494) +* COmpiler: fix js parser/printer wrt async functions (#1515) # 5.4.0 (2023-07-06) - Lille