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

Do not sort T::Struct fields (prop and const attributes) #140

Merged
merged 1 commit into from
Oct 4, 2022

Conversation

paracycle
Copy link
Member

Related to: https://github.com/Shopify/hedwig/pull/521

Sorbet defines the initializer depending on the declaration order of the fields. When we sort the fields, the initializer ends up not matching the declaration expected by Sorbet.

This is especially problematic if the initializer of the struct subclass is overriden, since the static type checker will raise an error if the order of the parameters in the initializer does not match the order that the props were declared, which is file order. An example can be seen
here. Since we generate the initializer params in document order, we should also generate props in document order as well.

Note: As I was removing TStructField from the node_name method case statement, I realized that we never really explicitly show which nodes should not be sorted by name, so I added an explicit nil returning case for those.

Sorbet defines the initializer depending on the declaration order of
the fields. When we sort the fields, the initializer ends up not
matching the declaration expected by Sorbet.

This is especially problematic if the initializer of the struct subclass
is overriden, since the static type checker will raise an error if the
order of the parameters in the initializer does not match the order that
the props were declared, which is file order. An example can be seen
here: https://sorbet.run/#%23%20typed%3A%20true%0A%0Aclass%20Foo%20%3C%20T%3A%3AStruct%0A%20%20const%20%3Abar%2C%20Integer%0A%20%20const%20%3Afoo%2C%20String%0A%0A%20%20sig%20%7B%20params%28foo%3A%20String%2C%20bar%3A%20Integer%29.void%20%7D%0A%20%20def%20initialize%28foo%3A%2C%20bar%3A%29%0A%20%20end%0Aend%0A%0A
@paracycle paracycle added the bugfix Fix a bug label Oct 3, 2022
@paracycle paracycle requested a review from egiurleo October 3, 2022 23:45
@paracycle paracycle requested a review from a team as a code owner October 3, 2022 23:45
Copy link

@solackerman solackerman left a comment

Choose a reason for hiding this comment

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

Nice!

Copy link
Contributor

@egiurleo egiurleo 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 fixing!

This change makes sense to me, but I'm wondering: why do nodes have to be sorted in the first place?

@paracycle
Copy link
Member Author

why do nodes have to be sorted in the first place?

For stability of output. If we don't sort to an expected order, then any change in the order of RBI node additions would cause the output to be different in spurious ways. For example, a class that changes the order in which its methods are declared, but nothing else, might end up causing an ordering change in its RBI file. Or, if two DSL compilers run in a different order, the resulting RBI file might look slightly different.

Having said this, I think we should make the nodes declare if they are sortable or not (or even better, what their sort key should be), so that we don't do this ad-hoc case/when over node types. But that is an improvement for another day.

@paracycle paracycle merged commit 425abe8 into main Oct 4, 2022
@paracycle paracycle deleted the uk-do-not-sort-tstruct-fields branch October 4, 2022 14:24
@egiurleo
Copy link
Contributor

egiurleo commented Oct 4, 2022

@paracycle Makes sense! Thanks for the explanation.

@shopify-shipit shopify-shipit bot temporarily deployed to production October 4, 2022 20:38 Inactive
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bugfix Fix a bug
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants