summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorKevin Newton <[email protected]>2025-01-14 13:10:46 -0500
committergit <[email protected]>2025-01-14 20:31:38 +0000
commit51d3d6ac8c2e3b6b6dacd80a9ddf11adc46fde08 (patch)
tree811c3723b8e7069eb12aa10536fff6088631e0aa /test
parentf5fa1ee5f6e0e29e15063e8b62eb0ce7042bb29b (diff)
[ruby/prism] Support forwarding flags on scopes
When parent scopes around an eval are forwarding parameters (like *, **, &, or ...) we need to know that information when we are in the parser. As such, we need to support passing that information into the scopes option. In order to do this, unfortunately we need a bunch of changes. The scopes option was previously an array of array of strings. These corresponded to the names of the locals in the parent scopes. We still support this, but now additionally support passing in a Prism::Scope instance at each index in the array. This Prism::Scope class holds both the names of the locals as well as an array of forwarding parameter names (symbols corresponding to the forwarding parameters). There is convenience function on the Prism module that creates a Prism::Scope object using Prism.scope. In JavaScript, we now additionally support an object much the same as the Ruby side. In Java, we now have a ParsingOptions.Scope class that holds that information. In the dump APIs, these objects in all 3 languages will add an additional byte for the forwarding flags in the middle of the scopes serialization. All of this is in service of properly parsing the following code: ```ruby def foo(*) = eval("bar(*)") ``` https://github.com/ruby/prism/commit/21abb6b7c4
Diffstat (limited to 'test')
-rw-r--r--test/prism/api/parse_test.rb18
1 files changed, 18 insertions, 0 deletions
diff --git a/test/prism/api/parse_test.rb b/test/prism/api/parse_test.rb
index 55b2731225..bbce8a8fad 100644
--- a/test/prism/api/parse_test.rb
+++ b/test/prism/api/parse_test.rb
@@ -140,6 +140,24 @@ module Prism
end
end
+ def test_scopes
+ assert_kind_of Prism::CallNode, Prism.parse_statement("foo")
+ assert_kind_of Prism::LocalVariableReadNode, Prism.parse_statement("foo", scopes: [[:foo]])
+ assert_kind_of Prism::LocalVariableReadNode, Prism.parse_statement("foo", scopes: [Prism.scope(locals: [:foo])])
+
+ assert Prism.parse_failure?("foo(*)")
+ assert Prism.parse_success?("foo(*)", scopes: [Prism.scope(forwarding: [:*])])
+
+ assert Prism.parse_failure?("foo(**)")
+ assert Prism.parse_success?("foo(**)", scopes: [Prism.scope(forwarding: [:**])])
+
+ assert Prism.parse_failure?("foo(&)")
+ assert Prism.parse_success?("foo(&)", scopes: [Prism.scope(forwarding: [:&])])
+
+ assert Prism.parse_failure?("foo(...)")
+ assert Prism.parse_success?("foo(...)", scopes: [Prism.scope(forwarding: [:"..."])])
+ end
+
private
def find_source_file_node(program)