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

Scala: allow ellipsis in for loop headers #5661

Merged
merged 6 commits into from Jun 30, 2022

Conversation

mmcqd
Copy link
Member

@mmcqd mmcqd commented Jun 29, 2022

Fixes #5650

This PR adds support for Scala patterns like for (...; $X <- $Y if $COND; ...) { ... }. These are supported by adding a new MultiForEach for loop header to the generic AST. In the AST to IL translation, this construct is unrolled into nested for loops. Extending the generic AST to treat Scala's for loop headers as a list was more straightforward than attempting to do some funky matching involving big nested for loops.

This PR also deletes the GIf constructor for enumerators (for loop headers) from the Scala AST. As far as I can tell this was never actually produced by the parser, as guards are always parsed as directly part of a generator (x <- y). The Scala docs agree with me: https://scala-lang.org/files/archive/spec/2.13/06-expressions.html#for-comprehensions-and-for-loops. There is no mention of these guards that are not part of a generator.

test plan: make test

PR checklist:

  • Documentation is up-to-date
  • Changelog is up-to-date
  • Change has no security implications (otherwise, ping security team)

@linear
Copy link

linear bot commented Jun 29, 2022

PA-1579 Scala for loops parse error

I expected that for($EXPR2; $IDENT <- $GEN; $EXPR) {yield ... }
Or for(...; $IDENT <- $GEN; ...) {yield ... }

would parse as patterns but they don't as of 0.100: https://semgrep.dev/s/NoNx
From #5650
Originally opened by ievans

@mmcqd mmcqd requested a review from a team June 29, 2022 22:18
@aryx
Copy link
Collaborator

aryx commented Jun 30, 2022

great PR comment!

Copy link
Collaborator

@aryx aryx left a comment

Choose a reason for hiding this comment

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

Great work!

and multi_for_each =
| FE of for_each
| FECond of for_each * tok * expr
| FEllipsis of tok
Copy link
Collaborator

Choose a reason for hiding this comment

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

I usually add a semgrep-ext: comment before those constructs that are Semgrep specific.


and multi_for_each =
| FE of for_each
| FECond of for_each * tok * expr
Copy link
Collaborator

Choose a reason for hiding this comment

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

maybe in comment you can put an example, like x <- xs if x > 2

| G.FECond (a1, at, a2), B.FECond (b1, bt, b2) ->
m_for_each a1 b1 >>= fun () ->
m_tok at bt >>= fun () -> m_expr a2 b2
| G.FEllipsis _, _ -> return ()
Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't think this can can happen given the definition of m_list_with_dots, but I guess it does not hurt.

G.If (g_tok, G.Cond g_e, stmt, None) |> G.s)
guards stmt)
v2 v3
G.For (v1, G.MultiForEach v2, v3) |> G.s
Copy link
Collaborator

Choose a reason for hiding this comment

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

I usually try to avoid adding a construct in AST_generic when it's useful only for one language, but
maybe it's ok for this one indeed.

@aryx aryx merged commit 6368cff into develop Jun 30, 2022
@@ -4,6 +4,10 @@ This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html

## Unreleased

### Added

- Scala: ellipsis are now allowed in for loop headers (#5650)
Copy link
Collaborator

Choose a reason for hiding this comment

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

During the "changelog meeting" this week, Bruno said he is now the one who is looking at the changelog to help producing the release notes, and that he thinks we don't generally write good changelog entries (that allow him to do that job easily). I think he will have problems understanding the purpose of this one.

Copy link
Collaborator

Choose a reason for hiding this comment

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

You can ask him directly, but my understanding is that he would like to know that this change is to allow Scala users to use ellipsis to write patterns matching a sequence of nested for loops. He actually emphasized a lot the what, why, and how but I'm not sure how that would be instantiated in this particular case.

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 an example would be nice "(e.g., you can write a pattern like for(...; $X <- bar(); ...) { ... }".
Otherwise I feel the associated issue (#5650) mentioned in the changelog can help answer the what/why/how.

@brendongo brendongo deleted the matthew/pa-1579-scala-for-loops-parse-error branch July 1, 2022 01:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

Scala for loops parse error
3 participants