Skip to content

Commit

Permalink
feat: add new case on platform
Browse files Browse the repository at this point in the history
  • Loading branch information
pedrobslisboa committed Nov 27, 2024
1 parent ab1564b commit 2c5e185
Show file tree
Hide file tree
Showing 11 changed files with 134 additions and 19 deletions.
4 changes: 2 additions & 2 deletions demo/server/Error.re
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
let handler =
Dream.error_template((error, info, suggested) => {
Dream.error_template((_error, info, suggested) => {
let status = Dream.status(suggested);
let code = Dream.status_to_int(status);
let _code = Dream.status_to_int(status);
let reason = Dream.status_to_string(status);
Dream.html(
ReactDOM.renderToStaticMarkup(
Expand Down
1 change: 0 additions & 1 deletion demo/server/dune
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
(name server)
(enabled_if
(= %{profile} "dev"))
(flags :standard -w -26-27) ; browser_only removes code form the server, making this warning necessary
(libraries
dream
demo_shared_native
Expand Down
2 changes: 1 addition & 1 deletion demo/server/server.re
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ let renderToStreamHandler = _ =>
let%lwt () = Dream.write(response_stream, data);
Dream.flush(response_stream);
};
let%lwt (stream, _abort) =
let%lwt (_stream, _abort) =
ReactDOM.renderToStream(~pipe, <Document> <Comments /> </Document>);
Lwt.return();
},
Expand Down
2 changes: 1 addition & 1 deletion demo/universal/native/lib/App.re
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ let make = () => {
<Stack gap=8 justify=`start>
<Title />
<Hr />
<Counter initial=23 />
<Counter initial=23 onClick={_ => print_endline("Clicked")} />
</Stack>
</Layout>;
};
31 changes: 20 additions & 11 deletions demo/universal/native/lib/Counter.re
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
[@warning "-27"];
let make = (~initial, ~onClick as [@platform js] onClick) => {
let (count, [@platform js] setCount) = RR.useStateValue(initial);

let make = (~initial) => {
let (state, setCount) = RR.useStateValue(initial);
switch%platform (Runtime.platform) {
| Server => print_endline("This prints to the server terminal")
| Client => print_endline("This prints to the console")
};

[@platform js]
let onClick = e => {
setCount(count + 1);

Js.log("This prints to the console");
Js.log2("Printing count", count);

let onClick = _event => {
setCount(state + 1);
onClick(e);
};

<div className={Theme.text(Theme.Color.white)}>
Expand All @@ -20,9 +29,9 @@ let make = (~initial) => {
{React.string("Counter")}
</p>
<button
onClick
className="font-mono border-2 py-1 px-2 rounded-lg bg-yellow-950 border-yellow-700 text-yellow-200">
{React.string(Int.to_string(state))}
className="font-mono border-2 py-1 px-2 rounded-lg bg-yellow-950 border-yellow-700 text-yellow-200"
onClick={[@platform js] e => onClick(e)}>
{React.string(Int.to_string(count))}
</button>
</div>
</Spacer>
Expand All @@ -36,16 +45,16 @@ let make = (~initial) => {
};

[@react.component]
let make = (~initial) =>
let make = (~initial, ~onClick as [@platform js] onClick) =>
switch%platform (Runtime.platform) {
| Server =>
React.Client_component({
import_module: "Counter",
import_name: "",
props: [("initial", React.Json(`Int(initial)))],
client: make(~initial),
client: make(~initial, ~onClick=_ => ()),
})
| Client => make(~initial)
| Client => make(~initial, ~onClick)
};

