You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit e5a1dfd
Browse filesBrowse the repository at this point in the historyBrowse files
Represent JSX component annotations with a parsetree node
`@react.component`, `@jsx.component` and their `componentWithProps` forms
on a `let`, an `external` or a signature item become `pvb_jsx_component` /
`pval_jsx_component`: the kind (labelled arguments, optionally sharing a
props type given as `(: t)`, or a props record), the spelling, and the
attribute's location. `Ast_helper.Vb.mk` and `Val.mk` take the annotation
out of the attributes, as `Type.field` does for `@as`, and
`Vb.binding_attributes` / `Val.description_attributes` put it back where it
was written for the printers, the mappers and iterators, the v0 PPX bridge
and the typed tree. The JSX transform reads the node instead of scanning
attribute names. An annotation whose payload the transform does not
understand, such as `@react.component("x")`, stays an attribute and is now
reported; it used to be accepted with the payload ignored.
Example (rescript):
module C = {
@react.component("Button")
let make = (~label) => React.string(label)
}
Diagnostic (text):
@react.component takes no payload, or the props type to share, as in
@react.component(: props).
Review: Why a field on the binding, not a structure item of its own?
The annotation is written on a `let`, an `external` or a signature `let`,
and the JSX transform expands it in place. A field keeps that shape, and
bindings the transform leaves alone (local `let`s, `componentWithProps` on
a signature item, everything when JSX is off) keep their meaning without
special cases.
Review: Why does the typed tree get the attribute back?
Nothing downstream reads the node, but `.cmi` attributes and tools that
read typed attributes saw `@react.component` wherever the JSX transform
did not consume it. Restoring the written attributes keeps that, and with
it diagnostics that print those declarations.
Review: Where does the attribute go on the v0 wire?
At its source position among the other attributes. PPX output carries no
positions, so everything ties; the annotation then goes first, where it is
usually written. A PPX that writes it after another attribute sees the
order swapped after a round trip; `@as` has the same limitation.
Review: Do duplicates behave as before?
Yes. The first `@react.component`, or failing that the first
`componentWithProps`, becomes the node, the precedence the transform
always applied. The rest stay attributes: bindings drop them as before,
externals and signature items count them for the existing "Only one JSX
component call" and `componentWithProps` external errors.
Area: syntax printer frontend typechecker analysis tests
Output: unchanged, the test suites' generated JS is byte-identical; 232
generated programs compile to identical JS without JSX, and with JSX 4
except the 45 with an unsupported payload, which now fail with the error
above
Formatting: unchanged, base and branch res_parser print 232 generated and
comment-heavy files identically, plain and through the v0 AST
Formats: ast cmi cmt
PPX: unchanged wire: PPXs see the attributes at their source positions;
ast-mapping fixture JsxComponents.res
Editor: unchanged: iterators see the annotation as an attribute, and
Utils.is_jsx_component reads the node
Errors: none, because the new messages are inline `raise_errorf` calls,
which the catalog's scope leaves out
Tests: +tests/syntax_tests/data/ast-mapping/JsxComponents.res
+tests/build_tests/super_errors/fixtures/react_component_invalid_payload.res
+tests/build_tests/super_errors/fixtures/react_componentWithProps_invalid_payload.res
~tests/ounit_tests/ounit_ast_mapper0_tests.ml
Measured: differential harness, base vs branch bsc -bs-jsx 4: 187 of 232
programs identical, 45 differ by the new payload error; without JSX: 232
of 232 identical
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014hcyfimX2ss8qj5MZwdMdP
Signed-off-by: Christoph Knittel <ck@cca.io>
- Represent `@react.component`, `@jsx.component` and their `componentWithProps` forms with a dedicated parsetree node. https://github.com/rescript-lang/rescript/pull/XXXX
- Report a JSX component annotation with an unsupported payload, such as `@react.component("x")`, instead of ignoring the payload. https://github.com/rescript-lang/rescript/pull/XXXX
0 commit comments