diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3c6ebb9b13..0b2cff5378 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -34,7 +34,7 @@ jobs: runs-on: ${{matrix.os}} container: - image: ghcr.io/rescript-lang/rescript-ci-build:v1.1.0 + image: ghcr.io/rescript-lang/rescript-ci-build:alpine-3.19-ocaml-4.14.1-02 steps: # See https://github.com/actions/runner/issues/801#issuecomment-1374967227. @@ -115,7 +115,7 @@ jobs: ubuntu-latest, windows-latest, ] - ocaml_compiler: [4.14.0] + ocaml_compiler: [4.14.1] runs-on: ${{matrix.os}} @@ -147,7 +147,7 @@ jobs: chmod +x _build/install/default/bin/* - name: Use OCaml ${{matrix.ocaml_compiler}} - uses: ocaml/setup-ocaml@v2.1.7 + uses: ocaml/setup-ocaml@v2 if: matrix.os != 'windows-latest' with: ocaml-compiler: ${{matrix.ocaml_compiler}} @@ -155,7 +155,7 @@ jobs: opam-depext: false - name: Use OCaml ${{matrix.ocaml_compiler}} (Win) - uses: ocaml/setup-ocaml@v2.1.7 + uses: ocaml/setup-ocaml@v2 if: matrix.os == 'windows-latest' with: ocaml-compiler: ${{matrix.ocaml_compiler}} diff --git a/CHANGELOG.md b/CHANGELOG.md index a5b8b25b4f..9195669a3e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,19 @@ # 12.0.0-alpha.1 (Unreleased) +# 11.1.0-rc.2 (Unreleased) + +#### :bug: Bug Fix + +- Fix issue with async and newtype in uncurried mode. https://github.com/rescript-lang/rescript-compiler/pull/6601 +- Generic JSX transform: Rename expected module name for lowercase JSX to `Elements` from `DOM`. https://github.com/rescript-lang/rescript-compiler/pull/6606 +- Generic JSX transform: Set default config params for `jsxConfig`. https://github.com/rescript-lang/rescript-compiler/pull/6606 +- Generic JSX transform: Handle namespaced names. https://github.com/rescript-lang/rescript-compiler/pull/6606 + +#### :house: Internal + +- Use OCaml 4.14.1 (+ Alpine 3.19 container) for CI build. https://github.com/rescript-lang/rescript-compiler/pull/6600 + # 11.1.0-rc.1 #### :rocket: New Feature diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 56a9d7391a..dda45b2ba1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -41,7 +41,7 @@ Make sure you have [opam](https://opam.ocaml.org/doc/Install.html) installed on opam init # Any recent OCaml version works as a development compiler -opam switch create 4.14.0 # can also create local switch with opam switch create . 4.14.0 +opam switch create 4.14.1 # can also create local switch with opam switch create . 4.14.1 # Install dev dependencies from OPAM opam install . --deps-only diff --git a/jscomp/bsc/rescript_compiler_main.ml b/jscomp/bsc/rescript_compiler_main.ml index 0307e1f708..b59f22f661 100644 --- a/jscomp/bsc/rescript_compiler_main.ml +++ b/jscomp/bsc/rescript_compiler_main.ml @@ -251,7 +251,14 @@ let buckle_script_flags : (string * Bsc_args.spec * string) array = "*internal* Set jsx version"; "-bs-jsx-module", string_call (fun i -> - Js_config.jsx_module := Js_config.jsx_module_of_string i), + let isGeneric = match i |> String.lowercase_ascii with + | "react" -> false + | _ -> true in + Js_config.jsx_module := Js_config.jsx_module_of_string i; + if isGeneric then ( + Js_config.jsx_mode := Automatic; + Js_config.jsx_version := Some Jsx_v4 + )), "*internal* Set jsx module"; "-bs-jsx-mode", string_call (fun i -> diff --git a/jscomp/gentype_tests/typescript-react-example/package-lock.json b/jscomp/gentype_tests/typescript-react-example/package-lock.json index a322751c5e..5fdd739d29 100644 --- a/jscomp/gentype_tests/typescript-react-example/package-lock.json +++ b/jscomp/gentype_tests/typescript-react-example/package-lock.json @@ -24,7 +24,7 @@ }, "../../..": { "name": "rescript", - "version": "11.0.1", + "version": "11.1.0", "dev": true, "hasInstallScript": true, "license": "SEE LICENSE IN LICENSE", diff --git a/jscomp/ml/ast_async.ml b/jscomp/ml/ast_async.ml index d16b193a4c..b1552cd9a2 100644 --- a/jscomp/ml/ast_async.ml +++ b/jscomp/ml/ast_async.ml @@ -13,12 +13,18 @@ let add_promise_type ?(loc = Location.none) ~async let add_async_attribute ~async (body : Parsetree.expression) = if async then - { - body with - pexp_attributes = - ({txt = "res.async"; loc = Location.none}, PStr []) - :: body.pexp_attributes; - } + ( + match body.pexp_desc with + | Pexp_construct (x, Some e) when Ast_uncurried.exprIsUncurriedFun body -> + {body with pexp_desc = Pexp_construct (x, Some {e with pexp_attributes = + ({txt = "res.async"; loc = Location.none}, PStr []) :: e.pexp_attributes} )} + | _ -> + { + body with + pexp_attributes = + ({txt = "res.async"; loc = Location.none}, PStr []) + :: body.pexp_attributes; + }) else body let rec add_promise_to_result ~loc (e : Parsetree.expression) = diff --git a/jscomp/syntax/src/jsx_ppx.ml b/jscomp/syntax/src/jsx_ppx.ml index e362a9c0a5..e0e1cac10e 100644 --- a/jscomp/syntax/src/jsx_ppx.ml +++ b/jscomp/syntax/src/jsx_ppx.ml @@ -48,15 +48,23 @@ let getString ~key fields = fields |> getJsxConfigByKey ~key ~type_:String let updateConfig config payload = let fields = getPayloadFields payload in - (match getInt ~key:"version" fields with - | None -> () - | Some i -> config.Jsx_common.version <- i); - (match getString ~key:"module_" fields with + let moduleRaw = getString ~key:"module_" fields in + let isGeneric = + match moduleRaw |> Option.map (fun m -> String.lowercase_ascii m) with + | Some "react" | None -> false + | Some _ -> true + in + (match (isGeneric, getInt ~key:"version" fields) with + | true, _ -> config.Jsx_common.version <- 4 + | false, Some i -> config.Jsx_common.version <- i + | _ -> ()); + (match moduleRaw with | None -> () | Some s -> config.module_ <- s); - match getString ~key:"mode" fields with - | None -> () - | Some s -> config.mode <- s + match (isGeneric, getString ~key:"mode" fields) with + | true, _ -> config.mode <- "automatic" + | false, Some s -> config.mode <- s + | _ -> () let isJsxConfigAttr ((loc, _) : attribute) = loc.txt = "jsxConfig" diff --git a/jscomp/syntax/src/jsx_v4.ml b/jscomp/syntax/src/jsx_v4.ml index 5246bbd31c..4524ca459c 100644 --- a/jscomp/syntax/src/jsx_v4.ml +++ b/jscomp/syntax/src/jsx_v4.ml @@ -4,7 +4,9 @@ open Asttypes open Parsetree open Longident -let moduleAccessName config = String.capitalize_ascii config.Jsx_common.module_ +let moduleAccessName config value = + String.capitalize_ascii config.Jsx_common.module_ ^ "." ^ value + |> Longident.parse let nolabel = Nolabel @@ -384,10 +386,7 @@ let transformUppercaseCall3 ~config modulePath mapper jsxExprLoc callExprLoc ( labelled "children", Exp.apply (Exp.ident - { - txt = Ldot (Lident (moduleAccessName config), "array"); - loc = Location.none; - }) + {txt = moduleAccessName config "array"; loc = Location.none}) [(Nolabel, expression)] ); ] | _ -> @@ -431,31 +430,17 @@ let transformUppercaseCall3 ~config modulePath mapper jsxExprLoc callExprLoc match (!childrenArg, keyProp) with | None, key :: _ -> ( Exp.ident - { - loc = Location.none; - txt = Ldot (Lident (moduleAccessName config), "jsxKeyed"); - }, + {loc = Location.none; txt = moduleAccessName config "jsxKeyed"}, [key; (nolabel, unitExpr ~loc:Location.none)] ) | None, [] -> - ( Exp.ident - { - loc = Location.none; - txt = Ldot (Lident (moduleAccessName config), "jsx"); - }, + ( Exp.ident {loc = Location.none; txt = moduleAccessName config "jsx"}, [] ) | Some _, key :: _ -> ( Exp.ident - { - loc = Location.none; - txt = Ldot (Lident (moduleAccessName config), "jsxsKeyed"); - }, + {loc = Location.none; txt = moduleAccessName config "jsxsKeyed"}, [key; (nolabel, unitExpr ~loc:Location.none)] ) | Some _, [] -> - ( Exp.ident - { - loc = Location.none; - txt = Ldot (Lident (moduleAccessName config), "jsxs"); - }, + ( Exp.ident {loc = Location.none; txt = moduleAccessName config "jsxs"}, [] ) in Exp.apply ~loc:jsxExprLoc ~attrs jsxExpr @@ -500,9 +485,9 @@ let transformLowercaseCall3 ~config mapper jsxExprLoc callExprLoc attrs (* the new jsx transform *) | "automatic" -> let elementBinding = - match moduleAccessName config with - | "React" -> Lident "ReactDOM" - | generic -> Ldot (Lident generic, "DOM") + match config.module_ |> String.lowercase_ascii with + | "react" -> Lident "ReactDOM" + | _generic -> moduleAccessName config "Elements" in let children, nonChildrenProps = @@ -539,10 +524,7 @@ let transformLowercaseCall3 ~config mapper jsxExprLoc callExprLoc attrs ( labelled "children", Exp.apply (Exp.ident - { - txt = Ldot (Lident (moduleAccessName config), "array"); - loc = Location.none; - }) + {txt = moduleAccessName config "array"; loc = Location.none}) [(Nolabel, expression)] ); ] in @@ -1203,10 +1185,7 @@ let transformStructureItem ~config item = (* can't be an arrow because it will defensively uncurry *) let newExternalType = Ptyp_constr - ( { - loc = pstr_loc; - txt = Ldot (Lident (moduleAccessName config), "componentLike"); - }, + ( {loc = pstr_loc; txt = moduleAccessName config "componentLike"}, [retPropsType; innerType] ) in let newStructure = @@ -1321,10 +1300,7 @@ let transformSignatureItem ~config item = (* can't be an arrow because it will defensively uncurry *) let newExternalType = Ptyp_constr - ( { - loc = psig_loc; - txt = Ldot (Lident (moduleAccessName config), "componentLike"); - }, + ( {loc = psig_loc; txt = moduleAccessName config "componentLike"}, [retPropsType; innerType] ) in let newStructure = @@ -1419,8 +1395,7 @@ let expr ~config mapper expression = let fragment = match config.mode with | "automatic" -> - Exp.ident ~loc - {loc; txt = Ldot (Lident (moduleAccessName config), "jsxFragment")} + Exp.ident ~loc {loc; txt = moduleAccessName config "jsxFragment"} | "classic" | _ -> Exp.ident ~loc {loc; txt = Ldot (Lident "React", "fragment")} in @@ -1431,10 +1406,7 @@ let expr ~config mapper expression = let applyJsxArray expr = Exp.apply (Exp.ident - { - txt = Ldot (Lident (moduleAccessName config), "array"); - loc = Location.none; - }) + {txt = moduleAccessName config "array"; loc = Location.none}) [(Nolabel, expr)] in let countOfChildren = function @@ -1472,11 +1444,8 @@ let expr ~config mapper expression = (match config.mode with | "automatic" -> if countOfChildren childrenExpr > 1 then - Exp.ident ~loc - {loc; txt = Ldot (Lident (moduleAccessName config), "jsxs")} - else - Exp.ident ~loc - {loc; txt = Ldot (Lident (moduleAccessName config), "jsx")} + Exp.ident ~loc {loc; txt = moduleAccessName config "jsxs"} + else Exp.ident ~loc {loc; txt = moduleAccessName config "jsx"} | "classic" | _ -> if countOfChildren childrenExpr > 1 then Exp.ident ~loc diff --git a/jscomp/test/async_await.js b/jscomp/test/async_await.js index 0c674d3b90..d376f50acf 100644 --- a/jscomp/test/async_await.js +++ b/jscomp/test/async_await.js @@ -34,6 +34,10 @@ var toplevelAwait = await topFoo(); var toplevelAwait2 = Caml_array.get(arr, await topFoo()); +async function f(value) { + return await Promise.resolve(1); +} + exports.next = next; exports.useNext = useNext; exports.Make = Make; @@ -41,4 +45,5 @@ exports.topFoo = topFoo; exports.arr = arr; exports.toplevelAwait = toplevelAwait; exports.toplevelAwait2 = toplevelAwait2; +exports.f = f; /* toplevelAwait Not a pure module */ diff --git a/jscomp/test/async_await.res b/jscomp/test/async_await.res index fd7bf92f34..85aafb08bd 100644 --- a/jscomp/test/async_await.res +++ b/jscomp/test/async_await.res @@ -16,3 +16,7 @@ let arr = [1, 2, 3] let toplevelAwait = await topFoo() let toplevelAwait2 = arr[await topFoo()] + +let f = async (type input, value: input) => { + await Js.Promise.resolve(. 1) +} \ No newline at end of file