Skip to content
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

allow hyphens in JSX tag names and props #6609

Merged
merged 4 commits into from
Feb 7, 2024
Merged

allow hyphens in JSX tag names and props #6609

merged 4 commits into from
Feb 7, 2024

Conversation

tsnobip
Copy link
Contributor

@tsnobip tsnobip commented Feb 3, 2024

remaining:
- [ ] hyphens in prop names

Edit: We don't actually need to allow hyphens in prop names since we can use @as for them.

The current situation where scanner.mode is a list is not ideal, you end up pushing multiple times to this list, you never know what's the mode once you popped up, etc. I tried using GADT so you could restrict some functions to a given mode, but it doesn't play well with the rest of the interface (mutable fields everywhere). Meanwhile it could maybe just be replaced with just a value instead of a list. What's is even Diamond mode by the way?

@tsnobip tsnobip marked this pull request as ready for review February 3, 2024 15:13
@tsnobip tsnobip changed the base branch from master to 11.0_release February 3, 2024 18:20
Copy link
Collaborator

@zth zth left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great! I'm unfamiliar with the parser mode etc where most of the changes are, so I'm going to defer reviewing that part to @cristianoc who I believe knows more about that. Outside of that this looks like it does just what we want, great work!

@cristianoc
Copy link
Collaborator

not familiar with that part of the parser either, perhaps a little explanation of the changes would be useful, unless the changes are obviously correct

Copy link
Contributor Author

@tsnobip tsnobip left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a few comments to the PR to make it more understandable @cristianoc

| ('A' .. 'Z' | 'a' .. 'z' | '0' .. '9' | '_' | '\''), false ->
next scanner;
skipGoodChars scanner
| ('A' .. 'Z' | 'a' .. 'z' | '0' .. '9' | '_' | '\'' | '-'), true ->
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here we allow - as a valid identifier in Jsx mode.

@@ -431,16 +431,18 @@ let classifyIdentContent ?(allowUident = false) txt =
match String.unsafe_get txt i with
| 'A' .. 'Z' when allowUident -> loop (i + 1)
| 'a' .. 'z' | '_' -> loop (i + 1)
| '-' when allowHyphen -> loop (i + 1)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here we make identifiers with hyphen regular identifier instead of exotic ones that need to be printed inside double quotes

| _ -> ExoticIdent
else
match String.unsafe_get txt i with
| 'A' .. 'Z' | 'a' .. 'z' | '0' .. '9' | '\'' | '_' -> loop (i + 1)
| '-' when allowHyphen -> loop (i + 1)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

Comment on lines +2623 to +2624
Scanner.popMode p.scanner Jsx;
Scanner.setJsxMode p.scanner;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

by using popMode before setJsxMode we make sure we don't add too many times the Jsx mode to the scanner mode list.

I also made sure we were calling setJsxMode at the right place, which was not really the case before and led to invalid results (allowing hyphens in contexts that should not have been in Jsx mode).

Comment on lines +2689 to +2690
Scanner.popMode p.scanner Jsx;
Scanner.setJsxMode p.Parser.scanner;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here, making sure we call setJsxMode when calling parseJsx

Comment on lines +2828 to +2831
| _ ->
let children = List.rev (loop p []) in
Scanner.popMode p.scanner Jsx;
(false, children)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here I simplified the loop function by applying recurring processing to the result instead of doing it for every branch.

I also fixed the calls to pop/set jsx mode.

Comment on lines -7 to +8
let x = <\"custom-tag" className="container" />
let x = <Foo.\"custom-tag" className="container" />
let x = <custom-tag className="container" />
let x = <Foo.custom-tag className="container" />
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

<custom-tag is now allowed and should not be printed as <\"custom-tag" exotic identifier, hence the update

Comment on lines -2 to -11
Syntax error!
tests/parsing/errors/expressions/jsx.res:1:12

1 │ let x = <di-v />
2 │ let x = <Unclosed >;
3 │ let x = <Foo.Bar></Free.Will>;

I'm not sure what to parse here when looking at "-".


Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

<di-v is now a valid tag name for lowercase jsx tag, so the error got removed

Comment on lines -69 to +59
let x = ((di ~children:[] ())[@JSX ]) - (v / ([%rescript.exprhole ]))
let x = ((di-v ~children:[] ())[@JSX ])
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a valid tag now instead of a exprhole

Copy link
Collaborator

@cristianoc cristianoc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the detailed explanation.
Looks good to go!

@tsnobip tsnobip enabled auto-merge (rebase) February 7, 2024 09:55
@zth
Copy link
Collaborator

zth commented Feb 7, 2024

@tsnobip 🎉 would you add some docs too?

@tsnobip tsnobip merged commit da91552 into 11.0_release Feb 7, 2024
@zth zth deleted the hyphen_jsx branch February 7, 2024 10:22
@tsnobip
Copy link
Contributor Author

tsnobip commented Feb 7, 2024

@tsnobip 🎉 would you add some docs too?

sure, what would you like me to document? Should I add what characters are allowed for uncapitalized jsx tags here https://rescript-lang.org/docs/manual/latest/jsx#uncapitalized?

@zth
Copy link
Collaborator

zth commented Feb 7, 2024

A sub section like "Spread Props" perhaps? Just a quick note that hyphens are allowed in this particular case and can be used with web components etc.

tsnobip added a commit to tsnobip/rescript-lang.org that referenced this pull request Feb 8, 2024
@tsnobip
Copy link
Contributor Author

tsnobip commented Feb 8, 2024

A sub section like "Spread Props" perhaps? Just a quick note that hyphens are allowed in this particular case and can be used with web components etc.

@zth done here rescript-lang/rescript-lang.org#812

tsnobip added a commit to tsnobip/rescript-lang.org that referenced this pull request Feb 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants