Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
  •  
  •  
  •  
42 changes: 37 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,14 @@ jobs:
run: git diff --exit-code lib/js lib/es6
working-directory: packages/@rescript/runtime

- name: Build @rescript/belt
run: yarn workspace @rescript/belt build
shell: bash

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

- name: Version Check
run: yarn constraints

Expand Down Expand Up @@ -401,7 +409,7 @@ jobs:
- name: Publish packages to pkg.pr.new
id: publish
run: |
yarn dlx pkg-pr-new publish "." "./packages/@rescript/*"
yarn dlx pkg-pr-new publish --yarn "." "./packages/@rescript/*"

api-docs:
needs:
Expand Down Expand Up @@ -493,12 +501,24 @@ jobs:
run: |
COMMIT_SHA="${{ needs.pkg-pr-new.outputs.commit_sha }}"
npm i --no-audit \
"https://pkg.pr.new/rescript-lang/rescript@${COMMIT_SHA}"
"https://pkg.pr.new/rescript-lang/rescript@${COMMIT_SHA}" \
"https://pkg.pr.new/rescript-lang/rescript/@rescript/runtime@${COMMIT_SHA}" \
"https://pkg.pr.new/rescript-lang/rescript/@rescript/belt@${COMMIT_SHA}"
shell: bash
working-directory: ${{ steps.tmp-dir.outputs.path }}

- name: Test installation
run: npx rescript -h && npx rescript build && cat src/Test.res.js
run: |
npx rescript -h
npx rescript build
cp src/BeltTest.res.txt src/BeltTest.res
if npx rescript build; then
echo "Belt unexpectedly compiled without being listed as a dependency" >&2
exit 1
fi
cp rescript-with-belt.json rescript.json
npx rescript build
node src/BeltTest.mjs
shell: bash
working-directory: ${{ steps.tmp-dir.outputs.path }}

Expand Down Expand Up @@ -548,12 +568,24 @@ jobs:
COMMIT_SHA="${{ needs.pkg-pr-new.outputs.commit_sha }}"
# pnpm 10 blocks pkg.pr.new's URL-based platform subdependencies unless block-exotic-subdeps is disabled.
pnpm --config.block-exotic-subdeps=false i \
"https://pkg.pr.new/rescript-lang/rescript@${COMMIT_SHA}"
"https://pkg.pr.new/rescript-lang/rescript@${COMMIT_SHA}" \
"https://pkg.pr.new/rescript-lang/rescript/@rescript/runtime@${COMMIT_SHA}" \
"https://pkg.pr.new/rescript-lang/rescript/@rescript/belt@${COMMIT_SHA}"
shell: bash
working-directory: ${{ steps.tmp-dir.outputs.path }}

- name: Test installation
run: pnpm rescript -h && pnpm rescript build && cat src/Test.res.js
run: |
pnpm rescript -h
pnpm rescript build
cp src/BeltTest.res.txt src/BeltTest.res
if pnpm rescript build; then
echo "Belt unexpectedly compiled without being listed as a dependency" >&2
exit 1
fi
cp rescript-with-belt.json rescript.json
pnpm rescript build
node src/BeltTest.mjs
shell: bash
working-directory: ${{ steps.tmp-dir.outputs.path }}

Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#### :boom: Breaking Change

- Remove the deprecated `Js` namespace and its runtime modules. https://github.com/rescript-lang/rescript/pull/8531
- Move Belt into the separately installed `@rescript/belt` package. Projects using Belt must install the package and list it in their `rescript.json` dependencies. https://github.com/rescript-lang/rescript/pull/8554

#### :eyeglasses: Spec Compliance

Expand Down
5 changes: 3 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ make checkformat

## Adding new Files to the Npm Packages

To make sure that no files are added to or removed from the `rescript` or `@rescript/runtime` npm package inadvertently, an artifact list is kept at `packages/artifacts.json`. During CI build, it is verified that only the files that are listed there are actually included in the npm packages.
To make sure that no files are added to or removed from the `rescript`, `@rescript/runtime`, or `@rescript/belt` npm package inadvertently, an artifact list is kept at `packages/artifacts.json`. During CI build, it is verified that only the files that are listed there are actually included in the npm packages.

