Skip to content

Commit 15ded2d

Browse files
fhammerschmidttsnobip
authored andcommitted
Add more regression tests
1 parent f0c3ccd commit 15ded2d

File tree

35 files changed

+471
-20
lines changed

35 files changed

+471
-20
lines changed

compiler/core/lam_compile.ml

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -347,46 +347,51 @@ let compile output_prefix =
347347
push hidden_name;
348348
List.rev !candidates
349349
in
350-
let exported_hidden_component_name (module_id : J.module_id)
350+
let exported_hidden_component_name ~(id : Ident.t) ~(dynamic_import : bool)
351351
(hidden_name_candidates : string list) =
352352
let rec loop = function
353353
| [] -> None
354354
| candidate :: rest -> (
355355
match
356-
Lam_compile_env.query_external_id_info
357-
~dynamic_import:module_id.dynamic_import module_id.id
356+
Lam_compile_env.query_external_id_info ~dynamic_import id
358357
(candidate ^ "$jsx")
359358
with
360359
| _ -> Some candidate
361360
| exception Not_found -> loop rest)
362361
in
363-
match module_id.kind with
364-
| Ml -> loop hidden_name_candidates
365-
| _ -> None
362+
loop hidden_name_candidates
366363
in
367364
let rewrite_nested_jsx_component_expr (jsx_tag : Lam.t)
368365
(compiled_expr : J.expression) : J.expression =
369-
let rec extract_module_id (expr : J.expression) =
366+
let rec extract_root_expr (expr : J.expression) =
370367
match expr.expression_desc with
371-
| Var (Qualified (module_id, _)) -> Some module_id
372-
| Static_index (inner, _, _) -> extract_module_id inner
368+
| Var (Qualified (module_id, Some _)) ->
369+
Some {expr with expression_desc = Var (Qualified (module_id, None))}
370+
| Static_index (inner, _, _) -> extract_root_expr inner
371+
| Var _ -> Some expr
373372
| _ -> None
374373
in
374+
let hidden_component_access (root_expr : J.expression) hidden_name =
375+
match root_expr.expression_desc with
376+
| Var (Qualified (module_id, None)) ->
377+
{
378+
root_expr with
379+
expression_desc = Var (Qualified (module_id, Some hidden_name));
380+
}
381+
| _ -> E.dot root_expr hidden_name
382+
in
375383
match extract_nested_external_component_field jsx_tag with
376-
| Some (id, _dynamic_import, hidden_name) -> (
384+
| Some (id, dynamic_import, hidden_name) -> (
377385
let hidden_name_candidates =
378386
hidden_component_name_candidates id hidden_name
379387
in
380-
match extract_module_id compiled_expr with
381-
| Some module_id -> (
388+
match extract_root_expr compiled_expr with
389+
| Some root_expr -> (
382390
match
383-
exported_hidden_component_name module_id hidden_name_candidates
391+
exported_hidden_component_name ~id ~dynamic_import
392+
hidden_name_candidates
384393
with
385-
| Some hidden_name ->
386-
{
387-
compiled_expr with
388-
expression_desc = Var (Qualified (module_id, Some hidden_name));
389-
}
394+
| Some hidden_name -> hidden_component_access root_expr hidden_name
390395
| None -> compiled_expr)
391396
| None -> compiled_expr)
392397
| None -> compiled_expr
@@ -1671,7 +1676,7 @@ let compile output_prefix =
16711676
};
16721677
} -> (
16731678
match fld_info with
1674-
| Fld_module {name} ->
1679+
| Fld_module {name; jsx_component = _} ->
16751680
compile_external_field_apply ~dynamic_import appinfo id name lambda_cxt
16761681
| _ -> assert false)
16771682
| _ -> (
@@ -1795,7 +1800,7 @@ let compile output_prefix =
17951800
} -> (
17961801
(* should be before Lglobal_global *)
17971802
match fld_info with
1798-
| Fld_module {name = field} ->
1803+
| Fld_module {name = field; jsx_component = _} ->
17991804
compile_external_field ~dynamic_import lambda_cxt id field
18001805
| _ -> assert false)
18011806
| {primitive = Praise; args = [e]; _} -> (

compiler/syntax/src/jsx_v4.ml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -953,6 +953,10 @@ let map_binding ~config ~empty_loc ~pstr_loc ~file_name ~rec_flag binding =
953953
Some
954954
(make_new_binding ~loc:empty_loc ~full_module_name modified_binding)
955955
in
956+
let () =
957+
maybe_hoist_nested_make_component ~config ~empty_loc ~full_module_name
958+
fn_name
959+
in
956960
let binding_expr =
957961
{
958962
binding.pvb_expr with
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// @ts-check
2+
3+
import * as assert from "node:assert";
4+
import * as fs from "node:fs/promises";
5+
import * as path from "node:path";
6+
import { setup } from "#dev/process";
7+
8+
const { execBuild, execClean } = setup(import.meta.dirname);
9+
10+
await execClean();
11+
await execBuild();
12+
13+
const outputPath = path.join(import.meta.dirname, "src", "MainLayout.res.js");
14+
const output = await fs.readFile(outputPath, "utf8");
15+
const sidebarOutputPath = path.join(
16+
import.meta.dirname,
17+
"src",
18+
"Sidebar.res.js",
19+
);
20+
const sidebarOutput = await fs.readFile(sidebarOutputPath, "utf8");
21+
22+
assert.match(
23+
output,
24+
/JsxRuntime\.jsx\(Sidebar\$RscComponentWithPropsNested\.Sidebar\$Provider,/,
25+
);
26+
assert.doesNotMatch(output, /\.Provider\.make,/);
27+
assert.match(sidebarOutput, /Sidebar\$Provider\$jsx/);
28+
assert.match(
29+
sidebarOutput,
30+
/export \{[\s\S]*Provider,[\s\S]*Sidebar\$Provider,[\s\S]*Sidebar\$Provider\$jsx[\s\S]*\}/s,
31+
);
32+
33+
await execClean();
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"name": "rsc-component-with-props-nested",
3+
"jsx": {
4+
"version": 4
5+
},
6+
"sources": {
7+
"dir": "src",
8+
"subdirs": true
9+
},
10+
"package-specs": {
11+
"module": "esmodule",
12+
"in-source": true,
13+
"suffix": ".res.js"
14+
},
15+
"namespace": true
16+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
@react.component
2+
let make = (~children) => {
3+
<Sidebar.Provider> {children} </Sidebar.Provider>
4+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
type element
2+
3+
@val external null: element = "null"
4+
5+
external string: string => element = "%identity"
6+
7+
type componentLike<'props, 'return> = 'props => 'return
8+
9+
type component<'props> = componentLike<'props, element>
10+
11+
@module("react/jsx-runtime")
12+
external jsx: (component<'props>, 'props) => element = "jsx"
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
module Provider = {
2+
type props = {children: React.element}
3+
4+
@react.componentWithProps
5+
let make = props => props.children
6+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// @ts-check
2+
3+
import * as assert from "node:assert";
4+
import * as fs from "node:fs/promises";
5+
import * as path from "node:path";
6+
import { setup } from "#dev/process";
7+
8+
const { execBuild, execClean } = setup(import.meta.dirname);
9+
10+
await execClean();
11+
await execBuild();
12+
13+
const outputPath = path.join(import.meta.dirname, "src", "MainLayout.res.mjs");
14+
const output = await fs.readFile(outputPath, "utf8");
15+
16+
assert.match(
17+
output,
18+
/let DynamicSidebar = await import\("\.\/Sidebar\.res\.mjs"\);/,
19+
);
20+
assert.match(output, /let dynamicProvider = DynamicSidebar\.Provider\.make;/);
21+
assert.match(
22+
output,
23+
/JsxRuntime\.jsx\(Sidebar\$RscDynamicImportNestedJsx\.Sidebar\$Provider,/,
24+
);
25+
assert.doesNotMatch(
26+
output,
27+
/let dynamicProvider = DynamicSidebar\.Sidebar\$Provider;/,
28+
);
29+
30+
await execClean();
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"name": "rsc-dynamic-import-nested-jsx",
3+
"jsx": {
4+
"version": 4
5+
},
6+
"sources": {
7+
"dir": "src",
8+
"subdirs": true
9+
},
10+
"package-specs": {
11+
"module": "esmodule",
12+
"in-source": true,
13+
"suffix": ".res.mjs"
14+
},
15+
"namespace": true
16+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
module DynamicSidebar = await Sidebar
2+
3+
let dynamicProvider = DynamicSidebar.Provider.make
4+
5+
@react.component
6+
let make = (~children) => {
7+
<Sidebar.Provider> {Option.getOr(children, React.null)} </Sidebar.Provider>
8+
}

0 commit comments

Comments
 (0)