Skip to content

Add loc to each props in JSX4 #5937

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

Merged
merged 11 commits into from
Jan 14, 2023
Merged

Add loc to each props in JSX4 #5937

merged 11 commits into from
Jan 14, 2023

Conversation

mununki
Copy link
Member

@mununki mununki commented Jan 10, 2023

This PR fixes the #5936. Now it shows the error with loc.
image
The message is not a bit kind yet, but the typechecker would not distinguish whether it is a type parameter of props type or not.

@mununki
Copy link
Member Author

mununki commented Jan 10, 2023

priority: 'priority,
text?: 'text,
}
type props<'priority, 'text> = {priority: 'priority, text?: 'text}
Copy link
Member Author

Choose a reason for hiding this comment

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

Wonder why this PR change leads to remove the trailing comma.

Copy link
Member

Choose a reason for hiding this comment

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

Probably formatted differently now because of the loc changes.

@mununki
Copy link
Member Author

mununki commented Jan 11, 2023

Now, it shows error like this:
image

priority: 'priority,
text?: 'text,
}
type props<'priority, 'text> = {priority: 'priority, text?: 'text}
Copy link
Member

Choose a reason for hiding this comment

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

Probably formatted differently now because of the loc changes.

@cknitt
Copy link
Member

cknitt commented Jan 11, 2023

I tested it and it works fine, thanks a lot!

I was wondering if it would be feasible to check for duplicate labels and emit an error directly in the PPX where there is still more information available than in the type checker. Then we could have an even better error message, something like Duplicate label "a".

@mununki
Copy link
Member Author

mununki commented Jan 11, 2023

Now it raises the error in ppx when there are duplicates. b825937
image

@mununki
Copy link
Member Author

mununki commented Jan 11, 2023

A bit polishing error msg
image

in
let duplicatedProp =
(* Find the duplicated prop from the back *)
namedTypeList |> List.rev
Copy link
Member

Choose a reason for hiding this comment

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

Now we always have to do an additional List.rev and List.map even if there are no duplicated labels at all, in which case we have another List.map below.

Could this be done in a more efficient way, avoiding additional List allocations in the standard case (no duplicate props)?
Maybe it would be better

Copy link
Member Author

Choose a reason for hiding this comment

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

Can you elavorate your thought? Do you mean that finding the duplicated prop without List.rev first and then List.rev if there is duplicated one?

Copy link
Member Author

Choose a reason for hiding this comment

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

Maybe this?

  1. check if there is duplicated without List.map or List.exists
  2. if there is, then List.map and List.rev

Copy link
Member

Choose a reason for hiding this comment

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

Yes, something like that, it would be ideal if we could perform the check without creating any additional lists.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, something like that, it would be ideal if we could perform the check without creating any additional lists.

Agree! I'll work on it.

Copy link
Member Author

Choose a reason for hiding this comment

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

Sorry for being late, I'm stuck with tasks from company 🥲

How does it look? 10421cd Looking a bit verbose, but I think it is avoiding the list relocation before checking for duplicated props.

Copy link
Member

Choose a reason for hiding this comment

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

Looks good to me! Thanks a lot!

@cknitt
Copy link
Member

cknitt commented Jan 13, 2023

I think it would be good to backport this one to 10.1 - what do you think @mununki @cristianoc?

@mununki
Copy link
Member Author

mununki commented Jan 13, 2023

Also backport to syntax repo for v10.1.1?

@cknitt
Copy link
Member

cknitt commented Jan 13, 2023

Ah, and a CHANGELOG entry would be great. 🙂

@@ -1844,11 +1844,11 @@ let tys_of_constr_args = function

let report_error ppf = function
| Repeated_parameter ->
fprintf ppf "A type parameter occurs several times"
fprintf ppf "A type parameter occurs several times. If this is a component, check for duplicated props."
Copy link
Collaborator

Choose a reason for hiding this comment

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

This change is not needed anymore right?

Copy link
Member Author

Choose a reason for hiding this comment

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

Correct, I will revert it.

in
let rec duplicated = function
| [] -> None
| hd :: tl -> if mem_label hd tl then Some hd else duplicated tl
Copy link
Collaborator

Choose a reason for hiding this comment

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

If you throw an error right here, then you don't need anything else below.
So a checkDuplicateLabel function that returns unit.

For perf, there are cases with several hundred props, in ReScript-react. This is quadratic, and happens only once when the big type is declared, but does not affect using the function. So I think it's OK.

| Some (_, label, _, loc, _) ->
React_jsx_common.raiseError ~loc "JSX: found the duplicated prop `%s`"
label
| None ->
Copy link
Collaborator

Choose a reason for hiding this comment

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

This logic is a bit unclear. If one throws an error above as soon as a duplicate is found, then this logic is not needed at all.

Copy link
Member Author

Choose a reason for hiding this comment

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

The logics after duplicated fn are to look for the duplicated prop in backward. If we get a duplicated prop's label and loc, then we can show the error msg pointing the last one.
Do you think it is enough to show the first duplicated prop as error msg?

Copy link
Collaborator

Choose a reason for hiding this comment

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

I think showing the first duplicated one is ok.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Otherwise, just reverse then iterate.

Copy link
Member Author

Choose a reason for hiding this comment

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

How does it look? b381364

Copy link
Collaborator

Choose a reason for hiding this comment

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

Looks great thanks.

let makeLabelDecls namedTypeList =
let rec mem_label ((_, la, _, _, _) as x) = function
| [] -> false
| (_, lb, _, _, _) :: l -> compare lb la = 0 || mem_label x l
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nit: lb = la is cleaner than using compare

Copy link
Collaborator

Choose a reason for hiding this comment

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

Also, it's way faster if one annotated that it's a string

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.

Looks good to go.

@mununki mununki merged commit 705b1c9 into master Jan 14, 2023
@mununki mununki deleted the add-loc-to-props branch January 14, 2023 10:04
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