After adding a new file to the repository that should go into one of the npm packages - e.g., a new stdlib module -, run `make artifacts`.

Expand Down Expand Up @@ -325,7 +325,8 @@ Note that building the cmijs is based on the dependencies defined in `packages/p
After a successful compilation, you will find following files in your project:

- `packages/playground/compiler.js` -> This is the ReScript compiler, which binds the ReScript API to the `window` object.
- `packages/playground/packages/compiler-builtins` -> The compiler base cmij containing all the relevant core modules (`Js`, `Belt`, `Pervasives`, etc.)
- `packages/playground/packages/compiler-builtins` -> The compiler base cmij containing the runtime and standard-library modules
- `packages/playground/packages/@rescript/belt` -> The Belt cmij, packaged separately from the compiler built-ins
- `packages/playground/packages/*` -> Contains third party deps with cmij.js files (as defined in `packages/playground/rescript.json`)

You can now use the `compiler.js` file either directly by using a `<script src="/path/to/compiler.js"/>` and `<script src="/path/to/packages/compilerCmij.js"/>` inside a html file, use a browser bundler infrastructure to optimize it, or use `nodejs` to run it on a command line:
Expand Down
14 changes: 11 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ endef

BIN_DIR := packages/@rescript/$(RESCRIPT_PLATFORM)/bin
RUNTIME_DIR := packages/@rescript/runtime
BELT_DIR := packages/@rescript/belt
DUNE_BIN_DIR = ./_build/install/default/bin

# Build stamps
Expand All @@ -56,6 +57,8 @@ COMPILER_BUILD_STAMP := _build/log
# after running `yarn workspace @rescript/runtime build`, which now runs `touch`
# as part of its build script.
RUNTIME_BUILD_STAMP := packages/@rescript/runtime/.buildstamp
# Belt workspace touches this stamp after building against the runtime.
BELT_BUILD_STAMP := packages/@rescript/belt/.buildstamp
Comment thread
cknitt marked this conversation as resolved.

# Default target

Expand Down Expand Up @@ -127,15 +130,20 @@ clean-compiler:
# Runtime / stdlib

RUNTIME_SOURCES := $(shell find $(RUNTIME_DIR) -path '$(RUNTIME_DIR)/lib' -prune -o -type f \( -name '*.res' -o -name '*.resi' -o -name 'rescript.json' \) -print)
BELT_SOURCES := $(shell find $(BELT_DIR) -path '$(BELT_DIR)/lib' -prune -o -type f \( -name '*.res' -o -name '*.resi' -o -name 'rescript.json' \) -print)

lib: $(RUNTIME_BUILD_STAMP)
lib: $(RUNTIME_BUILD_STAMP) $(BELT_BUILD_STAMP)

$(RUNTIME_BUILD_STAMP): $(RUNTIME_SOURCES) $(COMPILER_EXES) $(RESCRIPT_EXE) | $(YARN_INSTALL_STAMP)
yarn workspace @rescript/runtime build

$(BELT_BUILD_STAMP): $(BELT_SOURCES) $(RUNTIME_BUILD_STAMP) $(COMPILER_EXES) $(RESCRIPT_EXE) | $(YARN_INSTALL_STAMP)
yarn workspace @rescript/belt build

clean-lib:
yarn workspace @rescript/belt rescript clean
yarn workspace @rescript/runtime rescript clean
rm -f $(RUNTIME_BUILD_STAMP)
rm -f $(RUNTIME_BUILD_STAMP) $(BELT_BUILD_STAMP)

# Artifact list

Expand Down Expand Up @@ -198,7 +206,7 @@ $(PLAYGROUND_BUILD_STAMP): $(COMPILER_SOURCES)
# Creates all the relevant core and third party cmij files to side-load together with the playground bundle
playground-cmijs: $(PLAYGROUND_CMI_BUILD_STAMP)

$(PLAYGROUND_CMI_BUILD_STAMP): $(RUNTIME_BUILD_STAMP)
$(PLAYGROUND_CMI_BUILD_STAMP): $(RUNTIME_BUILD_STAMP) $(BELT_BUILD_STAMP)
yarn workspace playground build

playground-test: playground
Expand Down
5 changes: 3 additions & 2 deletions analysis/src/semantic_tokens.ml
Original file line number Diff line number Diff line change
Expand Up @@ -257,8 +257,9 @@ let command ~debug ~emitter ~source ~kind_file =
(* Don't emit semantic tokens for identifiers not present in source code *)
let should_emit =
match lid with
(* Array spread (`...`) is converted to `Belt.Array.concatMany` with `@res.spread` decorator *)
| Ldot (Ldot (Lident "Belt", "Array"), "concatMany") ->
(* Collection spreads (`...`) are converted to primitive spread calls
with an `@res.spread` decorator. *)
| Ldot (Lident ("Primitive_array" | "Primitive_list"), "spread") ->
let has_spread_attr =
e.pexp_attributes
|> List.exists (fun ({Location.txt}, _) -> txt = "res.spread")
Expand Down
1 change: 1 addition & 0 deletions biome.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
"!**/.yarn",
"!**/tests/analysis_tests/**/src",
"!**/tests/build_tests/**/src",
"!**/tests/belt_tests/**/src",
"!**/tests/commonjs_tests/src",
"!**/tests/dependencies/**/src",
"!**/tests/docstring_tests",
Expand Down
38 changes: 3 additions & 35 deletions compiler/core/outcome_printer_ns.ml
Original file line number Diff line number Diff line change
Expand Up @@ -26,38 +26,6 @@ let ps = Format.pp_print_string

