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

[Feature #20257] Rearchitect Ripper #9923

Merged
merged 3 commits into from Feb 20, 2024
Merged

Conversation

yui-knk
Copy link
Contributor

@yui-knk yui-knk commented Feb 12, 2024

https://bugs.ruby-lang.org/issues/20257

Introduce another semantic value stack for Ripper so that Ripper can manage both Node and Ruby Object separately.
This rearchitectutre of Ripper solves these issues.
Therefore adding test cases for them.

@yui-knk
Copy link
Contributor Author

yui-knk commented Feb 15, 2024

@kddnewton

This PR fixes ripper bugs and makes lex state transition of parser and ripper to be aligned. However it makes one of the Prism test failed. I wrote the detail on the second commit. What do you think about it?

@kddnewton
Copy link
Contributor

This PR fixes ripper bugs and makes lex state transition of parser and ripper to be aligned. However it makes one of the Prism test failed. I wrote the detail on the second commit. What do you think about it?

In this case the parser state of prism is incorrect, as it should be in the ARG state after bar. The test failure is legitimate in that case, so we shouldn't skip the test, we should fix the problem.

@yui-knk
Copy link
Contributor Author

yui-knk commented Feb 15, 2024

Then I want to merge this PR with the second commit, is it ok for you? If you have another option, please let me know.

@kddnewton
Copy link
Contributor

Please implement a fix yourself or wait until I implement one. I don't think it's a good idea to just comment out tests that break when they are legitimate issues.

yui-knk added a commit to yui-knk/ruby that referenced this pull request Feb 16, 2024
@yui-knk
Copy link
Contributor Author

yui-knk commented Feb 16, 2024

@kddnewton I implemented workaround and change to not modify "test/prism/parse_test.rb". What do you think about it?

yui-knk added a commit to yui-knk/ruby that referenced this pull request Feb 16, 2024
@kddnewton
Copy link
Contributor

That seems to mask the problem. I'll take care of this first thing Monday, thank you for your patience.

Introduce another semantic value stack for Ripper so that
Ripper can manage both Node and Ruby Object separately.
This rearchitectutre of Ripper solves these issues.
Therefore adding test cases for them.

* [Bug 10436] https://bugs.ruby-lang.org/issues/10436
* [Bug 18988] https://bugs.ruby-lang.org/issues/18988
* [Bug 20055] https://bugs.ruby-lang.org/issues/20055

Checked the differences of `Ripper.sexp` for files under `/test/ruby`
are only on test_pattern_matching.rb.
The differences comes from the differences between
`new_hash_pattern_tail` functions between parser and Ripper.
Ripper `new_hash_pattern_tail` didn’t call `assignable` then
`kw_rest_arg` wasn’t marked as local variable.
This is also fixed by this commit.

```
--- a/./tmp/before/test_pattern_matching.rb
+++ b/./tmp/after/test_pattern_matching.rb
@@ -3607,7 +3607,7 @@
                  [:in,
                   [:hshptn, nil, [], [:var_field, [:@Ident, “a”, [984, 13]]]],
                   [[:binary,
-                    [:vcall, [:@Ident, “a”, [985, 10]]],
+                    [:var_ref, [:@Ident, “a”, [985, 10]]],
                     :==,
                     [:hash, nil]]],
                   nil]]],
@@ -3662,7 +3662,7 @@
                  [:in,
                   [:hshptn, nil, [], [:var_field, [:@Ident, “a”, [993, 13]]]],
                   [[:binary,
-                    [:vcall, [:@Ident, “a”, [994, 10]]],
+                    [:var_ref, [:@Ident, “a”, [994, 10]]],
                     :==,
                     [:hash,
                      [:assoclist_from_args,
@@ -3813,7 +3813,7 @@
                    [:command,
                     [:@Ident, “raise”, [1022, 10]],
                     [:args_add_block,
-                     [[:vcall, [:@Ident, “b”, [1022, 16]]]],
+                     [[:var_ref, [:@Ident, “b”, [1022, 16]]]],
                      false]]],
                   [:else, [[:var_ref, [:@kw, “true”, [1024, 10]]]]]]]],
                nil,
@@ -3876,7 +3876,7 @@
                      [:@int, “0”, [1033, 15]]],
                     :“&&“,
                     [:binary,
-                     [:vcall, [:@Ident, “b”, [1033, 20]]],
+                     [:var_ref, [:@Ident, “b”, [1033, 20]]],
                      :==,
                      [:hash, nil]]]],
                   nil]]],
@@ -3946,7 +3946,7 @@
                      [:@int, “0”, [1042, 15]]],
                     :“&&“,
                     [:binary,
-                     [:vcall, [:@Ident, “b”, [1042, 20]]],
+                     [:var_ref, [:@Ident, “b”, [1042, 20]]],
                      :==,
                      [:hash,
                       [:assoclist_from_args,
@@ -5206,7 +5206,7 @@
                      [[:assoc_new,
                        [:@Label, “c:“, [1352, 22]],
                        [:@int, “0”, [1352, 25]]]]]],
-                   [:vcall, [:@Ident, “r”, [1352, 29]]]],
+                   [:var_ref, [:@Ident, “r”, [1352, 29]]]],
                   false]]],
                [:binary,
                 [:call,
@@ -5299,7 +5299,7 @@
                       [:assoc_new,
                        [:@Label, “c:“, [1367, 34]],
                        [:@int, “0”, [1367, 37]]]]]],
-                   [:vcall, [:@Ident, “r”, [1367, 41]]]],
+                   [:var_ref, [:@Ident, “r”, [1367, 41]]]],
                   false]]],
                [:binary,
                 [:call,
@@ -5931,7 +5931,7 @@
              [:in,
               [:hshptn, nil, [], [:var_field, [:@Ident, “r”, [1533, 11]]]],
               [[:binary,
-                [:vcall, [:@Ident, “r”, [1534, 8]]],
+                [:var_ref, [:@Ident, “r”, [1534, 8]]],
                 :==,
                 [:hash,
                  [:assoclist_from_args,
```
The previous commit changes Ripper lex state behavior of `tLABEL`.
For example, Ripper lex state for the second `bar` was changed
by the previous commit.

```
def foo(bar: bar())
end
```

Before the commit, Ripper didn’t add label `bar` id to `vtable`
because `formal_argument` function for Ripper didn’t return id
but returned `VALUE lhs`.
Therefore Ripper didn’t `SET_LEX_STATE(EXPR_END|EXPR_LABEL)` for following `bar`
in `parse_ident` because `lvar_defined` for following `bar` was not true.

Currently Ripper does `SET_LEX_STATE(EXPR_END|EXPR_LABEL)` then
the result of this test case is changed like below.

```
Prism::ParseTest#test_filepath_unparser/corpus/literal/def.txt [ruby/test/prism/parse_test.rb:280]:
<[[80, 13], :on_ident, “bar”, END|LABEL]> expected but was
<[[80, 13], :on_ident, “bar”, ARG]>.
```

Parser sets lex state to `END|LABEL` on master branch.
Therefore previous commit makes Ripper’s behavior aligned with parser’s behavior.

```
$ ruby -v -y -e "def foo(bar: bar())" -e "end"
ruby 3.4.0dev (2024-02-11T23:52:05Z master 697ade7) [arm64-darwin21]
...
Reading a token
parser_dispatch_scan_event:11210 (1: 12|1|7)
lex_state: ARG|LABELED -> ARG at line 11113
lex_state: ARG -> END|LABEL at line 11128
parser_dispatch_scan_event:11877 (1: 13|3|4)
Next token is token “local variable or method” (1.13-1.16: bar)
Shifting token “local variable or method” (1.13-1.16: bar)
```
@yui-knk
Copy link
Contributor Author

yui-knk commented Feb 20, 2024

This PR changes a lot of line of parse.y and my other commits are created based on this change.
I will merge this PR.

@yui-knk yui-knk merged commit 2a4b6ed into ruby:master Feb 20, 2024
96 checks passed
@yui-knk yui-knk deleted the lrama_after_shift branch February 20, 2024 08:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
2 participants