-
-
Notifications
You must be signed in to change notification settings - Fork 9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
browser-ppx: process stritems #127
Conversation
else None | ||
| Psig_extension _ | Psig_attribute _ -> Some sigi | ||
|
||
let preprocess_impl _exp_ctxt str = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure what the _exp_ctxt
variable is about, it was introduced in ppxlib v2, @davesnx do you know?
~preprocess_impl:Preprocess.preprocess_impl | ||
~preprocess_intf:Preprocess.preprocess_intf |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a way to do this processing using just rules
so no preprocess_impl
or preprocess_intf
is used?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Haven't looked into the code, yet, but would be nice
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Happy to merge it as it is, we can push for a better impl with:
- usage of context free
- have proper errors when one is missing
- more test cases
$ ./standalone.exe -impl input.ml | ocamlformat - --enable-outside-detected-project --impl | ||
include struct | ||
type t = string | ||
end [@@platform native] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should remove the annotation no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I think it should. Will look into this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried removing the attributes but it's quite cumbersome. The approach I took is to transform should_keep
into st like this:
let rec should_keep attrs =
let rec f acc attrs =
match attrs with
| [] -> `keep (List.rev acc)
| attr :: attrs -> (
match eval_attr attr with
| `found_drop -> `drop
| `found_keep -> f acc attrs
| `not_found -> f (attr :: acc) attrs)
in
f [] attrs
The main issue I found is on the apply_config_on_structure_item
function. Instead of the current simple approach, it becomes this monster:
let apply_config_on_structure_item stri =
match stri.pstr_desc with
| Pstr_typext ({ ptyext_attributes = attrs; _ } as payload) -> (
match should_keep attrs with
| `keep attrs ->
Some (Pstr_typext { payload with ptyext_attributes = attrs })
| `drop -> None)
| Pstr_modtype ({ pmtd_attributes = attrs; _ } as payload) -> (
match should_keep attrs with
| `keep attrs ->
Some (Pstr_modtype { payload with pmtd_attributes = attrs })
| `drop -> None)
| Pstr_open ({ popen_attributes = attrs; _ } as payload) -> (
match should_keep attrs with
| `keep attrs ->
Some (Pstr_open { payload with popen_attributes = attrs })
| `drop -> None)
| Pstr_include ({ pincl_attributes = attrs; _ } as payload) -> (
match should_keep attrs with
| `keep attrs ->
Some (Pstr_include { payload with pincl_attributes = attrs })
| `drop -> None)
| Pstr_exception ({ ptyexn_attributes = attrs; _ } as payload) -> (
match should_keep attrs with
| `keep attrs ->
Some (Pstr_exception { payload with ptyexn_attributes = attrs })
| `drop -> None)
| Pstr_primitive ({ pval_attributes = attrs; _ } as payload) -> (
match should_keep attrs with
| `keep attrs ->
Some (Pstr_primitive { payload with pval_attributes = attrs })
| `drop -> None)
| Pstr_eval (str_desc, attrs) -> (
match should_keep attrs with
| `keep attrs -> Some (Pstr_eval (str_desc, attrs))
| `drop -> None)
| Pstr_module ({ pmb_attributes = attrs; _ } as payload) -> (
match should_keep attrs with
| `keep attrs ->
Some (Pstr_module { payload with pmb_attributes = attrs })
| `drop -> None)
...
I am sure there are ways in which it could be simplified, but after discussing with @davesnx we're punting on this for later (maybe we end up using extensions instead of attributes...)
> | ||
> include struct | ||
> type t = string | ||
> end [@@platform native] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wondering what happens (if ppx raises) when you add platform to only one
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nothing happens (in terms of errors), added a test here:
server-reason-react/packages/browser-ppx/tests/preprocess.t
Lines 27 to 51 in cb61e51
Use only one of the platforms | |
$ cat > input.ml << EOF | |
> include struct | |
> type t = Js.Json.t | |
> end [@@platform js] | |
> | |
> include struct | |
> type t = string | |
> end | |
> EOF | |
$ ./standalone.exe -impl input.ml | ocamlformat - --enable-outside-detected-project --impl | |
include struct | |
type t = string | |
end | |
$ ./standalone.exe -impl input.ml -js | ocamlformat - --enable-outside-detected-project --impl | |
include struct | |
type t = Js.Json.t | |
end [@@platform js] | |
include struct | |
type t = string | |
end |
| { pstr_desc = Pstr_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_structure_item str |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know you might not implemented this part, but why do we have 2 passes?
Probably [@platform] can be applied to any structure, not only modules in this case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure I understand the q, where are the two passes? What I understand this code is doing is:
- If the str item itself has an the platform attr, process it
- Otherwise, process whatever is inside the str item
is this necessary? I can imagine scenarios where one might want to run something only on one platform (e.g. some side effect). I also think it'll be quite challenging to implement "exhaustiveness" considering how this ppx is integrating at the str item level 🤔
I added a bunch of them in cb61e51. Lmk what you think! |
I took a stab at this too. It seems non-trivial because context-free:
I am not sure how to work around that 🤔 |
CHANGES: ## 0.3.1 * Update quickjs dependency to 0.1.2 by @davesnx ## 0.3.0 * browser-ppx: process stritems by @jchavarri in ml-in-barcelona/server-reason-react#127 * Make React.Children.* APIs work as expected by @davesnx in ml-in-barcelona/server-reason-react#130 * Improve global crashes by @davesnx in ml-in-barcelona/server-reason-react#132 * Support assets in `mel.module` by @jchavarri in ml-in-barcelona/server-reason-react#134 * browser_only: don't convert to runtime errors on identifiers or function application by @jchavarri in ml-in-barcelona/server-reason-react#138 * Port `j` quoted strings interpolation from Melange by @jchavarri in ml-in-barcelona/server-reason-react#139 * mel.module: handle asset prefix by @jchavarri in ml-in-barcelona/server-reason-react#140 * Add browser_only transformation to useEffect automatically by @davesnx in ml-in-barcelona/server-reason-react#145 * Append doctype tag on html lowercase by @davesnx in ml-in-barcelona/server-reason-react#136 * Transform Pexp_function with browser_only by @davesnx in ml-in-barcelona/server-reason-react#146 ## 0.2.0 - Remove data-reactroot attr from ReactDOM.renderToString ml-in-barcelona/server-reason-react#129 by @pedrobslisboa - Make useUrl return the provided serverUrl ml-in-barcelona/server-reason-react#125 by @purefunctor - Replace Js.Re implemenation from `pcre` to quickjs b1a3e225cdad1298d705fbbd9618e15b0427ef0f by @davesnx - Remove Belt.Array.push ml-in-barcelona/server-reason-react#122 by @davesnx ## 0.1.0 Initial release of server-reason-react, includes: - Server-side rendering of ReasonReact components (renderToString, renderToStaticMarkup & renderToLwtStream) - `server-reason-react.browser_ppx` for skipping code from the server - `server-reason-react.melange_ppx` for enabling melange bindings and extensions which run on the server - `server-reason-react.belt` a native Belt implementation - `server-reason-react.js` a native Js implementation (unsafe and limited) - `server-reason-react.url` and `server-reason-react.url-native` a universal library with both implementations to work with URLs on the server and the client - `server-reason-react.promise` and `server-reason-react.promise-native` a universal library with both implementations to work with Promises on the server and the client. Based on https://github.com/aantron/promise - `server-reason-react.melange-fetch` a fork of melange-fetch which is a melange library to fetch data on the client via the Fetch API. This fork is to be able to compile it on the server (not running). - `server-reason-react.webapi` a fork of melange-webapi which is a melange library to work with the Web API on the client. This fork is to be able to compile it on the server (not running).
CHANGES: ## 0.3.1 * Update quickjs dependency to 0.1.2 by @davesnx ## 0.3.0 * browser-ppx: process stritems by @jchavarri in ml-in-barcelona/server-reason-react#127 * Make React.Children.* APIs work as expected by @davesnx in ml-in-barcelona/server-reason-react#130 * Improve global crashes by @davesnx in ml-in-barcelona/server-reason-react#132 * Support assets in `mel.module` by @jchavarri in ml-in-barcelona/server-reason-react#134 * browser_only: don't convert to runtime errors on identifiers or function application by @jchavarri in ml-in-barcelona/server-reason-react#138 * Port `j` quoted strings interpolation from Melange by @jchavarri in ml-in-barcelona/server-reason-react#139 * mel.module: handle asset prefix by @jchavarri in ml-in-barcelona/server-reason-react#140 * Add browser_only transformation to useEffect automatically by @davesnx in ml-in-barcelona/server-reason-react#145 * Append doctype tag on html lowercase by @davesnx in ml-in-barcelona/server-reason-react#136 * Transform Pexp_function with browser_only by @davesnx in ml-in-barcelona/server-reason-react#146 ## 0.2.0 - Remove data-reactroot attr from ReactDOM.renderToString ml-in-barcelona/server-reason-react#129 by @pedrobslisboa - Make useUrl return the provided serverUrl ml-in-barcelona/server-reason-react#125 by @purefunctor - Replace Js.Re implemenation from `pcre` to quickjs b1a3e225cdad1298d705fbbd9618e15b0427ef0f by @davesnx - Remove Belt.Array.push ml-in-barcelona/server-reason-react#122 by @davesnx ## 0.1.0 Initial release of server-reason-react, includes: - Server-side rendering of ReasonReact components (renderToString, renderToStaticMarkup & renderToLwtStream) - `server-reason-react.browser_ppx` for skipping code from the server - `server-reason-react.melange_ppx` for enabling melange bindings and extensions which run on the server - `server-reason-react.belt` a native Belt implementation - `server-reason-react.js` a native Js implementation (unsafe and limited) - `server-reason-react.url` and `server-reason-react.url-native` a universal library with both implementations to work with URLs on the server and the client - `server-reason-react.promise` and `server-reason-react.promise-native` a universal library with both implementations to work with Promises on the server and the client. Based on https://github.com/aantron/promise - `server-reason-react.melange-fetch` a fork of melange-fetch which is a melange library to fetch data on the client via the Fetch API. This fork is to be able to compile it on the server (not running). - `server-reason-react.webapi` a fork of melange-webapi which is a melange library to work with the Web API on the client. This fork is to be able to compile it on the server (not running).
Allows to do things like:
Both
platform
orbrowser-ppx
can be used as the attribute tag (this change applies to every existing preprocessing ofbrowser-ppx
as well).