let out_ident ppf s =
ps ppf
(match s with
(* Belt_libs *)
| "Belt_Id" -> "Belt.Id"
| "Belt_Array" -> "Belt.Array"
| "Belt_SortArray" -> "Belt.SortArray"
| "Belt_SortArrayInt" -> "Belt.SortArray.Int"
| "Belt_SortArrayString" -> "Belt.SortArray.String"
| "Belt_MutableQueue" -> "Belt.MutableQueue"
| "Belt_MutableStack" -> "Belt.MutableStack"
| "Belt_List" -> "Belt.List"
| "Belt_Range" -> "Belt.Range"
| "Belt_Set" -> "Belt.Set"
| "Belt_SetInt" -> "Belt.Set.Int"
| "Belt_SetString" -> "Belt.Set.String"
| "Belt_Map" -> "Belt.Map"
| "Belt_MapInt" -> "Belt.Map.Int"
| "Belt_MapString" -> "Belt.Map.String"
| "Belt_Option" -> "Belt.Option"
| "Belt_MutableSet" -> "Belt.MutableSet"
| "Belt_MutableSetInt" -> "Belt.MutableSet.Int"
| "Belt_MutableSetString" -> "Belt.MutableSet.String"
| "Belt_MutableMap" -> "Belt.MutableMap"
| "Belt_MutableMapInt" -> "Belt.MutableMap.Int"
| "Belt_MutableMapString" -> "Belt.MutableMap.String"
| "Belt_HashSet" -> "Belt.HashSet"
| "Belt_HashSetInt" -> "Belt.HashSet.Int"
| "Belt_HashSetString" -> "Belt.HashSet.String"
| "Belt_HashMap" -> "Belt.HashMap"
| "Belt_HashMapString" -> "Belt.HashMap.String"
| "Belt_HashMapInt" -> "Belt.HashMap.Int"
| "Belt_Debug" -> "Belt.Debug"
| s -> (
match Ext_namespace.try_split_module_name s with
| None -> s
| Some (ns, m) -> ns ^ "." ^ m))
(match Ext_namespace.try_split_module_name s with
| None -> s
| Some (ns, m) -> ns ^ "." ^ m)
2 changes: 2 additions & 0 deletions compiler/ext/primitive_modules.ml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ let string = "Primitive_string"