let default = make;
Expand Down
2 changes: 1 addition & 1 deletion demo/universal/native/lib/Noter.re
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ let make = (~valueIn3seconds as _) => {
</p>
<Note_editor title="Hello" body="World" />
<Hr />
<Counter initial=22 />
<Counter initial=22 onClick={_ => print_endline("Clicked")} />
<Hr />
</Stack>
</Layout>;
Expand Down
29 changes: 29 additions & 0 deletions packages/browser-ppx/ppx.ml
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,35 @@ module Preprocess = struct
| { psig_desc = Psig_attribute attr; _ } :: rest when is_platform_tag attr.attr_name.txt ->
if eval_attr attr = `keep then rest else []
| _ -> List.filter_map apply_config_on_signature_item sigi

method! expression expr =
let expr = super#expression expr in
match expr.pexp_desc with
| Pexp_ident _ | Pexp_constant _ ->
let loc = expr.pexp_loc in
[%expr [%ocaml.error "Don't use @platform in Pexp_ident or Pexp_constant"]]
| Pexp_let (_, [ { pvb_attributes = attrs; _ } ], body) -> if should_keep attrs = `keep then expr else body
| Pexp_fun _ ->
if should_keep expr.pexp_attributes = `keep then expr
else
let rec inner expr' =
match expr'.pexp_desc with
| Pexp_fun (label, def, _, expression) ->
Builder.pexp_fun ~loc:expr'.pexp_loc label def (Builder.ppat_any ~loc:expr'.pexp_loc)
(inner expression)
| _ ->
let loc = expr'.pexp_loc in
[%expr
Runtime.fail_impossible_action_in_ssr_anonymous
[%e Builder.estring ~loc (Astlib.Pprintast.string_of_expression expr)]]
in
inner expr
| _ -> expr

method! pattern pat =
let pat = super#pattern pat in
let loc = pat.ppat_loc in
if should_keep pat.ppat_attributes = `keep then pat else [%pat? _]
end
end

Expand Down
43 changes: 43 additions & 0 deletions packages/browser-ppx/tests/at_platform.t
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,49 @@ Pstr_value
$ ./standalone.exe -impl input_let.ml -js | ocamlformat - --enable-outside-detected-project --impl
let x = 42 [@@platform js]

Pexp_let

$ cat > input_let.ml << EOF
> let x =
> let y = 42 [@@platform js] in
> let y = 44 [@@platform native] in
> y
> EOF

$ ./standalone.exe -impl input_let.ml | ocamlformat - --enable-outside-detected-project --impl
let x =
let y = 44 [@@platform native] in
y

$ ./standalone.exe -impl input_let.ml -js | ocamlformat - --enable-outside-detected-project --impl
let x =
let y = 42 [@@platform js] in
y

Ppat_tuple

$ cat > input_let.ml << EOF
> let (x [@platform native], y [@platform js]) = (42, 44)
> EOF

$ ./standalone.exe -impl input_let.ml | ocamlformat - --enable-outside-detected-project --impl
let (x [@platform native]), _ = (42, 44)

$ ./standalone.exe -impl input_let.ml -js | ocamlformat - --enable-outside-detected-project --impl
let _, (y [@platform js]) = (42, 44)

Ppat_var

$ cat > input_let.ml << EOF
> let x ~onClick:((onClick)[@platform js]) = 42
> EOF

$ ./standalone.exe -impl input_let.ml | ocamlformat - --enable-outside-detected-project --impl
let x ~onClick:_ = 42

$ ./standalone.exe -impl input_let.ml -js | ocamlformat - --enable-outside-detected-project --impl
let x ~onClick:(onClick [@platform js]) = 42

Pstr_open

$ cat > input_open.ml << EOF
Expand Down
34 changes: 34 additions & 0 deletions packages/runtime/Runtime.ml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,40 @@ let fail_impossible_action_in_ssr fn =

Here's the raw callstack:

%s
|}
fn raw_callstack
in
raise (Impossible_in_ssr (Printf.sprintf {|'%s' shouldn't run on the server|} fn))

let fail_impossible_action_in_ssr_anonymous fn =
let backtrace = Printexc.get_callstack 8 in
let raw_callstack = Printexc.raw_backtrace_to_string backtrace in
let () =
Printf.printf
{|This function should only run on the client. Make sure you aren't accidentally calling this function in a server-side context.

Function: %s

Here's the raw callstack:

%s
|}
fn raw_callstack
in
raise (Impossible_in_ssr (Printf.sprintf {|'%s' shouldn't run on the server|} fn))

let fail_impossible_action_in_ssr_anonymous fn =
let backtrace = Printexc.get_callstack 8 in
let raw_callstack = Printexc.raw_backtrace_to_string backtrace in
let () =
Printf.printf
{|This function should only run on the client. Make sure you aren't accidentally calling this function in a server-side context.

Function: %s

Here's the raw callstack:

%s
|}
fn raw_callstack
Expand Down
1 change: 1 addition & 0 deletions packages/runtime/Runtime.mli
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ exception Impossible_in_ssr of string
(** Exception to throw when operations aren't meant to be running on native, mostly used by browser_ppx or ReactDOM *)

val fail_impossible_action_in_ssr : string -> 'a
val fail_impossible_action_in_ssr_anonymous : string -> 'a

type platform =
| Server
Expand Down
4 changes: 2 additions & 2 deletions packages/server-reason-react-ppx/server_reason_react_ppx.ml
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,7 @@ let rec transform_function_with_warning expression =
{ expression with pexp_desc = Pexp_sequence (wrapperExpression, exp) }
| _ -> expression

let transofrm_last_expression expr fn =
let transform_last_expression expr fn =
let rec inner expr =
match expr.pexp_desc with
| Pexp_sequence (expr, sequence) -> pexp_sequence ~loc:expr.pexp_loc expr (inner sequence)
Expand All @@ -475,7 +475,7 @@ let make_value_binding binding wrapping =
(* Append key argument since we want to allow users of this component to set key
(and assign it to _ since it shouldn't be used) *)
let body_expression =
pexp_fun ~loc:ghost_loc key_arg default_value key_pattern (transofrm_last_expression binding_expr wrapping)
pexp_fun ~loc:ghost_loc key_arg default_value key_pattern (transform_last_expression binding_expr wrapping)
in
Ast_helper.Vb.mk ~loc name body_expression

Expand Down

0 comments on commit 2c5e185

Please sign in to comment.