diff --git a/Changes.md b/Changes.md index d192ea884..b5ad535d6 100644 --- a/Changes.md +++ b/Changes.md @@ -134,6 +134,9 @@ Unreleased - Upgrade the Melange JS parser to [Flow v0.225.1](https://github.com/facebook/flow/releases/tag/v0.225.1) ([#1012](https://github.com/melange-re/melange/pull/1012)) +- fix: add a newline after `%mel.raw` expressions to avoid breaking JS output + when they contain single line comments + ([#1017](https://github.com/melange-re/melange/pull/1017)) 2.2.0 2023-12-05 --------------- diff --git a/jscomp/core/js_dump.ml b/jscomp/core/js_dump.ml index e6cb13b79..58153629e 100644 --- a/jscomp/core/js_dump.ml +++ b/jscomp/core/js_dump.ml @@ -663,7 +663,9 @@ and expression_desc cxt ~(level : int) x : cxt = in if raw_paren then string cxt L.lparen; string cxt s; - if raw_paren then string cxt L.rparen; + if raw_paren then ( + newline cxt; + string cxt L.rparen); cxt | Stmt stmt_info -> if stmt_info = Js_stmt_comment then string cxt s diff --git a/jscomp/core/js_exp_make.ml b/jscomp/core/js_exp_make.ml index 42263a11b..cd8ca59c3 100644 --- a/jscomp/core/js_exp_make.ml +++ b/jscomp/core/js_exp_make.ml @@ -139,7 +139,15 @@ let unicode ?loc ?comment s : t = make_expression ?loc ?comment (Unicode s) let raw_js_code ?loc ?comment info s : t = make_expression ?loc ?comment - (Raw_js_code { code = String.trim s; code_info = info }) + (Raw_js_code + { + code = + (* FIXME: save one allocation + trim can not be done before syntax checking + otherwise location is incorrect *) + String.trim s; + code_info = info; + }) let array ?loc ?comment mt es : t = make_expression ?loc ?comment (Array (es, mt)) diff --git a/jscomp/core/lam_compile_primitive.ml b/jscomp/core/lam_compile_primitive.ml index 9f809266d..1f17858fb 100644 --- a/jscomp/core/lam_compile_primitive.ml +++ b/jscomp/core/lam_compile_primitive.ml @@ -44,12 +44,7 @@ let translate loc (cxt : Lam_compile_context.t) (prim : Lam_primitive.t) | Pwrap_exn -> E.runtime_call Js_runtime_modules.caml_js_exceptions "internalToOCamlException" args - | Praw_js_code { code; code_info } -> - E.raw_js_code code_info code - (* FIXME: save one allocation - trim can not be done before syntax checking - otherwise location is incorrect - *) + | Praw_js_code { code; code_info } -> E.raw_js_code code_info code | Pjs_runtime_apply -> ( match args with [ f; args ] -> E.flat_call f args | _ -> assert false) | Pjs_apply -> ( diff --git a/jscomp/test/dist/jscomp/test/bs_hashtbl_string_test.js b/jscomp/test/dist/jscomp/test/bs_hashtbl_string_test.js index 8edd36346..97be2944b 100644 --- a/jscomp/test/dist/jscomp/test/bs_hashtbl_string_test.js +++ b/jscomp/test/dist/jscomp/test/bs_hashtbl_string_test.js @@ -23,7 +23,8 @@ var hashString = (function(str){ while(i !== 0) { hash = (hash * 33) ^ str.charCodeAt(--i); } - return hash}); + return hash} +); var $$String = Belt__Belt_Id.hashable(Stdlib__Hashtbl.hash, (function (x, y) { return x === y; diff --git a/jscomp/test/dist/jscomp/test/bs_node_string_buffer_test.js b/jscomp/test/dist/jscomp/test/bs_node_string_buffer_test.js index 00d2849c4..03afecd4c 100644 --- a/jscomp/test/dist/jscomp/test/bs_node_string_buffer_test.js +++ b/jscomp/test/dist/jscomp/test/bs_node_string_buffer_test.js @@ -20,7 +20,8 @@ function f(str) { f("xx"); -f((Buffer.from ('xx'))); +f((Buffer.from ('xx') + )); exports.f = f; /* Not a pure module */ diff --git a/jscomp/test/dist/jscomp/test/caml_compare_test.js b/jscomp/test/dist/jscomp/test/caml_compare_test.js index 123ba811e..4e805db10 100644 --- a/jscomp/test/dist/jscomp/test/caml_compare_test.js +++ b/jscomp/test/dist/jscomp/test/caml_compare_test.js @@ -999,7 +999,8 @@ var suites = { (function (param) { return { TAG: /* Eq */0, - _0: Caml_obj.caml_equal({x:1}, ((function(){let o = Object.create(null);o.x = 1;return o;})())), + _0: Caml_obj.caml_equal({x:1}, ((function(){let o = Object.create(null);o.x = 1;return o;})() + )), _1: true }; }) diff --git a/jscomp/test/dist/jscomp/test/epsilon_test.js b/jscomp/test/dist/jscomp/test/epsilon_test.js index 0e0cb4935..8c06007cf 100644 --- a/jscomp/test/dist/jscomp/test/epsilon_test.js +++ b/jscomp/test/dist/jscomp/test/epsilon_test.js @@ -4,7 +4,8 @@ var Mt = require("./mt.js"); var Stdlib = require("melange/stdlib.js"); -var v = (Number.EPSILON?Number.EPSILON:2.220446049250313e-16); +var v = (Number.EPSILON?Number.EPSILON:2.220446049250313e-16 +); var suites_0 = [ "epsilon", diff --git a/jscomp/test/dist/jscomp/test/exception_raise_test.js b/jscomp/test/dist/jscomp/test/exception_raise_test.js index a8af51883..4e5222398 100644 --- a/jscomp/test/dist/jscomp/test/exception_raise_test.js +++ b/jscomp/test/dist/jscomp/test/exception_raise_test.js @@ -64,7 +64,8 @@ var A = /* @__PURE__ */Caml_exceptions.create("Exception_raise_test.A"); var f; try { - f = (function () {throw (new Error ("x"))} ()); + f = (function () {throw (new Error ("x"))} () + ); } catch (raw_exn){ var exn = Caml_js_exceptions.internalToOCamlException(raw_exn); @@ -74,7 +75,8 @@ catch (raw_exn){ var ff; try { - ff = (function () {throw 3} ()); + ff = (function () {throw 3} () + ); } catch (raw_exn$1){ var exn$1 = Caml_js_exceptions.internalToOCamlException(raw_exn$1); @@ -84,7 +86,8 @@ catch (raw_exn$1){ var fff; try { - fff = (function () {throw 2} ()); + fff = (function () {throw 2} () + ); } catch (raw_exn$2){ var exn$2 = Caml_js_exceptions.internalToOCamlException(raw_exn$2); @@ -94,7 +97,8 @@ catch (raw_exn$2){ var a0; try { - a0 = (function (){throw 2} ()); + a0 = (function (){throw 2} () + ); } catch (raw_exn$3){ var exn$3 = Caml_js_exceptions.internalToOCamlException(raw_exn$3); @@ -116,7 +120,8 @@ catch (raw_exn$3){ var a1; try { - a1 = (function (){throw 2} ()); + a1 = (function (){throw 2} () + ); } catch (raw_e){ a1 = Caml_js_exceptions.internalToOCamlException(raw_e); @@ -125,7 +130,8 @@ catch (raw_e){ var a2; try { - a2 = (function (){throw (new Error("x"))} ()); + a2 = (function (){throw (new Error("x"))} () + ); } catch (raw_e$1){ a2 = Caml_js_exceptions.internalToOCamlException(raw_e$1); @@ -189,7 +195,8 @@ function eq(loc, x, y) { } try { - ((()=>{throw 2})()); + ((()=>{throw 2} + )()); } catch (raw_e$2){ var e = Caml_js_exceptions.internalToOCamlException(raw_e$2); @@ -236,7 +243,8 @@ function input_lines(ic, _acc) { }; } -eq("File \"jscomp/test/exception_raise_test.ml\", line 150, characters 5-12", ((a,b,c,_) => a + b + c)(1, 2, 3, 4), 6); +eq("File \"jscomp/test/exception_raise_test.ml\", line 150, characters 5-12", ((a,b,c,_) => a + b + c + )(1, 2, 3, 4), 6); Mt.from_pair_suites("Exception_raise_test", suites.contents); diff --git a/jscomp/test/dist/jscomp/test/ffi_arity_test.js b/jscomp/test/dist/jscomp/test/ffi_arity_test.js index db8345bc6..12b5daa48 100644 --- a/jscomp/test/dist/jscomp/test/ffi_arity_test.js +++ b/jscomp/test/dist/jscomp/test/ffi_arity_test.js @@ -122,7 +122,8 @@ function bar(fn) { return Curry._1(fn, undefined); } -(Curry._1((function(){console.log("forgiving arity")}), undefined)); +(Curry._1((function(){console.log("forgiving arity")} + ), undefined)); exports.f = f; exports.v = v; diff --git a/jscomp/test/dist/jscomp/test/ffi_js_test.js b/jscomp/test/dist/jscomp/test/ffi_js_test.js index 5f1c12140..52c061ed2 100644 --- a/jscomp/test/dist/jscomp/test/ffi_js_test.js +++ b/jscomp/test/dist/jscomp/test/ffi_js_test.js @@ -3,7 +3,8 @@ var Mt = require("./mt.js"); -var keys = (function (x){return Object.keys(x)}); +var keys = (function (x){return Object.keys(x)} +); function $$higher_order(x){ return function(y,z){ diff --git a/jscomp/test/dist/jscomp/test/flow_parser_reg_test.js b/jscomp/test/dist/jscomp/test/flow_parser_reg_test.js index 7ca405ae7..cc74f1d7b 100644 --- a/jscomp/test/dist/jscomp/test/flow_parser_reg_test.js +++ b/jscomp/test/dist/jscomp/test/flow_parser_reg_test.js @@ -15430,15 +15430,20 @@ var translation_errors = { contents: /* [] */0 }; -var string = (function (x) {return x;}); +var string = (function (x) {return x;} +); -var bool = (function (x) {x ? 1 : 0;}); +var bool = (function (x) {x ? 1 : 0;} +); -var obj = (function(arr) {var ret = {}; arr.forEach(function(a) {ret[a[0]]=a[1];}); return ret}); +var obj = (function(arr) {var ret = {}; arr.forEach(function(a) {ret[a[0]]=a[1];}); return ret} +); -var array = (function (x) {return x;}); +var array = (function (x) {return x;} +); -var number$1 = (function (x) {return x;}); +var number$1 = (function (x) {return x;} +); var $$null = null; diff --git a/jscomp/test/dist/jscomp/test/gpr_2682_test.js b/jscomp/test/dist/jscomp/test/gpr_2682_test.js index 3c40cd7e0..9ba777bdb 100644 --- a/jscomp/test/dist/jscomp/test/gpr_2682_test.js +++ b/jscomp/test/dist/jscomp/test/gpr_2682_test.js @@ -2,7 +2,8 @@ 'use strict'; -var sum = ((a,b) => a + b); +var sum = ((a,b) => a + b +); var v = sum(1, 2); @@ -18,7 +19,8 @@ var forIn = ((o,foo)=> { for (var i in o){ foo(o) } - }); + } +); function log(x) { console.log(x); @@ -41,7 +43,8 @@ forIn({ console.log(x); })); -var f3 = (()=>true); +var f3 = (()=>true +); var bbbb = f3(); diff --git a/jscomp/test/dist/jscomp/test/gpr_4442_test.js b/jscomp/test/dist/jscomp/test/gpr_4442_test.js index d09ea1d07..275b1dfd6 100644 --- a/jscomp/test/dist/jscomp/test/gpr_4442_test.js +++ b/jscomp/test/dist/jscomp/test/gpr_4442_test.js @@ -20,7 +20,8 @@ var u = (function fib(n){ return 1 } return fib(n-1) + fib(n-2) -}); +} +); eq("File \"jscomp/test/gpr_4442_test.ml\", line 14, characters 6-13", u(2), 2); diff --git a/jscomp/test/dist/jscomp/test/polymorphic_raw_test.js b/jscomp/test/dist/jscomp/test/polymorphic_raw_test.js index 34cbc4dca..397ff81bd 100644 --- a/jscomp/test/dist/jscomp/test/polymorphic_raw_test.js +++ b/jscomp/test/dist/jscomp/test/polymorphic_raw_test.js @@ -28,7 +28,8 @@ function eq(loc, x, y) { }; } -var f = ((a) => typeof a); +var f = ((a) => typeof a +); var a = f(3); diff --git a/jscomp/test/dist/jscomp/test/raw_output_test.js b/jscomp/test/dist/jscomp/test/raw_output_test.js index 1eff4d43c..be06893a9 100644 --- a/jscomp/test/dist/jscomp/test/raw_output_test.js +++ b/jscomp/test/dist/jscomp/test/raw_output_test.js @@ -7,7 +7,8 @@ function mk(fn) { return Curry._1(fn, undefined); } -(((_)=> console.log('should works'))(undefined)); +(((_)=> console.log('should works') + )(undefined)); console.log((function () { return 1; diff --git a/jscomp/test/dist/jscomp/test/re_or_res/reasonReactOptimizedCreateClass.js b/jscomp/test/dist/jscomp/test/re_or_res/reasonReactOptimizedCreateClass.js index 8f6a418e3..d3c256654 100644 --- a/jscomp/test/dist/jscomp/test/re_or_res/reasonReactOptimizedCreateClass.js +++ b/jscomp/test/dist/jscomp/test/re_or_res/reasonReactOptimizedCreateClass.js @@ -879,7 +879,8 @@ var factory = (function factory(ReactComponent, isValidElement, ReactNoopUpdateQ } return createClass; -}); +} +); var reactNoopUpdateQueue = new React.Component().updater; diff --git a/jscomp/test/dist/jscomp/test/string_interp_test.js b/jscomp/test/dist/jscomp/test/string_interp_test.js index 597d0fbc3..fe94e2bfb 100644 --- a/jscomp/test/dist/jscomp/test/string_interp_test.js +++ b/jscomp/test/dist/jscomp/test/string_interp_test.js @@ -51,9 +51,11 @@ function test5(x) { return "" + x; } -var js_in_raw = ("hello" + "你好"); +var js_in_raw = ("hello" + "你好" +); -var j_in_raw = ("hello" + "你好"); +var j_in_raw = ("hello" + "你好" +); var b = "test"; diff --git a/jscomp/test/dist/jscomp/test/unsafe_ppx_test.js b/jscomp/test/dist/jscomp/test/unsafe_ppx_test.js index ba00a1294..6fc58eaba 100644 --- a/jscomp/test/dist/jscomp/test/unsafe_ppx_test.js +++ b/jscomp/test/dist/jscomp/test/unsafe_ppx_test.js @@ -22,7 +22,8 @@ var regression4 = Math.max; function g(a) { var regression = (function(x,y){ return "" -}); +} + ); var regression2 = Math.max; regression(a, Stdlib.failwith); Curry._2(regression2, 3, 2); diff --git a/test/blackbox-tests/melange-ppx-raw.t b/test/blackbox-tests/melange-ppx-raw.t index cb8b7e67d..7f7868c66 100644 --- a/test/blackbox-tests/melange-ppx-raw.t +++ b/test/blackbox-tests/melange-ppx-raw.t @@ -31,3 +31,24 @@ Adding a callback breaks ^^^^^^^^^^^^^^^^^^^^^^ Error: `%mel.raw' can only be applied to a string [1] + +Show expressions in `%mel.raw` get wrapped in parentheses with proper syntax + + $ cat > main.ml < let () = [%mel.raw {| + > // before + > f(1,2) + > // after + > |}] + > EOF + $ melc -ppx melppx main.ml + // Generated by Melange + 'use strict'; + + + ((// before + f(1,2) + // after + )); + + /* Not a pure module */