let array = "Primitive_array"

let list = "Primitive_list"

let dict = "Primitive_dict"

let object_ = "Primitive_object"
Expand Down
14 changes: 7 additions & 7 deletions compiler/frontend/bs_builtin_ppx.ml
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ let pat_mapper (self : mapper) (p : Parsetree.pattern) =
| _ -> default_pat_mapper self p

(* Unpack requires core_type package for type inference:
Generate a module type name eg. __Belt_List__*)
Generate a module type name eg. __List__*)
let local_module_type_name txt =
"_"
^ (Longident.flatten txt |> List.fold_left (fun ll l -> ll ^ "_" ^ l) "")
Expand Down Expand Up @@ -323,7 +323,7 @@ let expr_mapper ~async_context ~in_function_def (self : mapper)
the attribute to the whole expression, in general, when shuffuling the ast
it is very hard to place attributes correctly
*)
(* module M = await Belt.List *)
(* module M = await List *)
| Pexp_letmodule
(lid, ({pmod_desc = Pmod_ident {txt}; pmod_attributes} as me), expr)
when Res_parsetree_viewer.has_await_attribute pmod_attributes ->
Expand All @@ -339,7 +339,7 @@ let expr_mapper ~async_context ~in_function_def (self : mapper)
~module_type_lid:safe_module_type_lid me,
self.expr self expr );
}
(* module M = await (Belt.List: BeltList) *)
(* module M = await (List: ListType) *)
| Pexp_letmodule
( lid,
({
Expand Down Expand Up @@ -661,7 +661,7 @@ let rec structure_mapper ~await_context (self : mapper) (stru : Ast_structure.t)
| _ -> expand_reverse acc (structure_mapper ~await_context self rest)
in
aux [] stru
(* Dynamic import of module transformation: module M = @res.await Belt.List *)
(* Dynamic import of module transformation: module M = @res.await List *)
| Pstr_module
({pmb_expr = {pmod_desc = Pmod_ident {txt; loc}; pmod_attributes} as me}
as mb)
Expand All @@ -671,7 +671,7 @@ let rec structure_mapper ~await_context (self : mapper) (stru : Ast_structure.t)
let has_local_module_name =
Hashtbl.find_opt !await_context safe_module_type_name
in
(* module __Belt_List__ = module type of Belt.List *)
(* module __List__ = module type of List *)
let module_type_decl =
match has_local_module_name with
| Some _ -> []
Expand All @@ -690,7 +690,7 @@ let rec structure_mapper ~await_context (self : mapper) (stru : Ast_structure.t)
in
module_type_decl
@
(* module M = @res.await Belt.List *)
(* module M = @res.await List *)
{
item with
pstr_desc =
Expand All @@ -705,7 +705,7 @@ let rec structure_mapper ~await_context (self : mapper) (stru : Ast_structure.t)
:: structure_mapper ~await_context self rest
| Pstr_value (_, vbs) ->
let item = self.structure_item self item in
(* [ module __Belt_List__ = module type of Belt.List ] *)
(* [ module __List__ = module type of List ] *)
let rec spelunk_vbs acc vbs =
match vbs with
| [] -> acc
Expand Down
8 changes: 2 additions & 6 deletions compiler/syntax/src/res_comments_table.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1593,14 +1593,10 @@ and walk_expression expr t comments =
when Res_parsetree_viewer.is_tuple_array key_values ->
walk_list [Expression key_values] t comments
| Pexp_apply {funct = call_expr; args = arguments} -> (
(* Special handling for Belt.Array.concatMany - treat like an array *)
(* Special handling for array spread - treat it like an array *)
match call_expr.pexp_desc with
| Pexp_ident
{
txt =
Longident.Ldot
(Longident.Ldot (Longident.Lident "Belt", "Array"), "concatMany");
}
{txt = Longident.Ldot (Longident.Lident "Primitive_array", "spread")}
when List.length arguments = 1 -> (
match arguments with
| [(_, {pexp_desc = Pexp_array sub_arrays})] ->
Expand Down
6 changes: 2 additions & 4 deletions compiler/syntax/src/res_core.ml
Original file line number Diff line number Diff line change
Expand Up @@ -4465,8 +4465,7 @@ and parse_list_expr ~start_pos p =
Ast_helper.Exp.apply ~loc
(Ast_helper.Exp.ident ~loc ~attrs:[spread_attr]
(Location.mkloc
(Longident.Ldot
(Longident.Ldot (Longident.Lident "Belt", "List"), "concatMany"))
(Longident.Ldot (Longident.Lident Primitive_modules.list, "spread"))
loc))
[(Asttypes.Nolabel, Ast_helper.Exp.array ~loc list_exprs)]

Expand Down Expand Up @@ -4608,8 +4607,7 @@ and parse_array_exp p =
Ast_helper.Exp.apply ~loc
(Ast_helper.Exp.ident ~loc ~attrs:[spread_attr]
(Location.mkloc
(Longident.Ldot
(Longident.Ldot (Longident.Lident "Belt", "Array"), "concatMany"))
(Longident.Ldot (Longident.Lident Primitive_modules.array, "spread"))
loc))
[(Nolabel, Ast_helper.Exp.array ~loc list_exprs)]

Expand Down
2 changes: 1 addition & 1 deletion compiler/syntax/src/res_diagnostics.ml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ let explain t =
let token = Token.to_string t in
"`" ^ token ^ "` is a reserved keyword."
| _ ->
"At this point, I'm looking for an uppercased name like `Belt` or `Array`"
"At this point, I'm looking for an uppercased name like `Array` or `Math`"
)
| Lident current_token -> (
match current_token with
Expand Down
2 changes: 1 addition & 1 deletion compiler/syntax/src/res_grammar.ml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
module Token = Res_token

type t =
| OpenDescription (* open Belt *)
| OpenDescription (* open Array *)
| ModuleLongIdent (* Foo or Foo.Bar *) [@live]
| Ternary (* condExpr ? trueExpr : falseExpr *)
| Es6ArrowExpr
Expand Down
16 changes: 4 additions & 12 deletions compiler/syntax/src/res_parsetree_viewer.ml
Original file line number Diff line number Diff line change
Expand Up @@ -726,25 +726,17 @@ let has_spread_attr attrs =
| _ -> false)
attrs

let is_spread_belt_list_concat expr =
let is_spread_list expr =
match expr.pexp_desc with
| Pexp_ident
{
txt =
Longident.Ldot
(Longident.Ldot (Longident.Lident "Belt", "List"), "concatMany");
} ->
{txt = Longident.Ldot (Longident.Lident "Primitive_list", "spread")} ->
has_spread_attr expr.pexp_attributes
| _ -> false

let is_spread_belt_array_concat expr =
let is_spread_array expr =
match expr.pexp_desc with
| Pexp_ident
{
txt =
Longident.Ldot
(Longident.Ldot (Longident.Lident "Belt", "Array"), "concatMany");
} ->
{txt = Longident.Ldot (Longident.Lident "Primitive_array", "spread")} ->
has_spread_attr expr.pexp_attributes
| _ -> false

Expand Down
4 changes: 2 additions & 2 deletions compiler/syntax/src/res_parsetree_viewer.mli
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,9 @@ val is_template_literal : Parsetree.expression -> bool
val is_tagged_template_literal : Parsetree.expression -> bool
val has_template_literal_attr : Parsetree.attributes -> bool

val is_spread_belt_list_concat : Parsetree.expression -> bool
val is_spread_list : Parsetree.expression -> bool

val is_spread_belt_array_concat : Parsetree.expression -> bool
val is_spread_array : Parsetree.expression -> bool

val collect_spread_dict_expr_parts :
Parsetree.expression -> dict_expr_part list option
Expand Down
Loading
Loading