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

Fix an incompatible behavior for Prism::Translation::Parser #2552

Closed

Conversation

koic
Copy link
Contributor

@koic koic commented Mar 4, 2024

This PR fixes the following incompatible behavior for Prism::Translation::Parser when using case/when/end with ; expression.

Expected

It returns the range of the semicolon even if there is a space before the semicolon:

$ bundle exec ruby -Ilib -rprism -rprism/translation/parser33 -ve \
'p Prism::Translation::Parser33.parse("case foo when x; end").children.to_a[1].loc.begin'
ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [x86_64-darwin22]
#<Parser::Source::Range (string) 15...16>
$ bundle exec ruby -Ilib -rprism -rprism/translation/parser33 -ve \
'p Prism::Translation::Parser33.parse("case foo when x; end").children.to_a[1].loc.begin.source'
ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [x86_64-darwin22]
";"

$ bundle exec ruby -Ilib -rprism -rprism/translation/parser33 -ve \
'p Prism::Translation::Parser33.parse("case foo when x ; end").children.to_a[1].loc.begin'
ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [x86_64-darwin22]
#<Parser::Source::Range (string) 16...17>
$ bundle exec ruby -Ilib -rprism -rprism/translation/parser33 -ve \
'p Prism::Translation::Parser33.parse("case foo when x ; end").children.to_a[1].loc.begin.source'
ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [x86_64-darwin22]
";"

Actual

It returns nil if there is a space before the semicolon:

$ bundle exec ruby -Ilib -rprism -rprism/translation/parser33 -ve \
'p Prism::Translation::Parser33.parse("case foo when x; end").children.to_a[1].loc.begin'
ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [x86_64-darwin22]
#<Parser::Source::Range (string) 15...16>
$ bundle exec ruby -Ilib -rprism -rprism/translation/parser33 -ve \
'p Prism::Translation::Parser33.parse("case foo when x; end").children.to_a[1].loc.begin.source'
ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [x86_64-darwin22]
";"

$ bundle exec ruby -Ilib -rprism -rprism/translation/parser33 -ve \
'p Prism::Translation::Parser33.parse("case foo when x ; end").children.to_a[1].loc.begin'
ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [x86_64-darwin22]
nil
$ bundle exec ruby -Ilib -rprism -rprism/translation/parser33 -ve \
'p Prism::Translation::Parser33.parse("case foo when x ; end").children.to_a[1].loc.begin.source'
ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [x86_64-darwin22]
-e:1:in `<main>': undefined method `source' for nil (NoMethodError)

p Prism::Translation::Parser33.parse("case foo when x ; end").children.to_a[1].loc.begin.source
                                                                                        ^^^^^^^

@kddnewton
Copy link
Collaborator

@koic I just added that to the WhenNode to fix this. Have you recompiled?

@koic
Copy link
Contributor Author

koic commented Mar 4, 2024

Oops, I forgot to recompile. But, after compiling, the following issues occur.

Expected

It returns the range of the semicolon even if there is a space before the semicolon:

$ bundle exec ruby -Ilib -rprism -rprism/translation/parser33 -ve 'p Prism::Translation::Parser33.parse("case foo when x; end").children.to_a[1].loc.begin'
ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [x86_64-darwin22]
#<Parser::Source::Range (string) 15...16>
$ bundle exec ruby -Ilib -rprism -rprism/translation/parser33 -ve 'p Prism::Translation::Parser33.parse("case foo when x; end").children.to_a[1].loc.begin.source'
ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [x86_64-darwin22]
";"

$ bundle exec ruby -Ilib -rprism -rprism/translation/parser33 -ve 'p Prism::Translation::Parser33.parse("case foo when x ; end").children.to_a[1].loc.begin'
ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [x86_64-darwin22]
#<Parser::Source::Range (string) 16...17>
$ bundle exec ruby -Ilib -rprism -rprism/translation/parser33 -ve 'p Prism::Translation::Parser33.parse("case foo when x ; end").children.to_a[1].loc.begin.source'
ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [x86_64-darwin22]
";"

Actual

It returns nil if there is a space before the semicolon:

$ bundle exec ruby -Ilib -rprism -rprism/translation/parser33 -ve 'p Prism::Translation::Parser33.parse("case foo when x; end").children.to_a[1].loc.begin'
ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [x86_64-darwin22]
#<Parser::Source::Range (string) 15...16>
$ bundle exec ruby -Ilib -rprism -rprism/translation/parser33 -ve 'p Prism::Translation::Parser33.parse("case foo when x; end").children.to_a[1].loc.begin.source'
ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [x86_64-darwin22]
";"

