Skip to content

Ruby: Desugar for loops as calls to each #7098

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 19 commits into from
Nov 23, 2021
Merged

Ruby: Desugar for loops as calls to each #7098

merged 19 commits into from
Nov 23, 2021

Conversation

alexrford
Copy link
Contributor

@alexrford alexrford commented Nov 9, 2021

Desugars:

for x in xs
  <loop_body>
end

into

xs.each { |__synth__0| x = __synth__0; <loop_body> }

This, roughly, is what MRI does. Desugaring these lets us drop the custom control flow graph handling for for loops and instead rely on "standard" modelling of calls to each.

I'm mostly satisfied with the shape of the AST, couple of minor notes:

  • Block arguments to MethodCallSynth are given index -2, as -1 denotes a desugared version of the call, 0 the receiver, and 1,2,3,... any arguments.
  • The synthesized block itself has children 0..n-1 to represent its parameters, and children n..m to represent the statements in its body, where n is the number of parameters to the block, and m - n + 1 is number of statements in the block body - i.e. Parameters, then Stmts

@github-actions github-actions bot added the Ruby label Nov 9, 2021
@alexrford alexrford marked this pull request as ready for review November 11, 2021 18:41
@alexrford alexrford requested a review from a team as a code owner November 11, 2021 18:41
@hvitved
Copy link
Contributor

hvitved commented Nov 16, 2021

I will rebase and resolve merge conflicts once #7141 is merged.

Commit 028ef6f had the unintended side-effect
that the AST and CFG stages got merged, because the AST stage's `isCapturedAccess`
now depends on `getCfgScopeImpl`, which belongs to the CFG stage.

The fix is to remove `getCfgScopeImpl` from the CFG stage, and instead let it
be part of the AST stage.
Copy link
Contributor

@nickrolfe nickrolfe left a comment

Choose a reason for hiding this comment

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

Nice work! That's been on the TODO list for a long time.

I can see why – there are a lot of changes, and it would be difficult for me to understand them all and really review them in detail. But overall it makes sense, and all the test changes that I did look into were sensible.

result = s
or
not s instanceof MethodBase and
not s instanceof ModuleBase and
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is this line needed? (Maybe add a comment?)

Copy link
Contributor

Choose a reason for hiding this comment

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

I guess it is not needed, since a module cannot be inside a method (right?)

Copy link
Contributor

Choose a reason for hiding this comment

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

It looks like singleton classes can be inside methods. Here's one example I found: https://github.com/gitlabhq/gitlabhq/blob/94ecc00f47df7051eea905a5899053bf476e0589/app/services/users/signup_service.rb#L27-L32

Copy link
Contributor

Choose a reason for hiding this comment

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

A module can be created in the body of a method, however, from a scope point of view the method and the module are unrelated.

This is in order to avoid name clash with the often so-named IPA type for data-
flow nodes. The name clash is not problematic because they are both in scope,
but because (cached) IPA types with overlapping names are known to sometimes
result in re-evaluation of cached stages, when one of the IPA types gets an
internal `#2` suffix in one query run, and the other IPA type gets the suffix
in another run.
@alexrford alexrford requested a review from a team as a code owner November 18, 2021 18:26
@github-actions github-actions bot added the C# label Nov 18, 2021
@hvitved hvitved merged commit 9d072a1 into main Nov 23, 2021
@hvitved hvitved deleted the ruby/desugar-for-1 branch November 23, 2021 10:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants