Skip to content
Merged
Show file tree
Hide file tree
Changes from 25 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
9 changes: 5 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -336,12 +336,13 @@ jobs:
run: ./scripts/test_syntax.sh
shell: bash

- name: Build runtime/stdlib
run: ./scripts/buildRuntime.sh
- name: Build @rescript/runtime
run: yarn workspace @rescript/runtime rescript build
shell: bash

- name: Check for changes in lib folder
- name: Check for changes in @rescript/runtime/lib
run: git diff --exit-code lib/js lib/es6
working-directory: packages/@rescript/runtime

- name: Version Check
run: yarn constraints
Expand Down Expand Up @@ -447,7 +448,7 @@ jobs:
uses: actions/upload-artifact@v4
with:
name: lib-ocaml
path: lib/ocaml
path: packages/@rescript/runtime/lib/ocaml

- name: Generate API Docs
if: ${{ matrix.generate_api_docs }}
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/moveArtifacts.sh
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ check_statically_linked() {
}

# rescript
mv lib-ocaml lib/ocaml
mv lib-ocaml packages/@rescript/runtime/lib/ocaml

# @rescript/{target}
chmod +x binaries-*/*.exe
Expand All @@ -40,4 +40,4 @@ check_statically_linked "packages/@rescript/linux-arm64/bin"

# @rescript/std
mkdir -p packages/std/lib
cp -R lib/es6 lib/js packages/std/lib
cp -R packages/@rescript/runtime/lib/es6 packages/@rescript/runtime/lib/js packages/std/lib
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@

#### :boom: Breaking Change

- Extract ReScript runtime files from main `rescript` package to separate `@rescript/runtime` package. https://github.com/rescript-lang/rescript/pull/7796

#### :eyeglasses: Spec Compliance

#### :rocket: New Feature
Expand Down
8 changes: 5 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ reanalyze:
reanalyze.exe -set-exit-code -all-cmt _build/default/compiler _build/default/tests -exclude-paths compiler/outcome_printer,compiler/ml,compiler/frontend,compiler/ext,compiler/depends,compiler/core,compiler/common,compiler/cmij,compiler/bsb_helper,compiler/bsb

lib:
./scripts/buildRuntime.sh
yarn workspace @rescript/runtime build

artifacts: lib
./scripts/npmPack.js --updateArtifactList
Expand Down Expand Up @@ -84,8 +84,10 @@ clean-gentype:
clean-rewatch:
cargo clean --manifest-path rewatch/Cargo.toml && rm -f rewatch/rewatch

clean:
(cd runtime && ../cli/rescript.js clean)
clean-lib:
yarn workspace @rescript/runtime rescript clean

clean: clean-lib
dune clean

clean-all: clean clean-gentype clean-rewatch
Expand Down
13 changes: 7 additions & 6 deletions analysis/src/BuildSystem.ml
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,24 @@ let namespacedName namespace name =

let ( /+ ) = Filename.concat

let getBsPlatformDir rootPath =
let getRuntimeDir rootPath =
match !Cfg.isDocGenFromCompiler with
| false -> (
let result =
ModuleResolution.resolveNodeModulePath ~startPath:rootPath "rescript"
ModuleResolution.resolveNodeModulePath ~startPath:rootPath
"@rescript/runtime"
in
match result with
| Some path -> Some path
| None ->
let message = "rescript could not be found" in
let message = "@rescript/runtime could not be found" in
Log.log message;
None)
| true -> Some rootPath

let getLibBs root = Files.ifExists (root /+ "lib" /+ "bs")
let getLibBs path = Files.ifExists (path /+ "lib" /+ "bs")

let getStdlib base =
match getBsPlatformDir base with
match getRuntimeDir base with
| None -> None
| Some bsPlatformDir -> Some (bsPlatformDir /+ "lib" /+ "ocaml")
| Some runtimeDir -> Some (runtimeDir /+ "lib" /+ "ocaml")
18 changes: 14 additions & 4 deletions analysis/src/Files.ml
Original file line number Diff line number Diff line change
Expand Up @@ -84,16 +84,26 @@ let rec collectDirs path =
|> List.concat)
| _ -> []

let rec collect ?(checkDir = fun _ -> true) path test =
match maybeStat path with
| None -> []
| Some {Unix.st_kind = Unix.S_DIR} ->
let rec collect ?(checkDir = fun _ -> true) ?maxDepth path test =
match (maxDepth, maybeStat path) with
| None, None -> []
| Some 0, _ -> []
| None, Some {Unix.st_kind = Unix.S_DIR} ->
if checkDir path then
readDirectory path
|> List.map (fun name ->
collect ~checkDir (Filename.concat path name) test)
|> List.concat
else []
| Some n, Some {Unix.st_kind = Unix.S_DIR} ->
if checkDir path then
readDirectory path
|> List.map (fun name ->
collect ~checkDir ~maxDepth:(n - 1)
(Filename.concat path name)
test)
|> List.concat
else []
| _ -> if test path then [path] else []

type classifiedFile = Res | Resi | Other
Expand Down
2 changes: 1 addition & 1 deletion analysis/src/FindFiles.ml
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ let findProjectFiles ~public ~namespace ~path ~sourceDirectories ~libBs =
in
let files =
dirs |> StringSet.elements
|> List.map (fun name -> Files.collect name isSourceFile)
|> List.map (fun name -> Files.collect ~maxDepth:2 name isSourceFile)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Curious, why is a maxDepth needed after this PR?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This part is from @cometkim.

From what I have seen, infinite recursion can occur during module resolution without it because rescript depends on @rescript/runtime, but @rescript/runtime also has rescript as a dev dependency.

Maybe we should add a comment there.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah a comment would be good.

|> List.concat |> StringSet.of_list
in
dirs
Expand Down
19 changes: 15 additions & 4 deletions analysis/src/ModuleResolution.ml
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
let ( /+ ) = Filename.concat

let rec resolveNodeModulePath ~startPath name =
let path = startPath /+ "node_modules" /+ name in
if Files.exists path then Some path
else if Filename.dirname startPath = startPath then None
else resolveNodeModulePath ~startPath:(Filename.dirname startPath) name
if name = "@rescript/runtime" then
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't remember exactly, but this is incomplete code. I think this is incompatible with the external-stdlib feature already.

I tried rewriting it to avoid relying on ninja's special stdlib resolution rules, but I wasn't successful. The current resolution rules still heavily rely on the node_modules directory structure and the runtime package name, which could be broken by package managers' storage design.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the module resolution in analysis/tools definitely has issues and should be revisited.

It does not work with workspace dependencies as can be seen here and also in #7525.

/cc @zth

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know much about the module resolution. What's the problem? Is it problem we handle as we should elsewhere but not in analysis/tools?

(* Hack: we need a reliable way to resolve modules in monorepos. *)
Some Config.runtime_module_path
else
let scope = Filename.dirname name in
let name = Filename.basename name in
let name =
match scope.[0] with
| '@' -> scope /+ name
| _ -> name
in
let path = startPath /+ "node_modules" /+ name in
if Files.exists path then Some path
else if Filename.dirname startPath = startPath then None
else resolveNodeModulePath ~startPath:(Filename.dirname startPath) name
2 changes: 1 addition & 1 deletion cli/common/bsb.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import * as fs from "node:fs";
import { createServer } from "node:http";
import * as os from "node:os";
import * as path from "node:path";
import { WebSocket } from "#lib/minisocket";

import { rescript_legacy_exe } from "./bins.js";
import { WebSocket } from "./minisocket.js";

const cwd = process.cwd();
const lockFileName = path.join(cwd, ".bsb.lock");
Expand Down
File renamed without changes.
9 changes: 0 additions & 9 deletions compiler/bsc/rescript_compiler_main.ml
Original file line number Diff line number Diff line change
Expand Up @@ -205,12 +205,6 @@ let eval (s : string) ~suffix =

(* let (//) = Filename.concat *)

let print_standard_library () =
let standard_library = Config.standard_library in
print_string standard_library;
print_newline ();
exit 0

let bs_version_string = "ReScript " ^ Bs_version.version

let print_version_string () =
Expand Down Expand Up @@ -378,9 +372,6 @@ let command_line_flags : (string * Bsc_args.spec * string) array =
( "-ignore-parse-errors",
set Clflags.ignore_parse_errors,
"*internal* continue after parse errors" );
( "-where",
unit_call print_standard_library,
"*internal* Print location of standard library and exit" );
( "-verbose",
set Clflags.verbose,
"*internal* Print calls to external commands" );
Expand Down
2 changes: 1 addition & 1 deletion compiler/common/bs_version.ml
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,4 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *)
let version = "12.0.0-beta.8"
let header = "// Generated by ReScript, PLEASE EDIT WITH CARE"
let package_name = ref "rescript"
let package_name = ref "@rescript/runtime"
30 changes: 18 additions & 12 deletions compiler/ext/config.ml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
(* This resolves the location of the standard library starting from the location of bsc.exe,
handling different supported package layouts. *)
let standard_library =
(* This resolves the location of the standard library starting from the location of bsc.exe
(@rescript/{platform}/bin/bsc.exe), handling different supported package layouts. *)
let runtime_module_path =
let build_path rest path =
String.concat Filename.dir_sep (List.rev_append rest path)
in
Expand All @@ -10,25 +10,31 @@ let standard_library =
|> List.rev
with
(* 1. Packages installed via pnpm
- bin: node_modules/.pnpm/@[email protected]/node_modules/@rescript/darwin-arm64/bin
- stdlib: node_modules/rescript/lib/ocaml (symlink)
- bin: node_modules/.pnpm/@[email protected]/node_modules/@rescript/darwin-arm64/bin
- runtime: node_modules/.pnpm/node_modules/@rescript/runtime (symlink)
*)
| "bin" :: _platform :: "@rescript" :: "node_modules" :: _package :: ".pnpm"
:: "node_modules" :: rest ->
build_path rest ["node_modules"; "rescript"; "lib"; "ocaml"]
build_path rest
["node_modules"; ".pnpm"; "node_modules"; "@rescript"; "runtime"]
(* 2. Packages installed via npm
- bin: node_modules/@rescript/{platform}/bin
- stdlib: node_modules/rescript/lib/ocaml
- bin: node_modules/@rescript/{platform}/bin
- runtime: node_modules/@rescript/runtime
*)
| "bin" :: _platform :: "@rescript" :: "node_modules" :: rest ->
build_path rest ["node_modules"; "rescript"; "lib"; "ocaml"]
build_path rest ["node_modules"; "@rescript"; "runtime"]
(* 3. Several other cases that can occur in local development, e.g.
- bin: <repo>/packages/@rescript/{platform}/bin, <repo>/_build/install/default/bin
- stdlib: <repo>/lib/ocaml
- bin: <repo>/packages/@rescript/{platform}/bin, <repo>/_build/install/default/bin
- runtime: <repo>/packages/@rescript/runtime
*)
| _ :: _ :: _ :: _ :: rest -> build_path rest ["lib"; "ocaml"]
| _ :: _ :: _ :: _ :: rest ->
build_path rest ["packages"; "@rescript"; "runtime"]
| _ -> ""

let standard_library =
let ( // ) = Filename.concat in
runtime_module_path // "lib" // "ocaml"

let cmi_magic_number = "Caml1999I022"

and ast_impl_magic_number = "Caml1999M022"
Expand Down
7 changes: 5 additions & 2 deletions compiler/ext/config.mli
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,14 @@

(* System configuration *)

(* The directory containing the runtime module (@rescript/runtime) *)
val runtime_module_path : string

(* The directory containing the runtime artifacts (@rescript/runtime/lib/ocaml) *)
val standard_library : string
(* The directory containing the standard libraries *)

val load_path : string list ref
(* Directories in the search path for .cmi and .cmo files *)
val load_path : string list ref

val cmi_magic_number : string

Expand Down
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@
"CREDITS.md",
"ninja.COPYING",
"docs/docson/build-schema.json",
"lib",
"cli"
],
"exports": {
Expand All @@ -72,8 +71,10 @@
},
"imports": {
"#cli/*": "./cli/common/*.js",
"#dev/*": "./lib_dev/*.js",
"#lib/minisocket": "./lib/minisocket.js"
"#dev/*": "./lib_dev/*.js"
},
"dependencies": {
"@rescript/runtime": "workspace:packages/@rescript/runtime"
},
"optionalDependencies": {
"@rescript/darwin-arm64": "workspace:packages/@rescript/darwin-arm64",
Expand Down
3 changes: 3 additions & 0 deletions packages/@rescript/runtime/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
lib/bs
lib/ocaml
*.lock
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ let rec getUndefined = (n, x: key) =>

let rec getExn = (n, x: key) =>
switch n {
| None => raise(Not_found)
| None => throw(Not_found)
| Some(n) =>
let v = n.N.key
if x == v {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ let rec getUndefined = (n: t, x: value) =>

let rec getExn = (n: t, x: value) =>
switch n {
| None => raise(Not_found)
| None => throw(Not_found)
| Some(t) =>
let v = t.value
if x == v {
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,24 @@ let findFirstByU: (t<'v>, (key, 'v) => bool) => option<(key, 'v)>
`findFirstBy(m, p)` uses funcion `f` to find the first key value pair
to match predicate `p`.

## Examples

```rescript
let s0 = fromArray(~id=module(IntCmp), [(4, "4"), (1, "1"), (2, "2,"(3, ""))])
findFirstBy(s0, (k, v) => k == 4) == option((4, "4"))
#ifdef TYPE_STRING
let mapString = Belt.Map.String.fromArray([("1", "one"), ("2", "two"), ("3", "three")])

mapString->
Belt.Map.String.findFirstBy((k, v) => k == "1" && v == "one")
->assertEqual(Some("1", "one"))
#elif defined TYPE_INT
let mapInt = Belt.Map.Int.fromArray([(1, "one"), (2, "two"), (3, "three")])

mapInt->
Belt.Map.Int.findFirstBy((k, v) => k == 1 && v == "one")
->assertEqual(Some(1, "one"))
#else
[%error "unknown type"]
#endif
```
*/
let findFirstBy: (t<'v>, (key, 'v) => bool) => option<(key, 'v)>
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Loading
Loading