$ bundle exec ruby -Ilib -rprism -rprism/translation/parser33 -ve 'p Prism::Translation::Parser33.parse("case foo when x ; end").children.to_a[1].loc.begin'
ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [x86_64-darwin22]
nil
$ bundle exec ruby -Ilib -rprism -rprism/translation/parser33 -ve 'p Prism::Translation::Parser33.parse("case foo when x ; end").children.to_a[1].loc.begin.source'
ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [x86_64-darwin22]
-e:1:in `<main>': undefined method `source' for nil (NoMethodError)

p Prism::Translation::Parser33.parse("case foo when x ; end").children.to_a[1].loc.begin.source
                                                                                        ^^^^^^^

This PR also fixes the above issues. I've updated the PR description as well.

@koic koic force-pushed the fix_parser_translator_for_case_when_then branch from 1f7e2eb to 1aa9c8c Compare March 4, 2024 17:23
@koic koic changed the title Fix an error for Prism::Translation::Parser Fix an unexpected behavior for Prism::Translation::Parser Mar 4, 2024
@koic koic force-pushed the fix_parser_translator_for_case_when_then branch from 1aa9c8c to 098b9f5 Compare March 4, 2024 17:28
else
srange_find(node.conditions.last.location.end_offset, node.statements&.location&.start_offset || (node.conditions.last.location.end_offset + 1), [";"])
end,
srange_find(node.conditions.last.location.end_offset, node.statements&.location&.start_offset || node.statements&.then_keyword_loc, [";", "then"]),
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@koic koic force-pushed the fix_parser_translator_for_case_when_then branch from 098b9f5 to a181fa9 Compare April 2, 2024 14:17
@koic koic changed the title Fix an unexpected behavior for Prism::Translation::Parser Fix an incompatible behavior for Prism::Translation::Parser Apr 2, 2024
This PR fixes the following incompatible behavior for `Prism::Translation::Parser`
when using `case`/`when`/`end` with `;` expression.

## Expected

It returns the range of the semicolon even if there is a space before the semicolon:

```console
$ bundle exec ruby -Ilib -rprism -rprism/translation/parser33 -ve \
'p Prism::Translation::Parser33.parse("case foo when x; end").children.to_a[1].loc.begin'
ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [x86_64-darwin22]
#<Parser::Source::Range (string) 15...16>
$ bundle exec ruby -Ilib -rprism -rprism/translation/parser33 -ve \
'p Prism::Translation::Parser33.parse("case foo when x; end").children.to_a[1].loc.begin.source'
ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [x86_64-darwin22]
";"

$ bundle exec ruby -Ilib -rprism -rprism/translation/parser33 -ve \
'p Prism::Translation::Parser33.parse("case foo when x ; end").children.to_a[1].loc.begin'
ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [x86_64-darwin22]
#<Parser::Source::Range (string) 16...17>
$ bundle exec ruby -Ilib -rprism -rprism/translation/parser33 -ve \
'p Prism::Translation::Parser33.parse("case foo when x ; end").children.to_a[1].loc.begin.source'
ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [x86_64-darwin22]
";"
```

## Actual

It returns `nil` if there is a space before the semicolon:

```console
$ bundle exec ruby -Ilib -rprism -rprism/translation/parser33 -ve \
'p Prism::Translation::Parser33.parse("case foo when x; end").children.to_a[1].loc.begin'
ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [x86_64-darwin22]
#<Parser::Source::Range (string) 15...16>
$ bundle exec ruby -Ilib -rprism -rprism/translation/parser33 -ve \
'p Prism::Translation::Parser33.parse("case foo when x; end").children.to_a[1].loc.begin.source'
ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [x86_64-darwin22]
";"

$ bundle exec ruby -Ilib -rprism -rprism/translation/parser33 -ve \
'p Prism::Translation::Parser33.parse("case foo when x ; end").children.to_a[1].loc.begin'
ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [x86_64-darwin22]
nil
$ bundle exec ruby -Ilib -rprism -rprism/translation/parser33 -ve \
'p Prism::Translation::Parser33.parse("case foo when x ; end").children.to_a[1].loc.begin.source'
ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [x86_64-darwin22]
-e:1:in `<main>': undefined method `source' for nil (NoMethodError)

p Prism::Translation::Parser33.parse("case foo when x ; end").children.to_a[1].loc.begin.source
                                                                                        ^^^^^^^
```
@koic koic force-pushed the fix_parser_translator_for_case_when_then branch from a181fa9 to 9625805 Compare April 2, 2024 14:18
@kddnewton
Copy link
Collaborator

Thanks @koic, this problem ended up being handled by #2552

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

2 participants