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

Better sorting for RBI nodes #405

Merged
merged 1 commit into from
Jul 29, 2021
Merged

Better sorting for RBI nodes #405

merged 1 commit into from
Jul 29, 2021

Conversation

Morriar
Copy link
Collaborator

@Morriar Morriar commented Jul 28, 2021

Motivation

Fix an early return in the node sorting as well as a conflicting node rank.

Implementation

Instead of returning early from the block, when two nodes are at a conflicting position in a tree, we preserve the original order in the non-sorted tree.

This means that mixins are always kept in the same order they were added to the tree even if moved around to satisfy the order against other node such as methods or constants.

Tests

See the new test file.

@Morriar Morriar requested a review from a team July 28, 2021 22:35
node.nodes.sort! do |a, b|
return 0 if a.is_a?(Mixin) || b.is_a?(Mixin)
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This was returning early. Thanks @paracycle 👀

else
9
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This was using the same rank number as scopes and consts

res = node_rank(a) <=> node_rank(b)
res = node_name(a) <=> node_name(b) if res == 0
res = (original_order[a] || 0) <=> (original_order[b] || 0) if res == 0
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Fall back on the original order if everything else fails

@@ -11,11 +11,11 @@ class SortNodes < Visitor
def visit(node)
return unless node.is_a?(Tree)
visit_all(node.nodes)
original_order = original_nodes_order(node.nodes.dup)
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Passing a copy so we always preserve the original order since the array will be sorted in place.

when TStructField then 4
when TEnumBlock then 5
when Group then group_rank(node.kind)
when Include, Extend then 10
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Using 10, 20, etc. so we can add some sub-ordering when needed (example with Method a few lines below)

lib/tapioca/rbi/rewriters/sort_nodes.rb Outdated Show resolved Hide resolved
res = node_rank(a) <=> node_rank(b)
res = node_name(a) <=> node_name(b) if res == 0
res = (original_order[a] || 0) <=> (original_order[b] || 0) if res == 0
Copy link
Member

Choose a reason for hiding this comment

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

I am not quite clear how we fallback to this case for mixins? Is it that their node names are always the same? What prevents mixin nodes from being sorted alphabetically?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

node_name always returns nil for nodes that shouldn't be sorted alphabetically: https://github.com/Shopify/tapioca/blob/master/lib/tapioca/rbi/rewriters/sort_nodes.rb#L69-L70

Signed-off-by: Alexandre Terrasa <alexandre.terrasa@shopify.com>
@Morriar Morriar merged commit 3424cb7 into master Jul 29, 2021
@Morriar Morriar deleted the at-fix-rbi-sort branch July 29, 2021 15:52
paracycle pushed a commit that referenced this pull request Aug 4, 2021
@shopify-shipit shopify-shipit bot temporarily deployed to production September 7, 2021 16:35 Inactive
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.

None yet

3 participants