From 54274b8c65a0981f1c69055a1513ba3c614dd675 Mon Sep 17 00:00:00 2001 From: Burdette Lamar Date: Wed, 6 Sep 2023 17:26:11 -0500 Subject: [PATCH 01/46] [DOC] Rdoc for Process::Status (#8386) --- process.c | 89 ++++++++++++++++++++++++++----------------------------- 1 file changed, 42 insertions(+), 47 deletions(-) diff --git a/process.c b/process.c index acb74c2d47b167..aaea02a0f808c6 100644 --- a/process.c +++ b/process.c @@ -857,10 +857,15 @@ pst_inspect(VALUE st) /* * call-seq: - * stat == other -> true or false + * stat == other -> true or false + * + * Returns whether the value of #to_i == +other+: + * + * `cat /nop` + * stat = $? # => # + * sprintf('%x', stat.to_i) # => "100" + * stat == 0x100 # => true * - * Returns +true+ if the integer value of _stat_ - * equals other. */ static VALUE @@ -873,14 +878,15 @@ pst_equal(VALUE st1, VALUE st2) /* * call-seq: - * stat & num -> integer + * stat & mask -> integer + * + * Returns the logical AND of the value of #to_i with +mask+: * - * Logical AND of the bits in _stat_ with num. + * `cat /nop` + * stat = $? # => # + * sprintf('%x', stat.to_i) # => "100" + * stat & 0x00 # => 0 * - * fork { exit 0x37 } - * Process.wait - * sprintf('%04x', $?.to_i) #=> "3700" - * sprintf('%04x', $? & 0x1e00) #=> "1600" */ static VALUE @@ -894,14 +900,17 @@ pst_bitand(VALUE st1, VALUE st2) /* * call-seq: - * stat >> num -> integer + * stat >> places -> integer * - * Shift the bits in _stat_ right num places. + * Returns the value of #to_i, shifted +places+ to the right: * - * fork { exit 99 } #=> 26563 - * Process.wait #=> 26563 - * $?.to_i #=> 25344 - * $? >> 8 #=> 99 + * `cat /nop` + * stat = $? # => # + * stat.to_i # => 256 + * stat >> 1 # => 128 + * stat >> 2 # => 64 + * + * Returns zero if +places+ is negative. */ static VALUE @@ -1155,46 +1164,32 @@ rb_process_status_wait(rb_pid_t pid, int flags) /* * call-seq: - * Process::Status.wait(pid=-1, flags=0) -> Process::Status + * Process::Status.wait(pid = -1, flags = 0) -> Process::Status * - * Waits for a child process to exit and returns a Process::Status object - * containing information on that process. Which child it waits on - * depends on the value of _pid_: + * Like Process.wait, but returns a Process::Status object + * (instead of an integer pid or nil); + * see Process.wait for the values of +pid+ and +flags+. * - * > 0:: Waits for the child whose process ID equals _pid_. + * If there are child processes, + * waits for a child process to exit and returns a Process::Status object + * containing information on that process; + * sets thread-local variable $?: * - * 0:: Waits for any child whose process group ID equals that of the - * calling process. + * Process.spawn('cat /nop') # => 1155880 + * Process::Status.wait # => # + * $? # => # * - * -1:: Waits for any child process (the default if no _pid_ is - * given). + * If there is no child process, + * returns an "empty" Process::Status object + * that does not represent an actual process; + * does not set thread-local variable $?: * - * < -1:: Waits for any child whose process group ID equals the absolute - * value of _pid_. + * Process::Status.wait # => # + * $? # => # # Unchanged. * - * The _flags_ argument may be a logical or of the flag values - * Process::WNOHANG (do not block if no child available) - * or Process::WUNTRACED (return stopped children that - * haven't been reported). Not all flags are available on all - * platforms, but a flag value of zero will work on all platforms. + * May invoke the scheduler hook Fiber::Scheduler#process_wait. * - * Returns +nil+ if there are no child processes. * Not available on all platforms. - * - * May invoke the scheduler hook _process_wait_. - * - * fork { exit 99 } #=> 27429 - * Process::Status.wait #=> pid 27429 exit 99 - * $? #=> nil - * - * pid = fork { sleep 3 } #=> 27440 - * Time.now #=> 2008-03-08 19:56:16 +0900 - * Process::Status.wait(pid, Process::WNOHANG) #=> nil - * Time.now #=> 2008-03-08 19:56:16 +0900 - * Process::Status.wait(pid, 0) #=> pid 27440 exit 99 - * Time.now #=> 2008-03-08 19:56:19 +0900 - * - * This is an EXPERIMENTAL FEATURE. */ static VALUE From af1bedbbd93e952810149e79d7fa6c20960e5373 Mon Sep 17 00:00:00 2001 From: Martin Emde Date: Thu, 31 Aug 2023 20:08:33 -0700 Subject: [PATCH 02/46] [rubygems/rubygems] Source::Rubygems#fetch_names is only called with override = false https://github.com/rubygems/rubygems/commit/790202691d --- lib/bundler/source/rubygems.rb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/bundler/source/rubygems.rb b/lib/bundler/source/rubygems.rb index 7cd24092c93112..8977edc7c0ca77 100644 --- a/lib/bundler/source/rubygems.rb +++ b/lib/bundler/source/rubygems.rb @@ -274,7 +274,7 @@ def double_check_for(unmet_dependency_names) Bundler.ui.debug "Double checking for #{unmet_dependency_names || "all specs (due to the size of the request)"} in #{self}" - fetch_names(api_fetchers, unmet_dependency_names, remote_specs, false) + fetch_names(api_fetchers, unmet_dependency_names, remote_specs) specs.use(remote_specs, false) end @@ -401,22 +401,22 @@ def remote_specs index_fetchers = fetchers - api_fetchers if index_fetchers.empty? - fetch_names(api_fetchers, dependency_names, idx, false) + fetch_names(api_fetchers, dependency_names, idx) else - fetch_names(fetchers, nil, idx, false) + fetch_names(fetchers, nil, idx) end end end - def fetch_names(fetchers, dependency_names, index, override_dupes) + def fetch_names(fetchers, dependency_names, index) fetchers.each do |f| if dependency_names Bundler.ui.info "Fetching gem metadata from #{URICredentialsFilter.credential_filtered_uri(f.uri)}", Bundler.ui.debug? - index.use f.specs_with_retry(dependency_names, self), override_dupes + index.use f.specs_with_retry(dependency_names, self) Bundler.ui.info "" unless Bundler.ui.debug? # new line now that the dots are over else Bundler.ui.info "Fetching source index from #{URICredentialsFilter.credential_filtered_uri(f.uri)}" - index.use f.specs_with_retry(nil, self), override_dupes + index.use f.specs_with_retry(nil, self) end end end From 86b93f74819dc814a223cd179d15b4d46dc3fc7a Mon Sep 17 00:00:00 2001 From: Martin Emde Date: Thu, 31 Aug 2023 20:11:54 -0700 Subject: [PATCH 03/46] [rubygems/rubygems] Improve efficiency of Index#use and #search_all Rename Index#use(override = true) to #merge! Rename Index @all_specs to @duplicates, it is not actually all specs. @duplicates only holds specs that would have been overridden during a call to Index#use or Index#merge! Reduced dupes in @duplicates by not double adding the new spec to the index and the @duplicates during #merge! Reduce Array creation by using specialized methods when the one result or no results are needed from the search. https://github.com/rubygems/rubygems/commit/47e91125db --- lib/bundler/index.rb | 57 ++++++++++++++++++++++++---------- lib/bundler/source/rubygems.rb | 14 ++++----- 2 files changed, 48 insertions(+), 23 deletions(-) diff --git a/lib/bundler/index.rb b/lib/bundler/index.rb index b8c599f63af999..6a20302322f608 100644 --- a/lib/bundler/index.rb +++ b/lib/bundler/index.rb @@ -10,8 +10,8 @@ def self.build i end - attr_reader :specs, :all_specs, :sources - protected :specs, :all_specs + attr_reader :specs, :duplicates, :sources + protected :specs, :duplicates RUBY = "ruby" NULL = "\0" @@ -20,20 +20,20 @@ def initialize @sources = [] @cache = {} @specs = Hash.new {|h, k| h[k] = {} } - @all_specs = Hash.new {|h, k| h[k] = EMPTY_SEARCH } + @duplicates = {} end def initialize_copy(o) @sources = o.sources.dup @cache = {} @specs = Hash.new {|h, k| h[k] = {} } - @all_specs = Hash.new {|h, k| h[k] = EMPTY_SEARCH } + @duplicates = {} o.specs.each do |name, hash| @specs[name] = hash.dup end - o.all_specs.each do |name, array| - @all_specs[name] = array.dup + o.duplicates.each do |name, array| + @duplicates[name] = array.dup end end @@ -47,7 +47,9 @@ def empty? end def search_all(name) - all_matches = local_search(name) + @all_specs[name] + all_matches = specs_by_name(name) # always returns a new Array + dupes = @duplicates[name] + all_matches.concat(dupes) if dupes @sources.each do |source| all_matches.concat(source.search_all(name)) end @@ -78,10 +80,11 @@ def local_search(query) alias_method :[], :search - def <<(spec) + def add(spec) @specs[spec.name][spec.full_name] = spec spec end + alias_method :<<, :add def each(&blk) return enum_for(:each) unless blk @@ -115,15 +118,25 @@ def dependency_names names.uniq end - def use(other, override_dupes = false) + # Combines indexes proritizing existing specs, like `Hash#reverse_merge!` + # Duplicate specs found in `other` are stored in `@duplicates`. + def use(other) return unless other - other.each do |s| - if (dupes = search_by_spec(s)) && !dupes.empty? - # safe to << since it's a new array when it has contents - @all_specs[s.name] = dupes << s - next unless override_dupes + other.each do |spec| + exist?(spec) ? add_duplicate(spec) : add(spec) + end + self + end + + # Combines indexes proritizing specs from `other`, like `Hash#merge!` + # Duplicate specs found in `self` are saved in `@duplicates`. + def merge!(other) + return unless other + other.each do |spec| + if existing = find_by_spec(spec) + add_duplicate(existing) end - self << s + add spec end self end @@ -157,6 +170,10 @@ def add_source(index) private + def add_duplicate(spec) + (@duplicates[spec.name] ||= []) << spec + end + def specs_by_name_and_version(name, version) specs_by_name(name).select {|spec| spec.version == version } end @@ -168,8 +185,16 @@ def specs_by_name(name) EMPTY_SEARCH = [].freeze def search_by_spec(spec) - spec = @specs[spec.name][spec.full_name] + spec = find_by_spec(spec) spec ? [spec] : EMPTY_SEARCH end + + def find_by_spec(spec) + @specs[spec.name][spec.full_name] + end + + def exist?(spec) + @specs[spec.name].key?(spec.full_name) + end end end diff --git a/lib/bundler/source/rubygems.rb b/lib/bundler/source/rubygems.rb index 8977edc7c0ca77..dc82d1d33ccfc3 100644 --- a/lib/bundler/source/rubygems.rb +++ b/lib/bundler/source/rubygems.rb @@ -128,12 +128,12 @@ def identifier def specs @specs ||= begin # remote_specs usually generates a way larger Index than the other - # sources, and large_idx.use small_idx is way faster than - # small_idx.use large_idx. - idx = @allow_remote ? remote_specs.dup : Index.new - idx.use(cached_specs, :override_dupes) if @allow_cached || @allow_remote - idx.use(installed_specs, :override_dupes) if @allow_local - idx + # sources, and large_idx.merge! small_idx is way faster than + # small_idx.merge! large_idx. + index = @allow_remote ? remote_specs.dup : Index.new + index.merge!(cached_specs) if @allow_cached || @allow_remote + index.merge!(installed_specs) if @allow_local + index end end @@ -276,7 +276,7 @@ def double_check_for(unmet_dependency_names) fetch_names(api_fetchers, unmet_dependency_names, remote_specs) - specs.use(remote_specs, false) + specs.use remote_specs end def dependency_names_to_double_check From 89cb95679dfcb15e404d03959497e5b1dda78df3 Mon Sep 17 00:00:00 2001 From: Martin Emde Date: Thu, 31 Aug 2023 21:38:52 -0700 Subject: [PATCH 04/46] [rubygems/rubygems] Reduce excess index creation and merging When @allow_cached is true, @allow_local is always true, therefore, the #installed_specs will always be merged after #cached_specs is called. This makes starting with installed_specs.dup redundant. When #cached_specs is called because @allow_remote is true and @allow_cached is false, then installed_specs will be added after cached_specs based on @allow_local. We never need to add installed_specs here, so don't. https://github.com/rubygems/rubygems/commit/49b38f9750 --- lib/bundler/source/rubygems.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/bundler/source/rubygems.rb b/lib/bundler/source/rubygems.rb index dc82d1d33ccfc3..44102c47c829a5 100644 --- a/lib/bundler/source/rubygems.rb +++ b/lib/bundler/source/rubygems.rb @@ -380,7 +380,7 @@ def installed_specs def cached_specs @cached_specs ||= begin - idx = @allow_local ? installed_specs.dup : Index.new + idx = Index.new Dir["#{cache_path}/*.gem"].each do |gemfile| s ||= Bundler.rubygems.spec_from_gem(gemfile) From ac65fc833d79ad519c114647b3624a733cdd5485 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Thu, 7 Sep 2023 10:05:10 +0900 Subject: [PATCH 05/46] [DOC] Fix up Process::Status#>> --- process.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/process.c b/process.c index aaea02a0f808c6..681535d92fd452 100644 --- a/process.c +++ b/process.c @@ -910,7 +910,7 @@ pst_bitand(VALUE st1, VALUE st2) * stat >> 1 # => 128 * stat >> 2 # => 64 * - * Returns zero if +places+ is negative. + * The behavior is unspecified if +places+ is negative. */ static VALUE From 05aaff2191cbe777d1efb915ab9652eeaa1c16b8 Mon Sep 17 00:00:00 2001 From: Samuel Williams Date: Thu, 7 Sep 2023 13:53:51 +1200 Subject: [PATCH 06/46] Reduce number of iterations in `TestFiberScheduler#test_autoload`. (#8391) `ppc64le` appears to be struggling with this test due to timeout. Let's see if reducing the number of iterations can help improve the test performance. --- test/fiber/test_scheduler.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/fiber/test_scheduler.rb b/test/fiber/test_scheduler.rb index f8993bb18f3956..34effad816316a 100644 --- a/test/fiber/test_scheduler.rb +++ b/test/fiber/test_scheduler.rb @@ -118,7 +118,7 @@ def test_current_scheduler end def test_autoload - 100.times do + 10.times do Object.autoload(:TestFiberSchedulerAutoload, File.expand_path("autoload.rb", __dir__)) thread = Thread.new do From bd046764e31267c83e7ae515d9bc7f09ffaa5b95 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Wed, 29 Mar 2023 18:42:46 +0900 Subject: [PATCH 07/46] [Bug #19549] Check for variables to be interpolated --- parse.y | 18 ++---------------- test/ruby/test_parse.rb | 5 +++++ 2 files changed, 7 insertions(+), 16 deletions(-) diff --git a/parse.y b/parse.y index 8b88b1b38df6a8..277d313592ce9d 100644 --- a/parse.y +++ b/parse.y @@ -5432,24 +5432,10 @@ string_dend : tSTRING_DEND | END_OF_INPUT ; -string_dvar : tGVAR +string_dvar : nonlocal_var { /*%%%*/ - $$ = NEW_GVAR($1, &@$); - /*% %*/ - /*% ripper: var_ref!($1) %*/ - } - | tIVAR - { - /*%%%*/ - $$ = NEW_IVAR($1, &@$); - /*% %*/ - /*% ripper: var_ref!($1) %*/ - } - | tCVAR - { - /*%%%*/ - $$ = NEW_CVAR($1, &@$); + if (!($$ = gettable(p, $1, &@$))) $$ = NEW_BEGIN(0, &@$); /*% %*/ /*% ripper: var_ref!($1) %*/ } diff --git a/test/ruby/test_parse.rb b/test/ruby/test_parse.rb index cf989d190b20f0..957a37eb81bb8a 100644 --- a/test/ruby/test_parse.rb +++ b/test/ruby/test_parse.rb @@ -1443,6 +1443,11 @@ def set(arg) assert_equal(expected, obj.arg) end + def test_ungettable_gvar + assert_syntax_error('$01234', /not valid to get/) + assert_syntax_error('"#$01234"', /not valid to get/) + end + =begin def test_past_scope_variable assert_warning(/past scope/) {catch {|tag| eval("BEGIN{throw tag}; tap {a = 1}; a")}} From 009e0a3f9e26b30623ade32f7edf1806426f3a45 Mon Sep 17 00:00:00 2001 From: git Date: Thu, 7 Sep 2023 06:59:55 +0000 Subject: [PATCH 08/46] Update bundled gems list at 2023-09-07 --- NEWS.md | 2 +- gems/bundled_gems | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/NEWS.md b/NEWS.md index f424808bf2d203..d15bf224c74c7e 100644 --- a/NEWS.md +++ b/NEWS.md @@ -100,7 +100,7 @@ The following default gems are updated. The following bundled gems are updated. -* minitest 5.19.0 +* minitest 5.20.0 * test-unit 3.6.1 * rexml 3.2.6 * rss 0.3.0 diff --git a/gems/bundled_gems b/gems/bundled_gems index f11380027ac77c..34433723fa5368 100644 --- a/gems/bundled_gems +++ b/gems/bundled_gems @@ -5,7 +5,7 @@ # - repository-url: URL from where clone for test # - revision: revision in repository-url to test # if `revision` is not given, "v"+`version` or `version` will be used. -minitest 5.19.0 https://github.com/minitest/minitest +minitest 5.20.0 https://github.com/minitest/minitest power_assert 2.0.3 https://github.com/ruby/power_assert rake 13.0.6 https://github.com/ruby/rake test-unit 3.6.1 https://github.com/test-unit/test-unit From 5184b40dd4dc446660cd35c3e53896324e95b317 Mon Sep 17 00:00:00 2001 From: Samuel Williams Date: Fri, 8 Sep 2023 00:32:54 +1200 Subject: [PATCH 09/46] Extract `do_mutex_lock_check_interrupts` to try and fix `ppc64le`. (#8393) We found some tests were hanging in `do_mutex_lock`, specifically the fiber scheduler autoload test. After much investigation, it may be a code generation bug. Because we didn't change the code, but only extracted it into a separate function, and it appears to fix the problem. --- thread_sync.c | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/thread_sync.c b/thread_sync.c index 85ebec4d8cfc3d..63f0228d9d1a7b 100644 --- a/thread_sync.c +++ b/thread_sync.c @@ -290,6 +290,28 @@ delete_from_waitq(VALUE value) return Qnil; } +static void +do_mutex_lock_check_interrupts(int interruptible_p, rb_fiber_t *fiber, rb_mutex_t *mutex, rb_thread_t *thread) +{ + // We extracted this function because we suspect there can be a codegen bug + // on ppc64le and moving this code to a separate function seems to fix the + // problem, at least in my tests. + if (interruptible_p) { + /* release mutex before checking for interrupts...as interrupt checking + * code might call rb_raise() */ + if (mutex->fiber == fiber) { + mutex->fiber = 0; + } + + RUBY_VM_CHECK_INTS_BLOCKING(thread->ec); /* may release mutex */ + + if (!mutex->fiber) { + mutex->fiber = fiber; + } + } +} + + static VALUE do_mutex_lock(VALUE self, int interruptible_p) { @@ -378,15 +400,7 @@ do_mutex_lock(VALUE self, int interruptible_p) rb_ractor_sleeper_threads_dec(th->ractor); } - if (interruptible_p) { - /* release mutex before checking for interrupts...as interrupt checking - * code might call rb_raise() */ - if (mutex->fiber == fiber) mutex->fiber = 0; - RUBY_VM_CHECK_INTS_BLOCKING(th->ec); /* may release mutex */ - if (!mutex->fiber) { - mutex->fiber = fiber; - } - } + do_mutex_lock_check_interrupts(interruptible_p, fiber, mutex, th); } if (mutex->fiber == fiber) mutex_locked(th, self); From e2a0f25888d089f6f858e584c3210c2d00ad3f12 Mon Sep 17 00:00:00 2001 From: Kevin Newton Date: Wed, 6 Sep 2023 15:30:38 -0400 Subject: [PATCH 10/46] [ruby/yarp] Remove name constant from classes/modules https://github.com/ruby/yarp/commit/26105f0b58 --- test/yarp/errors_test.rb | 10 +++------- test/yarp/snapshots/classes.txt | 7 ------- test/yarp/snapshots/method_calls.txt | 2 -- test/yarp/snapshots/modules.txt | 6 ------ test/yarp/snapshots/seattlerb/TestRubyParserShared.txt | 7 ------- test/yarp/snapshots/seattlerb/class_comments.txt | 1 - test/yarp/snapshots/seattlerb/defn_oneliner_eq2.txt | 1 - test/yarp/snapshots/seattlerb/defs_oneliner_eq2.txt | 1 - .../snapshots/seattlerb/magic_encoding_comment.txt | 1 - test/yarp/snapshots/seattlerb/module_comments.txt | 1 - .../seattlerb/parse_line_heredoc_hardnewline.txt | 1 - test/yarp/snapshots/unparser/corpus/literal/class.txt | 8 -------- test/yarp/snapshots/unparser/corpus/literal/if.txt | 2 -- test/yarp/snapshots/unparser/corpus/literal/module.txt | 4 ---- test/yarp/snapshots/unparser/corpus/literal/send.txt | 4 ---- test/yarp/snapshots/unparser/corpus/literal/while.txt | 6 ------ test/yarp/snapshots/unparser/corpus/semantic/while.txt | 1 - test/yarp/snapshots/while.txt | 1 - test/yarp/snapshots/whitequark/class.txt | 2 -- .../whitequark/class_definition_in_while_cond.txt | 2 -- test/yarp/snapshots/whitequark/class_super.txt | 1 - test/yarp/snapshots/whitequark/class_super_label.txt | 1 - test/yarp/snapshots/whitequark/cpath.txt | 2 -- .../whitequark/if_while_after_class__since_32.txt | 4 ---- test/yarp/snapshots/whitequark/module.txt | 1 - .../snapshots/whitequark/numparam_outside_block.txt | 2 -- test/yarp/snapshots/whitequark/parser_bug_490.txt | 2 -- test/yarp/snapshots/whitequark/parser_bug_518.txt | 1 - yarp/config.yml | 4 ---- yarp/yarp.c | 8 ++------ 30 files changed, 5 insertions(+), 89 deletions(-) diff --git a/test/yarp/errors_test.rb b/test/yarp/errors_test.rb index 6c03960ec3ed3e..5c714c26ba466f 100644 --- a/test/yarp/errors_test.rb +++ b/test/yarp/errors_test.rb @@ -19,10 +19,9 @@ def test_module_name_recoverable Location(), ConstantReadNode(:Parent), StatementsNode( - [ModuleNode([], Location(), MissingNode(), nil, Location(), :"", :"")] + [ModuleNode([], Location(), MissingNode(), nil, Location(), :"")] ), Location(), - :Parent, :Parent ) @@ -394,7 +393,7 @@ def test_module_definition_in_method_body Location(), nil, nil, - StatementsNode([ModuleNode([], Location(), ConstantReadNode(:A), nil, Location(), :A, :A)]), + StatementsNode([ModuleNode([], Location(), ConstantReadNode(:A), nil, Location(), :A)]), [], Location(), nil, @@ -425,7 +424,7 @@ def test_module_definition_in_method_body_within_block BlockNode( [], nil, - StatementsNode([ModuleNode([], Location(), ConstantReadNode(:Foo), nil, Location(), :Foo, :Foo)]), + StatementsNode([ModuleNode([], Location(), ConstantReadNode(:Foo), nil, Location(), :Foo)]), Location(), Location() ), @@ -465,7 +464,6 @@ def test_class_definition_in_method_body nil, nil, Location(), - :A, :A )] ), @@ -981,7 +979,6 @@ def test_dont_allow_return_inside_class_body nil, StatementsNode([ReturnNode(Location(), nil)]), Location(), - :A, :A ) @@ -997,7 +994,6 @@ def test_dont_allow_return_inside_module_body ConstantReadNode(:A), StatementsNode([ReturnNode(Location(), nil)]), Location(), - :A, :A ) diff --git a/test/yarp/snapshots/classes.txt b/test/yarp/snapshots/classes.txt index 43c0d24ab9817b..0679fe957fb3a8 100644 --- a/test/yarp/snapshots/classes.txt +++ b/test/yarp/snapshots/classes.txt @@ -17,7 +17,6 @@ ProgramNode(0...370)( )] ), (14...17), - :A, :A ), ClassNode(19...39)( @@ -35,7 +34,6 @@ ProgramNode(0...370)( (36...39) ), (36...39), - :A, :A ), ClassNode(41...75)( @@ -53,7 +51,6 @@ ProgramNode(0...370)( (72...75) ), (72...75), - :A, :A ), ClassNode(77...98)( @@ -72,7 +69,6 @@ ProgramNode(0...370)( )] ), (95...98), - :A, :A ), SingletonClassNode(100...120)( @@ -127,7 +123,6 @@ ProgramNode(0...370)( )] ), (159...162), - :A, :A ), ClassNode(164...218)( @@ -154,7 +149,6 @@ ProgramNode(0...370)( )] ), (215...218), - :A, :A ), SingletonClassNode(220...240)( @@ -287,7 +281,6 @@ ProgramNode(0...370)( ), nil, (367...370), - :A, :A )] ) diff --git a/test/yarp/snapshots/method_calls.txt b/test/yarp/snapshots/method_calls.txt index f320ab86feed20..6cec125ec12abb 100644 --- a/test/yarp/snapshots/method_calls.txt +++ b/test/yarp/snapshots/method_calls.txt @@ -1192,7 +1192,6 @@ ProgramNode(0...1237)( )] ), (926...929), - :Bar, :Bar )] ), @@ -1225,7 +1224,6 @@ ProgramNode(0...1237)( )] ), (957...960), - :Bar, :Bar )] ), diff --git a/test/yarp/snapshots/modules.txt b/test/yarp/snapshots/modules.txt index 306e7db3e34c30..741c3c842092cb 100644 --- a/test/yarp/snapshots/modules.txt +++ b/test/yarp/snapshots/modules.txt @@ -15,7 +15,6 @@ ProgramNode(0...140)( )] ), (15...18), - :A, :A ), InterpolatedStringNode(20...38)( @@ -51,7 +50,6 @@ ProgramNode(0...140)( ), nil, (52...55), - :M, :M ), ModuleNode(57...85)( @@ -75,7 +73,6 @@ ProgramNode(0...140)( (82...85) ), (82...85), - :A, :A ), ModuleNode(87...101)( @@ -88,7 +85,6 @@ ProgramNode(0...140)( ), nil, (98...101), - :A, :A ), ModuleNode(103...120)( @@ -111,7 +107,6 @@ ProgramNode(0...140)( ), nil, (117...120), - :B, :B ), ModuleNode(122...140)( @@ -134,7 +129,6 @@ ProgramNode(0...140)( ), nil, (137...140), - :B, :B )] ) diff --git a/test/yarp/snapshots/seattlerb/TestRubyParserShared.txt b/test/yarp/snapshots/seattlerb/TestRubyParserShared.txt index 6ae8ed6d031f7d..d839450b2cb5d0 100644 --- a/test/yarp/snapshots/seattlerb/TestRubyParserShared.txt +++ b/test/yarp/snapshots/seattlerb/TestRubyParserShared.txt @@ -87,7 +87,6 @@ ProgramNode(0...689)( )] ), (266...269), - :X, :X ), ClassNode(293...376)( @@ -112,12 +111,10 @@ ProgramNode(0...689)( )] ), (355...358), - :Y, :Y )] ), (373...376), - :X, :X ), ClassNode(395...498)( @@ -165,7 +162,6 @@ ProgramNode(0...689)( )] ), (495...498), - :X, :X ), ModuleNode(517...565)( @@ -186,7 +182,6 @@ ProgramNode(0...689)( )] ), (562...565), - :X, :X ), ModuleNode(568...651)( @@ -207,12 +202,10 @@ ProgramNode(0...689)( )] ), (630...633), - :Y, :Y )] ), (648...651), - :X, :X ), CallNode(670...689)( diff --git a/test/yarp/snapshots/seattlerb/class_comments.txt b/test/yarp/snapshots/seattlerb/class_comments.txt index 905c5914a2f19b..85d9d91067cec5 100644 --- a/test/yarp/snapshots/seattlerb/class_comments.txt +++ b/test/yarp/snapshots/seattlerb/class_comments.txt @@ -23,7 +23,6 @@ ProgramNode(19...71)( )] ), (68...71), - :X, :X )] ) diff --git a/test/yarp/snapshots/seattlerb/defn_oneliner_eq2.txt b/test/yarp/snapshots/seattlerb/defn_oneliner_eq2.txt index bbbdc17368d7b9..b2d59818591f7e 100644 --- a/test/yarp/snapshots/seattlerb/defn_oneliner_eq2.txt +++ b/test/yarp/snapshots/seattlerb/defn_oneliner_eq2.txt @@ -31,7 +31,6 @@ ProgramNode(0...28)( )] ), (25...28), - :X, :X )] ) diff --git a/test/yarp/snapshots/seattlerb/defs_oneliner_eq2.txt b/test/yarp/snapshots/seattlerb/defs_oneliner_eq2.txt index 1a88fffa507e10..cebb94c32f412d 100644 --- a/test/yarp/snapshots/seattlerb/defs_oneliner_eq2.txt +++ b/test/yarp/snapshots/seattlerb/defs_oneliner_eq2.txt @@ -31,7 +31,6 @@ ProgramNode(0...33)( )] ), (30...33), - :X, :X )] ) diff --git a/test/yarp/snapshots/seattlerb/magic_encoding_comment.txt b/test/yarp/snapshots/seattlerb/magic_encoding_comment.txt index 77efd6f4160317..2baa7bab0b323f 100644 --- a/test/yarp/snapshots/seattlerb/magic_encoding_comment.txt +++ b/test/yarp/snapshots/seattlerb/magic_encoding_comment.txt @@ -31,7 +31,6 @@ ProgramNode(18...90)( )] ), (87...90), - :ExampleUTF8ClassNameVarietà, :ExampleUTF8ClassNameVarietà )] ) diff --git a/test/yarp/snapshots/seattlerb/module_comments.txt b/test/yarp/snapshots/seattlerb/module_comments.txt index 152697f4022a1d..0a818d3116ae69 100644 --- a/test/yarp/snapshots/seattlerb/module_comments.txt +++ b/test/yarp/snapshots/seattlerb/module_comments.txt @@ -21,7 +21,6 @@ ProgramNode(24...77)( )] ), (74...77), - :X, :X )] ) diff --git a/test/yarp/snapshots/seattlerb/parse_line_heredoc_hardnewline.txt b/test/yarp/snapshots/seattlerb/parse_line_heredoc_hardnewline.txt index 623eb3aabf840b..4d1925d56a890f 100644 --- a/test/yarp/snapshots/seattlerb/parse_line_heredoc_hardnewline.txt +++ b/test/yarp/snapshots/seattlerb/parse_line_heredoc_hardnewline.txt @@ -19,7 +19,6 @@ ProgramNode(0...48)( nil, nil, (45...48), - :Foo, :Foo )] ) diff --git a/test/yarp/snapshots/unparser/corpus/literal/class.txt b/test/yarp/snapshots/unparser/corpus/literal/class.txt index cb49848ae35d70..4d8b7056232891 100644 --- a/test/yarp/snapshots/unparser/corpus/literal/class.txt +++ b/test/yarp/snapshots/unparser/corpus/literal/class.txt @@ -9,7 +9,6 @@ ProgramNode(0...213)( nil, nil, (8...11), - :A, :A ), SingletonClassNode(13...27)( @@ -42,7 +41,6 @@ ProgramNode(0...213)( nil, nil, (60...63), - :B, :B ), ClassNode(65...82)( @@ -61,7 +59,6 @@ ProgramNode(0...213)( nil, nil, (79...82), - :C, :C ), ClassNode(84...99)( @@ -72,7 +69,6 @@ ProgramNode(0...213)( ConstantReadNode(94...95)(:B), nil, (96...99), - :A, :A ), ClassNode(101...119)( @@ -87,7 +83,6 @@ ProgramNode(0...213)( ), nil, (116...119), - :A, :A ), ClassNode(121...142)( @@ -106,7 +101,6 @@ ProgramNode(0...213)( ), nil, (139...142), - :B, :B ), ClassNode(144...198)( @@ -156,7 +150,6 @@ ProgramNode(0...213)( )] ), (195...198), - :A, :A ), ClassNode(200...213)( @@ -171,7 +164,6 @@ ProgramNode(0...213)( nil, nil, (210...213), - :A, :A )] ) diff --git a/test/yarp/snapshots/unparser/corpus/literal/if.txt b/test/yarp/snapshots/unparser/corpus/literal/if.txt index 455db66af842f4..610dac8d92a5b1 100644 --- a/test/yarp/snapshots/unparser/corpus/literal/if.txt +++ b/test/yarp/snapshots/unparser/corpus/literal/if.txt @@ -81,7 +81,6 @@ ProgramNode(0...246)( )] ), (130...133), - :A, :A ), ModuleNode(135...170)( @@ -116,7 +115,6 @@ ProgramNode(0...246)( )] ), (167...170), - :B, :B ), UnlessNode(171...197)( diff --git a/test/yarp/snapshots/unparser/corpus/literal/module.txt b/test/yarp/snapshots/unparser/corpus/literal/module.txt index 28de3bfa3bc00d..e9b4470d6f02d3 100644 --- a/test/yarp/snapshots/unparser/corpus/literal/module.txt +++ b/test/yarp/snapshots/unparser/corpus/literal/module.txt @@ -7,7 +7,6 @@ ProgramNode(0...106)( ConstantReadNode(7...8)(:A), nil, (9...12), - :A, :A ), ModuleNode(14...29)( @@ -20,7 +19,6 @@ ProgramNode(0...106)( ), nil, (26...29), - :B, :B ), ModuleNode(31...49)( @@ -37,7 +35,6 @@ ProgramNode(0...106)( ), nil, (46...49), - :C, :C ), ModuleNode(51...106)( @@ -85,7 +82,6 @@ ProgramNode(0...106)( )] ), (103...106), - :A, :A )] ) diff --git a/test/yarp/snapshots/unparser/corpus/literal/send.txt b/test/yarp/snapshots/unparser/corpus/literal/send.txt index fccb137c0932b0..cc3f23beedbe06 100644 --- a/test/yarp/snapshots/unparser/corpus/literal/send.txt +++ b/test/yarp/snapshots/unparser/corpus/literal/send.txt @@ -38,7 +38,6 @@ ProgramNode(0...999)( )] ), (32...35), - :A, :A ), ModuleNode(37...73)( @@ -66,7 +65,6 @@ ProgramNode(0...999)( )] ), (70...73), - :A, :A ), CallNode(74...89)( @@ -78,7 +76,6 @@ ProgramNode(0...999)( nil, nil, (82...85), - :A, :A ), (85...86), @@ -97,7 +94,6 @@ ProgramNode(0...999)( ConstantReadNode(97...98)(:A), nil, (99...102), - :A, :A ), (102...103), diff --git a/test/yarp/snapshots/unparser/corpus/literal/while.txt b/test/yarp/snapshots/unparser/corpus/literal/while.txt index 4d924f0d3df9fa..6d90f455398891 100644 --- a/test/yarp/snapshots/unparser/corpus/literal/while.txt +++ b/test/yarp/snapshots/unparser/corpus/literal/while.txt @@ -64,7 +64,6 @@ ProgramNode(0...620)( )] ), (65...68), - :A, :A ), DefNode(70...110)( @@ -160,7 +159,6 @@ ProgramNode(0...620)( )] ), (143...146), - :A, :A ), ModuleNode(148...182)( @@ -195,7 +193,6 @@ ProgramNode(0...620)( )] ), (179...182), - :A, :A ), ModuleNode(184...228)( @@ -240,7 +237,6 @@ ProgramNode(0...620)( )] ), (225...228), - :A, :A ), ModuleNode(230...299)( @@ -316,7 +312,6 @@ ProgramNode(0...620)( )] ), (296...299), - :A, :A ), ModuleNode(301...370)( @@ -382,7 +377,6 @@ ProgramNode(0...620)( )] ), (367...370), - :A, :A ), LocalVariableWriteNode(371...402)( diff --git a/test/yarp/snapshots/unparser/corpus/semantic/while.txt b/test/yarp/snapshots/unparser/corpus/semantic/while.txt index 3e6ef668a1cfc0..6b29da7e48bf45 100644 --- a/test/yarp/snapshots/unparser/corpus/semantic/while.txt +++ b/test/yarp/snapshots/unparser/corpus/semantic/while.txt @@ -186,7 +186,6 @@ ProgramNode(0...188)( )] ), (185...188), - :A, :A )] ) diff --git a/test/yarp/snapshots/while.txt b/test/yarp/snapshots/while.txt index 843db1e147fb2b..aeb0fc9b0dde7a 100644 --- a/test/yarp/snapshots/while.txt +++ b/test/yarp/snapshots/while.txt @@ -139,7 +139,6 @@ ProgramNode(0...314)( )] ), (195...198), - :Foo, :Foo ), StatementsNode(200...205)([BreakNode(200...205)(nil, (200...205))]), diff --git a/test/yarp/snapshots/whitequark/class.txt b/test/yarp/snapshots/whitequark/class.txt index 84ab3a72ef0ace..692e70859d2cbf 100644 --- a/test/yarp/snapshots/whitequark/class.txt +++ b/test/yarp/snapshots/whitequark/class.txt @@ -9,7 +9,6 @@ ProgramNode(0...29)( nil, nil, (10...13), - :Foo, :Foo ), ClassNode(15...29)( @@ -20,7 +19,6 @@ ProgramNode(0...29)( nil, nil, (26...29), - :Foo, :Foo )] ) diff --git a/test/yarp/snapshots/whitequark/class_definition_in_while_cond.txt b/test/yarp/snapshots/whitequark/class_definition_in_while_cond.txt index cec17515f12d46..8fbb656c2c6950 100644 --- a/test/yarp/snapshots/whitequark/class_definition_in_while_cond.txt +++ b/test/yarp/snapshots/whitequark/class_definition_in_while_cond.txt @@ -88,7 +88,6 @@ ProgramNode(0...197)( )] ), (136...139), - :Foo, :Foo ), StatementsNode(141...146)([BreakNode(141...146)(nil, (141...146))]), @@ -117,7 +116,6 @@ ProgramNode(0...197)( )] ), (182...185), - :Foo, :Foo ), StatementsNode(187...192)([BreakNode(187...192)(nil, (187...192))]), diff --git a/test/yarp/snapshots/whitequark/class_super.txt b/test/yarp/snapshots/whitequark/class_super.txt index ec400beb09de74..a2458fe128410a 100644 --- a/test/yarp/snapshots/whitequark/class_super.txt +++ b/test/yarp/snapshots/whitequark/class_super.txt @@ -9,7 +9,6 @@ ProgramNode(0...20)( ConstantReadNode(12...15)(:Bar), nil, (17...20), - :Foo, :Foo )] ) diff --git a/test/yarp/snapshots/whitequark/class_super_label.txt b/test/yarp/snapshots/whitequark/class_super_label.txt index 8ebba419a27333..ab6bf568d82150 100644 --- a/test/yarp/snapshots/whitequark/class_super_label.txt +++ b/test/yarp/snapshots/whitequark/class_super_label.txt @@ -21,7 +21,6 @@ ProgramNode(0...20)( ), nil, (17...20), - :Foo, :Foo )] ) diff --git a/test/yarp/snapshots/whitequark/cpath.txt b/test/yarp/snapshots/whitequark/cpath.txt index b557da7e7fc522..7e3f62ee17b87a 100644 --- a/test/yarp/snapshots/whitequark/cpath.txt +++ b/test/yarp/snapshots/whitequark/cpath.txt @@ -7,7 +7,6 @@ ProgramNode(0...39)( ConstantPathNode(7...12)(nil, ConstantReadNode(9...12)(:Foo), (7...9)), nil, (14...17), - :Foo, :Foo ), ModuleNode(19...39)( @@ -20,7 +19,6 @@ ProgramNode(0...39)( ), nil, (36...39), - :Foo, :Foo )] ) diff --git a/test/yarp/snapshots/whitequark/if_while_after_class__since_32.txt b/test/yarp/snapshots/whitequark/if_while_after_class__since_32.txt index c18c1b4e9a4a9e..f2ba2a124538bc 100644 --- a/test/yarp/snapshots/whitequark/if_while_after_class__since_32.txt +++ b/test/yarp/snapshots/whitequark/if_while_after_class__since_32.txt @@ -19,7 +19,6 @@ ProgramNode(0...178)( nil, nil, (35...38), - :Kernel, :Kernel ), ClassNode(40...87)( @@ -45,7 +44,6 @@ ProgramNode(0...178)( nil, nil, (84...87), - :Kernel, :Kernel ), ModuleNode(89...128)( @@ -64,7 +62,6 @@ ProgramNode(0...178)( ), nil, (125...128), - :Kernel, :Kernel ), ModuleNode(130...178)( @@ -90,7 +87,6 @@ ProgramNode(0...178)( ), nil, (175...178), - :Kernel, :Kernel )] ) diff --git a/test/yarp/snapshots/whitequark/module.txt b/test/yarp/snapshots/whitequark/module.txt index 7880ab9980ac22..18d3d2e9b55e00 100644 --- a/test/yarp/snapshots/whitequark/module.txt +++ b/test/yarp/snapshots/whitequark/module.txt @@ -7,7 +7,6 @@ ProgramNode(0...15)( ConstantReadNode(7...10)(:Foo), nil, (12...15), - :Foo, :Foo )] ) diff --git a/test/yarp/snapshots/whitequark/numparam_outside_block.txt b/test/yarp/snapshots/whitequark/numparam_outside_block.txt index 61d138fa6d5a89..5b41378aa7438c 100644 --- a/test/yarp/snapshots/whitequark/numparam_outside_block.txt +++ b/test/yarp/snapshots/whitequark/numparam_outside_block.txt @@ -22,7 +22,6 @@ ProgramNode(0...83)( [CallNode(36...38)(nil, nil, (36...38), nil, nil, nil, nil, 2, "_1")] ), (40...43), - :A, :A ), DefNode(45...64)( @@ -48,7 +47,6 @@ ProgramNode(0...83)( [CallNode(76...78)(nil, nil, (76...78), nil, nil, nil, nil, 2, "_1")] ), (80...83), - :A, :A )] ) diff --git a/test/yarp/snapshots/whitequark/parser_bug_490.txt b/test/yarp/snapshots/whitequark/parser_bug_490.txt index b3b5b04a4a4baf..a82c7d1bb79059 100644 --- a/test/yarp/snapshots/whitequark/parser_bug_490.txt +++ b/test/yarp/snapshots/whitequark/parser_bug_490.txt @@ -49,7 +49,6 @@ ProgramNode(0...132)( nil, nil, (72...75), - :C, :C )] ), @@ -81,7 +80,6 @@ ProgramNode(0...132)( ConstantReadNode(116...117)(:M), nil, (119...122), - :M, :M )] ), diff --git a/test/yarp/snapshots/whitequark/parser_bug_518.txt b/test/yarp/snapshots/whitequark/parser_bug_518.txt index fc53bcb5274727..1f2cca8d1ddff2 100644 --- a/test/yarp/snapshots/whitequark/parser_bug_518.txt +++ b/test/yarp/snapshots/whitequark/parser_bug_518.txt @@ -9,7 +9,6 @@ ProgramNode(0...15)( ConstantReadNode(10...11)(:B), nil, (12...15), - :A, :A )] ) diff --git a/yarp/config.yml b/yarp/config.yml index 5ccdabab16cda9..4207e09a0c062d 100644 --- a/yarp/config.yml +++ b/yarp/config.yml @@ -782,8 +782,6 @@ nodes: type: location - name: name type: constant - - name: name_constant - type: constant comment: | Represents a class declaration involving the `class` keyword. @@ -1742,8 +1740,6 @@ nodes: type: location - name: name type: constant - - name: name_constant - type: constant comment: | Represents a module declaration involving the `module` keyword. diff --git a/yarp/yarp.c b/yarp/yarp.c index 2bce80abade61f..17ef80c4725e77 100644 --- a/yarp/yarp.c +++ b/yarp/yarp.c @@ -1655,7 +1655,6 @@ yp_case_node_end_keyword_loc_set(yp_case_node_t *node, const yp_token_t *end_key static yp_class_node_t * yp_class_node_create(yp_parser_t *parser, yp_constant_id_list_t *locals, const yp_token_t *class_keyword, yp_node_t *constant_path, const yp_token_t *name, const yp_token_t *inheritance_operator, yp_node_t *superclass, yp_node_t *body, const yp_token_t *end_keyword) { yp_class_node_t *node = YP_ALLOC_NODE(parser, yp_class_node_t); - yp_constant_id_t name_constant = yp_parser_constant_id_token(parser, name); *node = (yp_class_node_t) { { @@ -1669,8 +1668,7 @@ yp_class_node_create(yp_parser_t *parser, yp_constant_id_list_t *locals, const y .superclass = superclass, .body = body, .end_keyword_loc = YP_LOCATION_TOKEN_VALUE(end_keyword), - .name = name_constant, - .name_constant = name_constant + .name = yp_parser_constant_id_token(parser, name) }; return node; @@ -3305,7 +3303,6 @@ yp_match_required_node_create(yp_parser_t *parser, yp_node_t *value, yp_node_t * static yp_module_node_t * yp_module_node_create(yp_parser_t *parser, yp_constant_id_list_t *locals, const yp_token_t *module_keyword, yp_node_t *constant_path, const yp_token_t *name, yp_node_t *body, const yp_token_t *end_keyword) { yp_module_node_t *node = YP_ALLOC_NODE(parser, yp_module_node_t); - yp_constant_id_t name_constant = yp_parser_constant_id_token(parser, name); *node = (yp_module_node_t) { { @@ -3320,8 +3317,7 @@ yp_module_node_create(yp_parser_t *parser, yp_constant_id_list_t *locals, const .constant_path = constant_path, .body = body, .end_keyword_loc = YP_LOCATION_TOKEN_VALUE(end_keyword), - .name = name_constant, - .name_constant = name_constant + .name = yp_parser_constant_id_token(parser, name) }; return node; From 9e21b33ece212b67d62cf47527a1d9e0251c9fdd Mon Sep 17 00:00:00 2001 From: Kevin Newton Date: Wed, 6 Sep 2023 11:06:26 -0400 Subject: [PATCH 11/46] [ruby/yarp] Constants on keyword parameters https://github.com/ruby/yarp/commit/d2d4f25a23 --- lib/yarp.rb | 4 ++-- test/yarp/errors_test.rb | 10 +++++----- test/yarp/snapshots/blocks.txt | 4 +++- test/yarp/snapshots/lambda.txt | 3 +++ test/yarp/snapshots/methods.txt | 16 +++++++++++----- test/yarp/snapshots/procs.txt | 12 ++++++------ test/yarp/snapshots/seattlerb/args_kw_block.txt | 2 +- test/yarp/snapshots/seattlerb/block_kw.txt | 6 +++++- .../snapshots/seattlerb/block_kw__required.txt | 2 +- .../snapshots/seattlerb/block_kwarg_lvar.txt | 1 + .../seattlerb/block_kwarg_lvar_multiple.txt | 2 ++ .../snapshots/seattlerb/defn_kwarg_kwarg.txt | 8 ++++++-- .../snapshots/seattlerb/defn_kwarg_kwsplat.txt | 2 +- .../seattlerb/defn_kwarg_kwsplat_anon.txt | 2 +- .../yarp/snapshots/seattlerb/defn_kwarg_lvar.txt | 1 + .../snapshots/seattlerb/defn_kwarg_no_parens.txt | 2 +- test/yarp/snapshots/seattlerb/defn_kwarg_val.txt | 2 +- test/yarp/snapshots/seattlerb/defs_kwarg.txt | 6 +++++- test/yarp/snapshots/seattlerb/f_kw.txt | 2 +- test/yarp/snapshots/seattlerb/f_kw__required.txt | 2 +- test/yarp/snapshots/seattlerb/iter_kwarg.txt | 2 +- .../snapshots/seattlerb/iter_kwarg_kwsplat.txt | 2 +- .../seattlerb/required_kwarg_no_value.txt | 4 ++-- .../yarp/snapshots/seattlerb/stabby_block_kw.txt | 2 +- .../seattlerb/stabby_block_kw__required.txt | 2 +- .../snapshots/unparser/corpus/literal/def.txt | 10 +++++++--- test/yarp/snapshots/whitequark/args.txt | 6 +++++- test/yarp/snapshots/whitequark/blockargs.txt | 5 ++++- test/yarp/snapshots/whitequark/kwarg.txt | 2 +- test/yarp/snapshots/whitequark/kwoptarg.txt | 6 +++++- ...woptarg_with_kwrestarg_and_forwarded_args.txt | 2 +- .../yarp/snapshots/whitequark/ruby_bug_15789.txt | 1 + test/yarp/snapshots/whitequark/ruby_bug_9669.txt | 2 +- .../whitequark/send_lambda_args_noparen.txt | 4 ++-- yarp/config.yml | 2 ++ yarp/yarp.c | 1 + 36 files changed, 94 insertions(+), 48 deletions(-) diff --git a/lib/yarp.rb b/lib/yarp.rb index 769b149bcabf55..c445a31d32dacf 100644 --- a/lib/yarp.rb +++ b/lib/yarp.rb @@ -542,8 +542,8 @@ def self.yarp_locals(source) *params.optionals.map(&:name), *((params.rest.name ? params.rest.name.to_sym : :*) if params.rest && params.rest.operator != ","), *params.posts.grep(RequiredParameterNode).map(&:name), - *params.keywords.reject(&:value).map { |param| param.name.chomp(":").to_sym }, - *params.keywords.select(&:value).map { |param| param.name.chomp(":").to_sym } + *params.keywords.reject(&:value).map(&:name), + *params.keywords.select(&:value).map(&:name) ] # TODO: When we get a ... parameter, we should be pushing * and & diff --git a/test/yarp/errors_test.rb b/test/yarp/errors_test.rb index 5c714c26ba466f..d4f46440b5d6e9 100644 --- a/test/yarp/errors_test.rb +++ b/test/yarp/errors_test.rb @@ -714,7 +714,7 @@ def test_keywords_parameters_before_required_parameters [], [RequiredParameterNode(:a)], nil, - [KeywordParameterNode(Location(), nil)], + [KeywordParameterNode(:b, Location(), nil)], nil, nil ), @@ -741,7 +741,7 @@ def test_rest_keywords_parameters_before_required_parameters [], [], nil, - [KeywordParameterNode(Location(), nil)], + [KeywordParameterNode(:b, Location(), nil)], KeywordRestParameterNode(Location(), Location()), nil ), @@ -788,7 +788,7 @@ def test_multiple_error_in_parameters_order [], [RequiredParameterNode(:a)], nil, - [KeywordParameterNode(Location(), nil)], + [KeywordParameterNode(:b, Location(), nil)], KeywordRestParameterNode(Location(), Location()), nil ), @@ -817,7 +817,7 @@ def test_switching_to_optional_arguments_twice [], [RequiredParameterNode(:a)], nil, - [KeywordParameterNode(Location(), nil)], + [KeywordParameterNode(:b, Location(), nil)], KeywordRestParameterNode(Location(), Location()), nil ), @@ -846,7 +846,7 @@ def test_switching_to_named_arguments_twice [], [RequiredParameterNode(:a)], nil, - [KeywordParameterNode(Location(), nil)], + [KeywordParameterNode(:b, Location(), nil)], KeywordRestParameterNode(Location(), Location()), nil ), diff --git a/test/yarp/snapshots/blocks.txt b/test/yarp/snapshots/blocks.txt index 4a2c3f7585eeff..54a8d6f743f927 100644 --- a/test/yarp/snapshots/blocks.txt +++ b/test/yarp/snapshots/blocks.txt @@ -405,7 +405,7 @@ ProgramNode(0...402)( )], [], nil, - [KeywordParameterNode(270...272)((270...272), nil)], + [KeywordParameterNode(270...272)(:z, (270...272), nil)], nil, nil ), @@ -561,10 +561,12 @@ ProgramNode(0...402)( [], nil, [KeywordParameterNode(365...369)( + :a, (365...367), IntegerNode(368...369)() ), KeywordParameterNode(373...377)( + :b, (373...375), IntegerNode(376...377)() )], diff --git a/test/yarp/snapshots/lambda.txt b/test/yarp/snapshots/lambda.txt index 6640b585c32140..01846d7c147d46 100644 --- a/test/yarp/snapshots/lambda.txt +++ b/test/yarp/snapshots/lambda.txt @@ -34,6 +34,7 @@ ProgramNode(0...92)( [], nil, [KeywordParameterNode(19...29)( + :x, (19...21), InterpolatedStringNode(22...29)( (22...23), @@ -79,6 +80,7 @@ ProgramNode(0...92)( [], nil, [KeywordParameterNode(39...47)( + :a, (39...41), CallNode(42...47)( CallNode(42...43)( @@ -159,6 +161,7 @@ ProgramNode(0...92)( [], nil, [KeywordParameterNode(77...85)( + :foo, (77...81), CallNode(82...85)( nil, diff --git a/test/yarp/snapshots/methods.txt b/test/yarp/snapshots/methods.txt index 13a81d15cda623..390522bae4d54c 100644 --- a/test/yarp/snapshots/methods.txt +++ b/test/yarp/snapshots/methods.txt @@ -218,7 +218,7 @@ ProgramNode(0...1194)( [], [], nil, - [KeywordParameterNode(212...214)((212...214), nil)], + [KeywordParameterNode(212...214)(:b, (212...214), nil)], nil, nil ), @@ -240,7 +240,7 @@ ProgramNode(0...1194)( [], [], nil, - [KeywordParameterNode(235...237)((235...237), nil)], + [KeywordParameterNode(235...237)(:b, (235...237), nil)], nil, nil ), @@ -359,8 +359,9 @@ ProgramNode(0...1194)( [], [], nil, - [KeywordParameterNode(333...335)((333...335), nil), + [KeywordParameterNode(333...335)(:b, (333...335), nil), KeywordParameterNode(337...341)( + :c, (337...339), IntegerNode(340...341)() )], @@ -384,8 +385,9 @@ ProgramNode(0...1194)( [], [], nil, - [KeywordParameterNode(353...355)((353...355), nil), + [KeywordParameterNode(353...355)(:b, (353...355), nil), KeywordParameterNode(357...361)( + :c, (357...359), IntegerNode(360...361)() )], @@ -410,10 +412,11 @@ ProgramNode(0...1194)( [], nil, [KeywordParameterNode(374...380)( + :b, (374...376), IntegerNode(379...380)() ), - KeywordParameterNode(382...384)((382...384), nil)], + KeywordParameterNode(382...384)(:c, (382...384), nil)], nil, nil ), @@ -1111,6 +1114,7 @@ ProgramNode(0...1194)( [], nil, [KeywordParameterNode(990...1001)( + :a, (990...992), ParenthesesNode(993...1001)( StatementsNode(994...1000)( @@ -1146,6 +1150,7 @@ ProgramNode(0...1194)( [], nil, [KeywordParameterNode(1016...1026)( + :a, (1016...1018), ParenthesesNode(1019...1026)( StatementsNode(1020...1025)( @@ -1181,6 +1186,7 @@ ProgramNode(0...1194)( [], nil, [KeywordParameterNode(1041...1050)( + :a, (1041...1043), ParenthesesNode(1044...1050)( StatementsNode(1045...1049)( diff --git a/test/yarp/snapshots/procs.txt b/test/yarp/snapshots/procs.txt index 64ad900220fa5f..e825afd8e4642e 100644 --- a/test/yarp/snapshots/procs.txt +++ b/test/yarp/snapshots/procs.txt @@ -90,8 +90,8 @@ ProgramNode(0...266)( )], [], nil, - [KeywordParameterNode(113...115)((113...115), nil), - KeywordParameterNode(117...119)((117...119), nil)], + [KeywordParameterNode(113...115)(:c, (113...115), nil), + KeywordParameterNode(117...119)(:d, (117...119), nil)], nil, BlockParameterNode(121...123)(:e, (122...123), (121...122)) ), @@ -117,8 +117,8 @@ ProgramNode(0...266)( )], [], RestParameterNode(145...147)((145...146), (146...147)), - [KeywordParameterNode(149...151)((149...151), nil), - KeywordParameterNode(153...155)((153...155), nil)], + [KeywordParameterNode(149...151)(:d, (149...151), nil), + KeywordParameterNode(153...155)(:e, (153...155), nil)], KeywordRestParameterNode(157...160)((157...159), (159...160)), BlockParameterNode(162...164)(:g, (163...164), (162...163)) ), @@ -144,8 +144,8 @@ ProgramNode(0...266)( )], [], RestParameterNode(187...189)((187...188), (188...189)), - [KeywordParameterNode(191...193)((191...193), nil), - KeywordParameterNode(195...197)((195...197), nil)], + [KeywordParameterNode(191...193)(:d, (191...193), nil), + KeywordParameterNode(195...197)(:e, (195...197), nil)], KeywordRestParameterNode(199...202)((199...201), (201...202)), BlockParameterNode(204...206)(:g, (205...206), (204...205)) ), diff --git a/test/yarp/snapshots/seattlerb/args_kw_block.txt b/test/yarp/snapshots/seattlerb/args_kw_block.txt index c11a1590702c09..3ccb7472787ecb 100644 --- a/test/yarp/snapshots/seattlerb/args_kw_block.txt +++ b/test/yarp/snapshots/seattlerb/args_kw_block.txt @@ -9,7 +9,7 @@ ProgramNode(0...20)( [], [], nil, - [KeywordParameterNode(6...10)((6...8), IntegerNode(9...10)())], + [KeywordParameterNode(6...10)(:a, (6...8), IntegerNode(9...10)())], nil, BlockParameterNode(12...14)(:b, (13...14), (12...13)) ), diff --git a/test/yarp/snapshots/seattlerb/block_kw.txt b/test/yarp/snapshots/seattlerb/block_kw.txt index b8f61d8e30a84f..32a518dc394b1c 100644 --- a/test/yarp/snapshots/seattlerb/block_kw.txt +++ b/test/yarp/snapshots/seattlerb/block_kw.txt @@ -16,7 +16,11 @@ ProgramNode(0...15)( [], [], nil, - [KeywordParameterNode(8...12)((8...10), IntegerNode(10...12)())], + [KeywordParameterNode(8...12)( + :k, + (8...10), + IntegerNode(10...12)() + )], nil, nil ), diff --git a/test/yarp/snapshots/seattlerb/block_kw__required.txt b/test/yarp/snapshots/seattlerb/block_kw__required.txt index cb7b2912371f4e..be6125fa1d826f 100644 --- a/test/yarp/snapshots/seattlerb/block_kw__required.txt +++ b/test/yarp/snapshots/seattlerb/block_kw__required.txt @@ -16,7 +16,7 @@ ProgramNode(0...16)( [], [], nil, - [KeywordParameterNode(9...11)((9...11), nil)], + [KeywordParameterNode(9...11)(:k, (9...11), nil)], nil, nil ), diff --git a/test/yarp/snapshots/seattlerb/block_kwarg_lvar.txt b/test/yarp/snapshots/seattlerb/block_kwarg_lvar.txt index dd1df1b7ad87ee..eb215151086ec8 100644 --- a/test/yarp/snapshots/seattlerb/block_kwarg_lvar.txt +++ b/test/yarp/snapshots/seattlerb/block_kwarg_lvar.txt @@ -17,6 +17,7 @@ ProgramNode(0...20)( [], nil, [KeywordParameterNode(6...14)( + :kw, (6...9), SymbolNode(10...14)((10...11), (11...14), nil, "val") )], diff --git a/test/yarp/snapshots/seattlerb/block_kwarg_lvar_multiple.txt b/test/yarp/snapshots/seattlerb/block_kwarg_lvar_multiple.txt index ae561f5de395d4..240ece6f7066e4 100644 --- a/test/yarp/snapshots/seattlerb/block_kwarg_lvar_multiple.txt +++ b/test/yarp/snapshots/seattlerb/block_kwarg_lvar_multiple.txt @@ -17,10 +17,12 @@ ProgramNode(0...33)( [], nil, [KeywordParameterNode(6...14)( + :kw, (6...9), SymbolNode(10...14)((10...11), (11...14), nil, "val") ), KeywordParameterNode(16...26)( + :kw2, (16...20), SymbolNode(21...26)((21...22), (22...26), nil, "val2") )], diff --git a/test/yarp/snapshots/seattlerb/defn_kwarg_kwarg.txt b/test/yarp/snapshots/seattlerb/defn_kwarg_kwarg.txt index 6dcd4aaf2bd2f7..6a1abc0d205792 100644 --- a/test/yarp/snapshots/seattlerb/defn_kwarg_kwarg.txt +++ b/test/yarp/snapshots/seattlerb/defn_kwarg_kwarg.txt @@ -9,8 +9,12 @@ ProgramNode(0...24)( [], [], nil, - [KeywordParameterNode(9...13)((9...11), IntegerNode(12...13)()), - KeywordParameterNode(15...19)((15...17), IntegerNode(18...19)())], + [KeywordParameterNode(9...13)(:b, (9...11), IntegerNode(12...13)()), + KeywordParameterNode(15...19)( + :c, + (15...17), + IntegerNode(18...19)() + )], nil, nil ), diff --git a/test/yarp/snapshots/seattlerb/defn_kwarg_kwsplat.txt b/test/yarp/snapshots/seattlerb/defn_kwarg_kwsplat.txt index 5bc6490a6f62d1..bc4cb7d8a9faee 100644 --- a/test/yarp/snapshots/seattlerb/defn_kwarg_kwsplat.txt +++ b/test/yarp/snapshots/seattlerb/defn_kwarg_kwsplat.txt @@ -9,7 +9,7 @@ ProgramNode(0...20)( [], [], nil, - [KeywordParameterNode(6...10)((6...8), IntegerNode(9...10)())], + [KeywordParameterNode(6...10)(:b, (6...8), IntegerNode(9...10)())], KeywordRestParameterNode(12...15)((12...14), (14...15)), nil ), diff --git a/test/yarp/snapshots/seattlerb/defn_kwarg_kwsplat_anon.txt b/test/yarp/snapshots/seattlerb/defn_kwarg_kwsplat_anon.txt index 3dfb42f6d7525a..009b3f0fcaebac 100644 --- a/test/yarp/snapshots/seattlerb/defn_kwarg_kwsplat_anon.txt +++ b/test/yarp/snapshots/seattlerb/defn_kwarg_kwsplat_anon.txt @@ -9,7 +9,7 @@ ProgramNode(0...19)( [], [], nil, - [KeywordParameterNode(6...10)((6...8), IntegerNode(9...10)())], + [KeywordParameterNode(6...10)(:b, (6...8), IntegerNode(9...10)())], KeywordRestParameterNode(12...14)((12...14), nil), nil ), diff --git a/test/yarp/snapshots/seattlerb/defn_kwarg_lvar.txt b/test/yarp/snapshots/seattlerb/defn_kwarg_lvar.txt index f4f6964c58327a..e118d362a49f6c 100644 --- a/test/yarp/snapshots/seattlerb/defn_kwarg_lvar.txt +++ b/test/yarp/snapshots/seattlerb/defn_kwarg_lvar.txt @@ -10,6 +10,7 @@ ProgramNode(0...26)( [], nil, [KeywordParameterNode(8...16)( + :kw, (8...11), SymbolNode(12...16)((12...13), (13...16), nil, "val") )], diff --git a/test/yarp/snapshots/seattlerb/defn_kwarg_no_parens.txt b/test/yarp/snapshots/seattlerb/defn_kwarg_no_parens.txt index b0649973accb64..27982d5cb80179 100644 --- a/test/yarp/snapshots/seattlerb/defn_kwarg_no_parens.txt +++ b/test/yarp/snapshots/seattlerb/defn_kwarg_no_parens.txt @@ -9,7 +9,7 @@ ProgramNode(0...14)( [], [], nil, - [KeywordParameterNode(6...10)((6...8), IntegerNode(9...10)())], + [KeywordParameterNode(6...10)(:a, (6...8), IntegerNode(9...10)())], nil, nil ), diff --git a/test/yarp/snapshots/seattlerb/defn_kwarg_val.txt b/test/yarp/snapshots/seattlerb/defn_kwarg_val.txt index dfa99b70664770..2ae853d3f4b4a0 100644 --- a/test/yarp/snapshots/seattlerb/defn_kwarg_val.txt +++ b/test/yarp/snapshots/seattlerb/defn_kwarg_val.txt @@ -9,7 +9,7 @@ ProgramNode(0...17)( [], [], nil, - [KeywordParameterNode(9...12)((9...11), IntegerNode(11...12)())], + [KeywordParameterNode(9...12)(:b, (9...11), IntegerNode(11...12)())], nil, nil ), diff --git a/test/yarp/snapshots/seattlerb/defs_kwarg.txt b/test/yarp/snapshots/seattlerb/defs_kwarg.txt index 0309161b8e4fab..d7288bc1e05f03 100644 --- a/test/yarp/snapshots/seattlerb/defs_kwarg.txt +++ b/test/yarp/snapshots/seattlerb/defs_kwarg.txt @@ -9,7 +9,11 @@ ProgramNode(0...19)( [], [], nil, - [KeywordParameterNode(11...15)((11...13), IntegerNode(14...15)())], + [KeywordParameterNode(11...15)( + :b, + (11...13), + IntegerNode(14...15)() + )], nil, nil ), diff --git a/test/yarp/snapshots/seattlerb/f_kw.txt b/test/yarp/snapshots/seattlerb/f_kw.txt index ace0997f9e1378..420dab984dc1a8 100644 --- a/test/yarp/snapshots/seattlerb/f_kw.txt +++ b/test/yarp/snapshots/seattlerb/f_kw.txt @@ -9,7 +9,7 @@ ProgramNode(0...15)( [], [], nil, - [KeywordParameterNode(6...10)((6...8), IntegerNode(8...10)())], + [KeywordParameterNode(6...10)(:k, (6...8), IntegerNode(8...10)())], nil, nil ), diff --git a/test/yarp/snapshots/seattlerb/f_kw__required.txt b/test/yarp/snapshots/seattlerb/f_kw__required.txt index 38d564599ffc39..30cd82d52c6684 100644 --- a/test/yarp/snapshots/seattlerb/f_kw__required.txt +++ b/test/yarp/snapshots/seattlerb/f_kw__required.txt @@ -9,7 +9,7 @@ ProgramNode(0...13)( [], [], nil, - [KeywordParameterNode(6...8)((6...8), nil)], + [KeywordParameterNode(6...8)(:k, (6...8), nil)], nil, nil ), diff --git a/test/yarp/snapshots/seattlerb/iter_kwarg.txt b/test/yarp/snapshots/seattlerb/iter_kwarg.txt index a3984ee42f5047..4dfc24209a4140 100644 --- a/test/yarp/snapshots/seattlerb/iter_kwarg.txt +++ b/test/yarp/snapshots/seattlerb/iter_kwarg.txt @@ -16,7 +16,7 @@ ProgramNode(0...12)( [], [], nil, - [KeywordParameterNode(5...9)((5...7), IntegerNode(8...9)())], + [KeywordParameterNode(5...9)(:b, (5...7), IntegerNode(8...9)())], nil, nil ), diff --git a/test/yarp/snapshots/seattlerb/iter_kwarg_kwsplat.txt b/test/yarp/snapshots/seattlerb/iter_kwarg_kwsplat.txt index 39dce0cca39f15..b068be0913aa39 100644 --- a/test/yarp/snapshots/seattlerb/iter_kwarg_kwsplat.txt +++ b/test/yarp/snapshots/seattlerb/iter_kwarg_kwsplat.txt @@ -16,7 +16,7 @@ ProgramNode(0...17)( [], [], nil, - [KeywordParameterNode(5...9)((5...7), IntegerNode(8...9)())], + [KeywordParameterNode(5...9)(:b, (5...7), IntegerNode(8...9)())], KeywordRestParameterNode(11...14)((11...13), (13...14)), nil ), diff --git a/test/yarp/snapshots/seattlerb/required_kwarg_no_value.txt b/test/yarp/snapshots/seattlerb/required_kwarg_no_value.txt index 95cf0e279a730e..3f95094fef4353 100644 --- a/test/yarp/snapshots/seattlerb/required_kwarg_no_value.txt +++ b/test/yarp/snapshots/seattlerb/required_kwarg_no_value.txt @@ -9,8 +9,8 @@ ProgramNode(0...16)( [], [], nil, - [KeywordParameterNode(6...8)((6...8), nil), - KeywordParameterNode(10...12)((10...12), nil)], + [KeywordParameterNode(6...8)(:a, (6...8), nil), + KeywordParameterNode(10...12)(:b, (10...12), nil)], nil, nil ), diff --git a/test/yarp/snapshots/seattlerb/stabby_block_kw.txt b/test/yarp/snapshots/seattlerb/stabby_block_kw.txt index 8df95715c9f04e..ffb20333869f54 100644 --- a/test/yarp/snapshots/seattlerb/stabby_block_kw.txt +++ b/test/yarp/snapshots/seattlerb/stabby_block_kw.txt @@ -12,7 +12,7 @@ ProgramNode(0...13)( [], [], nil, - [KeywordParameterNode(4...8)((4...6), IntegerNode(6...8)())], + [KeywordParameterNode(4...8)(:k, (4...6), IntegerNode(6...8)())], nil, nil ), diff --git a/test/yarp/snapshots/seattlerb/stabby_block_kw__required.txt b/test/yarp/snapshots/seattlerb/stabby_block_kw__required.txt index 8d3e73af8b7766..3b1ba23e9d01c3 100644 --- a/test/yarp/snapshots/seattlerb/stabby_block_kw__required.txt +++ b/test/yarp/snapshots/seattlerb/stabby_block_kw__required.txt @@ -12,7 +12,7 @@ ProgramNode(0...11)( [], [], nil, - [KeywordParameterNode(4...6)((4...6), nil)], + [KeywordParameterNode(4...6)(:k, (4...6), nil)], nil, nil ), diff --git a/test/yarp/snapshots/unparser/corpus/literal/def.txt b/test/yarp/snapshots/unparser/corpus/literal/def.txt index f458483791f2a4..d4def391b701ef 100644 --- a/test/yarp/snapshots/unparser/corpus/literal/def.txt +++ b/test/yarp/snapshots/unparser/corpus/literal/def.txt @@ -179,8 +179,8 @@ ProgramNode(0...913)( [], [], nil, - [KeywordParameterNode(113...117)((113...117), nil), - KeywordParameterNode(119...123)((119...123), nil)], + [KeywordParameterNode(113...117)(:bar, (113...117), nil), + KeywordParameterNode(119...123)(:baz, (119...123), nil)], nil, nil ), @@ -570,6 +570,7 @@ ProgramNode(0...913)( [], nil, [KeywordParameterNode(459...465)( + :bar, (459...463), IntegerNode(464...465)() )], @@ -594,6 +595,7 @@ ProgramNode(0...913)( [], nil, [KeywordParameterNode(480...488)( + :bar, (480...484), CallNode(485...488)( nil, @@ -628,6 +630,7 @@ ProgramNode(0...913)( [], nil, [KeywordParameterNode(503...513)( + :bar, (503...507), CallNode(508...513)( nil, @@ -957,8 +960,9 @@ ProgramNode(0...913)( [], [], nil, - [KeywordParameterNode(831...835)((831...835), nil), + [KeywordParameterNode(831...835)(:bar, (831...835), nil), KeywordParameterNode(837...849)( + :baz, (837...841), StringNode(842...849)( (842...843), diff --git a/test/yarp/snapshots/whitequark/args.txt b/test/yarp/snapshots/whitequark/args.txt index faa2ee445925f6..8d5ce21dcb060e 100644 --- a/test/yarp/snapshots/whitequark/args.txt +++ b/test/yarp/snapshots/whitequark/args.txt @@ -306,6 +306,7 @@ ProgramNode(0...690)( [], nil, [KeywordParameterNode(236...242)( + :foo, (236...240), IntegerNode(241...242)() )], @@ -330,10 +331,12 @@ ProgramNode(0...690)( [], nil, [KeywordParameterNode(261...267)( + :foo, (261...265), IntegerNode(266...267)() ), KeywordParameterNode(269...275)( + :bar, (269...273), IntegerNode(274...275)() )], @@ -621,7 +624,7 @@ ProgramNode(0...690)( [], [], nil, - [KeywordParameterNode(565...569)((565...569), nil)], + [KeywordParameterNode(565...569)(:foo, (565...569), nil)], nil, nil ), @@ -643,6 +646,7 @@ ProgramNode(0...690)( [], nil, [KeywordParameterNode(583...590)( + :foo, (583...587), IntegerNode(588...590)() )], diff --git a/test/yarp/snapshots/whitequark/blockargs.txt b/test/yarp/snapshots/whitequark/blockargs.txt index d716003643385c..56bf4f49ca3ce8 100644 --- a/test/yarp/snapshots/whitequark/blockargs.txt +++ b/test/yarp/snapshots/whitequark/blockargs.txt @@ -807,6 +807,7 @@ ProgramNode(0...550)( [], nil, [KeywordParameterNode(403...409)( + :foo, (403...407), IntegerNode(408...409)() )], @@ -840,10 +841,12 @@ ProgramNode(0...550)( [], nil, [KeywordParameterNode(422...428)( + :foo, (422...426), IntegerNode(427...428)() ), KeywordParameterNode(430...436)( + :bar, (430...434), IntegerNode(435...436)() )], @@ -876,7 +879,7 @@ ProgramNode(0...550)( [], [], nil, - [KeywordParameterNode(456...460)((456...460), nil)], + [KeywordParameterNode(456...460)(:foo, (456...460), nil)], nil, nil ), diff --git a/test/yarp/snapshots/whitequark/kwarg.txt b/test/yarp/snapshots/whitequark/kwarg.txt index d096caece0c61c..9b605f5c5e5933 100644 --- a/test/yarp/snapshots/whitequark/kwarg.txt +++ b/test/yarp/snapshots/whitequark/kwarg.txt @@ -9,7 +9,7 @@ ProgramNode(0...16)( [], [], nil, - [KeywordParameterNode(6...10)((6...10), nil)], + [KeywordParameterNode(6...10)(:foo, (6...10), nil)], nil, nil ), diff --git a/test/yarp/snapshots/whitequark/kwoptarg.txt b/test/yarp/snapshots/whitequark/kwoptarg.txt index 9514567387d91f..effee043fad37b 100644 --- a/test/yarp/snapshots/whitequark/kwoptarg.txt +++ b/test/yarp/snapshots/whitequark/kwoptarg.txt @@ -9,7 +9,11 @@ ProgramNode(0...18)( [], [], nil, - [KeywordParameterNode(6...12)((6...10), IntegerNode(11...12)())], + [KeywordParameterNode(6...12)( + :foo, + (6...10), + IntegerNode(11...12)() + )], nil, nil ), diff --git a/test/yarp/snapshots/whitequark/kwoptarg_with_kwrestarg_and_forwarded_args.txt b/test/yarp/snapshots/whitequark/kwoptarg_with_kwrestarg_and_forwarded_args.txt index 14fd8da395164c..c9e8989ef35bcb 100644 --- a/test/yarp/snapshots/whitequark/kwoptarg_with_kwrestarg_and_forwarded_args.txt +++ b/test/yarp/snapshots/whitequark/kwoptarg_with_kwrestarg_and_forwarded_args.txt @@ -9,7 +9,7 @@ ProgramNode(0...28)( [], [], nil, - [KeywordParameterNode(6...12)((6...8), NilNode(9...12)())], + [KeywordParameterNode(6...12)(:a, (6...8), NilNode(9...12)())], KeywordRestParameterNode(14...16)((14...16), nil), nil ), diff --git a/test/yarp/snapshots/whitequark/ruby_bug_15789.txt b/test/yarp/snapshots/whitequark/ruby_bug_15789.txt index 0621e71c8cc3f5..9066a4032bbdec 100644 --- a/test/yarp/snapshots/whitequark/ruby_bug_15789.txt +++ b/test/yarp/snapshots/whitequark/ruby_bug_15789.txt @@ -76,6 +76,7 @@ ProgramNode(0...41)( [], nil, [KeywordParameterNode(27...36)( + :a, (27...29), LambdaNode(30...36)( [], diff --git a/test/yarp/snapshots/whitequark/ruby_bug_9669.txt b/test/yarp/snapshots/whitequark/ruby_bug_9669.txt index 6302c3d317b073..aad27053bbcc7c 100644 --- a/test/yarp/snapshots/whitequark/ruby_bug_9669.txt +++ b/test/yarp/snapshots/whitequark/ruby_bug_9669.txt @@ -9,7 +9,7 @@ ProgramNode(0...33)( [], [], nil, - [KeywordParameterNode(6...8)((6...8), nil)], + [KeywordParameterNode(6...8)(:b, (6...8), nil)], nil, nil ), diff --git a/test/yarp/snapshots/whitequark/send_lambda_args_noparen.txt b/test/yarp/snapshots/whitequark/send_lambda_args_noparen.txt index ebb6fb106518f6..57f5c2ead21096 100644 --- a/test/yarp/snapshots/whitequark/send_lambda_args_noparen.txt +++ b/test/yarp/snapshots/whitequark/send_lambda_args_noparen.txt @@ -12,7 +12,7 @@ ProgramNode(0...22)( [], [], nil, - [KeywordParameterNode(3...7)((3...5), IntegerNode(6...7)())], + [KeywordParameterNode(3...7)(:a, (3...5), IntegerNode(6...7)())], nil, nil ), @@ -33,7 +33,7 @@ ProgramNode(0...22)( [], [], nil, - [KeywordParameterNode(16...18)((16...18), nil)], + [KeywordParameterNode(16...18)(:a, (16...18), nil)], nil, nil ), diff --git a/yarp/config.yml b/yarp/config.yml index 4207e09a0c062d..91d6d81cb53b3c 100644 --- a/yarp/config.yml +++ b/yarp/config.yml @@ -1556,6 +1556,8 @@ nodes: ^^^^ - name: KeywordParameterNode fields: + - name: name + type: constant - name: name_loc type: location - name: value diff --git a/yarp/yarp.c b/yarp/yarp.c index 17ef80c4725e77..6596b876209399 100644 --- a/yarp/yarp.c +++ b/yarp/yarp.c @@ -3067,6 +3067,7 @@ yp_keyword_parameter_node_create(yp_parser_t *parser, const yp_token_t *name, yp .end = value == NULL ? name->end : value->location.end }, }, + .name = yp_parser_constant_id_location(parser, name->start, name->end - 1), .name_loc = YP_LOCATION_TOKEN_VALUE(name), .value = value }; From 3f78eec44ab2f06f05c699cbd90714716e13ebd7 Mon Sep 17 00:00:00 2001 From: Kevin Newton Date: Wed, 6 Sep 2023 11:14:38 -0400 Subject: [PATCH 12/46] [ruby/yarp] Constants on keyword rest parameters https://github.com/ruby/yarp/commit/5e1a8fbc54 --- test/yarp/errors_test.rb | 10 +++++----- test/yarp/snapshots/methods.txt | 4 ++-- test/yarp/snapshots/non_alphanumeric_methods.txt | 2 +- test/yarp/snapshots/procs.txt | 4 ++-- test/yarp/snapshots/seattlerb/block_arg_kwsplat.txt | 2 +- test/yarp/snapshots/seattlerb/block_args_kwargs.txt | 2 +- test/yarp/snapshots/seattlerb/defn_kwarg_env.txt | 2 +- test/yarp/snapshots/seattlerb/defn_kwarg_kwsplat.txt | 2 +- .../snapshots/seattlerb/defn_kwarg_kwsplat_anon.txt | 2 +- test/yarp/snapshots/seattlerb/defn_powarg.txt | 2 +- test/yarp/snapshots/seattlerb/iter_kwarg_kwsplat.txt | 2 +- .../snapshots/unparser/corpus/literal/since/32.txt | 2 +- test/yarp/snapshots/whitequark/args.txt | 6 +++--- test/yarp/snapshots/whitequark/blockargs.txt | 8 ++++++-- .../whitequark/forwarded_argument_with_kwrestarg.txt | 2 +- test/yarp/snapshots/whitequark/forwarded_kwrestarg.txt | 2 +- .../forwarded_kwrestarg_with_additional_kwarg.txt | 2 +- .../kwoptarg_with_kwrestarg_and_forwarded_args.txt | 2 +- test/yarp/snapshots/whitequark/kwrestarg_named.txt | 2 +- test/yarp/snapshots/whitequark/kwrestarg_unnamed.txt | 2 +- yarp/config.yml | 6 ++++-- yarp/yarp.c | 5 +++-- 22 files changed, 40 insertions(+), 33 deletions(-) diff --git a/test/yarp/errors_test.rb b/test/yarp/errors_test.rb index d4f46440b5d6e9..f4f3eab12fe638 100644 --- a/test/yarp/errors_test.rb +++ b/test/yarp/errors_test.rb @@ -742,7 +742,7 @@ def test_rest_keywords_parameters_before_required_parameters [], nil, [KeywordParameterNode(:b, Location(), nil)], - KeywordRestParameterNode(Location(), Location()), + KeywordRestParameterNode(:rest, Location(), Location()), nil ), nil, @@ -789,7 +789,7 @@ def test_multiple_error_in_parameters_order [RequiredParameterNode(:a)], nil, [KeywordParameterNode(:b, Location(), nil)], - KeywordRestParameterNode(Location(), Location()), + KeywordRestParameterNode(:args, Location(), Location()), nil ), nil, @@ -818,7 +818,7 @@ def test_switching_to_optional_arguments_twice [RequiredParameterNode(:a)], nil, [KeywordParameterNode(:b, Location(), nil)], - KeywordRestParameterNode(Location(), Location()), + KeywordRestParameterNode(:args, Location(), Location()), nil ), nil, @@ -847,7 +847,7 @@ def test_switching_to_named_arguments_twice [RequiredParameterNode(:a)], nil, [KeywordParameterNode(:b, Location(), nil)], - KeywordRestParameterNode(Location(), Location()), + KeywordRestParameterNode(:args, Location(), Location()), nil ), nil, @@ -1065,7 +1065,7 @@ def test_duplicated_parameter_names expected = DefNode( Location(), nil, - ParametersNode([RequiredParameterNode(:a), RequiredParameterNode(:b)], [], [], nil, [], KeywordRestParameterNode(Location(), Location()), nil), + ParametersNode([RequiredParameterNode(:a), RequiredParameterNode(:b)], [], [], nil, [], KeywordRestParameterNode(:a, Location(), Location()), nil), nil, [:a, :b], Location(), diff --git a/test/yarp/snapshots/methods.txt b/test/yarp/snapshots/methods.txt index 390522bae4d54c..ae808aba0dacb5 100644 --- a/test/yarp/snapshots/methods.txt +++ b/test/yarp/snapshots/methods.txt @@ -262,7 +262,7 @@ ProgramNode(0...1194)( [], nil, [], - KeywordRestParameterNode(250...253)((250...252), (252...253)), + KeywordRestParameterNode(250...253)(:b, (252...253), (250...252)), nil ), nil, @@ -283,7 +283,7 @@ ProgramNode(0...1194)( [], nil, [], - KeywordRestParameterNode(266...268)((266...268), nil), + KeywordRestParameterNode(266...268)(nil, nil, (266...268)), nil ), nil, diff --git a/test/yarp/snapshots/non_alphanumeric_methods.txt b/test/yarp/snapshots/non_alphanumeric_methods.txt index a8e9cd798fb465..cf87adc48c9c0b 100644 --- a/test/yarp/snapshots/non_alphanumeric_methods.txt +++ b/test/yarp/snapshots/non_alphanumeric_methods.txt @@ -115,7 +115,7 @@ ProgramNode(0...434)( [], nil, [], - KeywordRestParameterNode(110...113)((110...112), (112...113)), + KeywordRestParameterNode(110...113)(:b, (112...113), (110...112)), nil ), nil, diff --git a/test/yarp/snapshots/procs.txt b/test/yarp/snapshots/procs.txt index e825afd8e4642e..3f6f1d7470702e 100644 --- a/test/yarp/snapshots/procs.txt +++ b/test/yarp/snapshots/procs.txt @@ -119,7 +119,7 @@ ProgramNode(0...266)( RestParameterNode(145...147)((145...146), (146...147)), [KeywordParameterNode(149...151)(:d, (149...151), nil), KeywordParameterNode(153...155)(:e, (153...155), nil)], - KeywordRestParameterNode(157...160)((157...159), (159...160)), + KeywordRestParameterNode(157...160)(:f, (159...160), (157...159)), BlockParameterNode(162...164)(:g, (163...164), (162...163)) ), [], @@ -146,7 +146,7 @@ ProgramNode(0...266)( RestParameterNode(187...189)((187...188), (188...189)), [KeywordParameterNode(191...193)(:d, (191...193), nil), KeywordParameterNode(195...197)(:e, (195...197), nil)], - KeywordRestParameterNode(199...202)((199...201), (201...202)), + KeywordRestParameterNode(199...202)(:f, (201...202), (199...201)), BlockParameterNode(204...206)(:g, (205...206), (204...205)) ), [], diff --git a/test/yarp/snapshots/seattlerb/block_arg_kwsplat.txt b/test/yarp/snapshots/seattlerb/block_arg_kwsplat.txt index 36b7c9f83cced4..196b4d250f2fd2 100644 --- a/test/yarp/snapshots/seattlerb/block_arg_kwsplat.txt +++ b/test/yarp/snapshots/seattlerb/block_arg_kwsplat.txt @@ -17,7 +17,7 @@ ProgramNode(0...11)( [], nil, [], - KeywordRestParameterNode(5...8)((5...7), (7...8)), + KeywordRestParameterNode(5...8)(:b, (7...8), (5...7)), nil ), [], diff --git a/test/yarp/snapshots/seattlerb/block_args_kwargs.txt b/test/yarp/snapshots/seattlerb/block_args_kwargs.txt index f54b1bc55f5efe..8db4d3f0ea2727 100644 --- a/test/yarp/snapshots/seattlerb/block_args_kwargs.txt +++ b/test/yarp/snapshots/seattlerb/block_args_kwargs.txt @@ -17,7 +17,7 @@ ProgramNode(0...23)( [], nil, [], - KeywordRestParameterNode(5...13)((5...7), (7...13)), + KeywordRestParameterNode(5...13)(:kwargs, (7...13), (5...7)), nil ), [], diff --git a/test/yarp/snapshots/seattlerb/defn_kwarg_env.txt b/test/yarp/snapshots/seattlerb/defn_kwarg_env.txt index 5872579ee6ef8b..4364d661881ff7 100644 --- a/test/yarp/snapshots/seattlerb/defn_kwarg_env.txt +++ b/test/yarp/snapshots/seattlerb/defn_kwarg_env.txt @@ -10,7 +10,7 @@ ProgramNode(0...45)( [], nil, [], - KeywordRestParameterNode(9...18)((9...11), (11...18)), + KeywordRestParameterNode(9...18)(:testing, (11...18), (9...11)), nil ), StatementsNode(20...41)( diff --git a/test/yarp/snapshots/seattlerb/defn_kwarg_kwsplat.txt b/test/yarp/snapshots/seattlerb/defn_kwarg_kwsplat.txt index bc4cb7d8a9faee..040bca4c5d5f57 100644 --- a/test/yarp/snapshots/seattlerb/defn_kwarg_kwsplat.txt +++ b/test/yarp/snapshots/seattlerb/defn_kwarg_kwsplat.txt @@ -10,7 +10,7 @@ ProgramNode(0...20)( [], nil, [KeywordParameterNode(6...10)(:b, (6...8), IntegerNode(9...10)())], - KeywordRestParameterNode(12...15)((12...14), (14...15)), + KeywordRestParameterNode(12...15)(:c, (14...15), (12...14)), nil ), nil, diff --git a/test/yarp/snapshots/seattlerb/defn_kwarg_kwsplat_anon.txt b/test/yarp/snapshots/seattlerb/defn_kwarg_kwsplat_anon.txt index 009b3f0fcaebac..080b3ed2abc7d0 100644 --- a/test/yarp/snapshots/seattlerb/defn_kwarg_kwsplat_anon.txt +++ b/test/yarp/snapshots/seattlerb/defn_kwarg_kwsplat_anon.txt @@ -10,7 +10,7 @@ ProgramNode(0...19)( [], nil, [KeywordParameterNode(6...10)(:b, (6...8), IntegerNode(9...10)())], - KeywordRestParameterNode(12...14)((12...14), nil), + KeywordRestParameterNode(12...14)(nil, nil, (12...14)), nil ), nil, diff --git a/test/yarp/snapshots/seattlerb/defn_powarg.txt b/test/yarp/snapshots/seattlerb/defn_powarg.txt index a6d63f56cb44e9..6965fca97e027a 100644 --- a/test/yarp/snapshots/seattlerb/defn_powarg.txt +++ b/test/yarp/snapshots/seattlerb/defn_powarg.txt @@ -10,7 +10,7 @@ ProgramNode(0...17)( [], nil, [], - KeywordRestParameterNode(6...12)((6...8), (8...12)), + KeywordRestParameterNode(6...12)(:opts, (8...12), (6...8)), nil ), nil, diff --git a/test/yarp/snapshots/seattlerb/iter_kwarg_kwsplat.txt b/test/yarp/snapshots/seattlerb/iter_kwarg_kwsplat.txt index b068be0913aa39..5ade32c4838c74 100644 --- a/test/yarp/snapshots/seattlerb/iter_kwarg_kwsplat.txt +++ b/test/yarp/snapshots/seattlerb/iter_kwarg_kwsplat.txt @@ -17,7 +17,7 @@ ProgramNode(0...17)( [], nil, [KeywordParameterNode(5...9)(:b, (5...7), IntegerNode(8...9)())], - KeywordRestParameterNode(11...14)((11...13), (13...14)), + KeywordRestParameterNode(11...14)(:c, (13...14), (11...13)), nil ), [], diff --git a/test/yarp/snapshots/unparser/corpus/literal/since/32.txt b/test/yarp/snapshots/unparser/corpus/literal/since/32.txt index 31397bf46874e3..fd07f07237685a 100644 --- a/test/yarp/snapshots/unparser/corpus/literal/since/32.txt +++ b/test/yarp/snapshots/unparser/corpus/literal/since/32.txt @@ -10,7 +10,7 @@ ProgramNode(0...90)( [], nil, [], - KeywordRestParameterNode(18...20)((18...20), nil), + KeywordRestParameterNode(18...20)(nil, nil, (18...20)), nil ), StatementsNode(24...41)( diff --git a/test/yarp/snapshots/whitequark/args.txt b/test/yarp/snapshots/whitequark/args.txt index 8d5ce21dcb060e..12d18fdaffe4d2 100644 --- a/test/yarp/snapshots/whitequark/args.txt +++ b/test/yarp/snapshots/whitequark/args.txt @@ -340,7 +340,7 @@ ProgramNode(0...690)( (269...273), IntegerNode(274...275)() )], - KeywordRestParameterNode(277...282)((277...279), (279...282)), + KeywordRestParameterNode(277...282)(:baz, (279...282), (277...279)), BlockParameterNode(284...286)(:b, (285...286), (284...285)) ), nil, @@ -361,7 +361,7 @@ ProgramNode(0...690)( [], nil, [], - KeywordRestParameterNode(300...305)((300...302), (302...305)), + KeywordRestParameterNode(300...305)(:baz, (302...305), (300...302)), BlockParameterNode(307...309)(:b, (308...309), (307...308)) ), nil, @@ -382,7 +382,7 @@ ProgramNode(0...690)( [], RestParameterNode(322...323)((322...323), nil), [], - KeywordRestParameterNode(325...327)((325...327), nil), + KeywordRestParameterNode(325...327)(nil, nil, (325...327)), nil ), nil, diff --git a/test/yarp/snapshots/whitequark/blockargs.txt b/test/yarp/snapshots/whitequark/blockargs.txt index 56bf4f49ca3ce8..4c51e4e1a8dfd4 100644 --- a/test/yarp/snapshots/whitequark/blockargs.txt +++ b/test/yarp/snapshots/whitequark/blockargs.txt @@ -75,7 +75,7 @@ ProgramNode(0...550)( [], nil, [], - KeywordRestParameterNode(32...37)((32...34), (34...37)), + KeywordRestParameterNode(32...37)(:baz, (34...37), (32...34)), BlockParameterNode(39...41)(:b, (40...41), (39...40)) ), [], @@ -850,7 +850,11 @@ ProgramNode(0...550)( (430...434), IntegerNode(435...436)() )], - KeywordRestParameterNode(438...443)((438...440), (440...443)), + KeywordRestParameterNode(438...443)( + :baz, + (440...443), + (438...440) + ), BlockParameterNode(445...447)(:b, (446...447), (445...446)) ), [], diff --git a/test/yarp/snapshots/whitequark/forwarded_argument_with_kwrestarg.txt b/test/yarp/snapshots/whitequark/forwarded_argument_with_kwrestarg.txt index a751f923c117be..da165e8e71a72a 100644 --- a/test/yarp/snapshots/whitequark/forwarded_argument_with_kwrestarg.txt +++ b/test/yarp/snapshots/whitequark/forwarded_argument_with_kwrestarg.txt @@ -10,7 +10,7 @@ ProgramNode(0...45)( [], nil, [], - KeywordRestParameterNode(18...20)((18...20), nil), + KeywordRestParameterNode(18...20)(nil, nil, (18...20)), nil ), StatementsNode(23...40)( diff --git a/test/yarp/snapshots/whitequark/forwarded_kwrestarg.txt b/test/yarp/snapshots/whitequark/forwarded_kwrestarg.txt index 0fcac6a2985d97..51d8720fe6c819 100644 --- a/test/yarp/snapshots/whitequark/forwarded_kwrestarg.txt +++ b/test/yarp/snapshots/whitequark/forwarded_kwrestarg.txt @@ -10,7 +10,7 @@ ProgramNode(0...25)( [], nil, [], - KeywordRestParameterNode(8...10)((8...10), nil), + KeywordRestParameterNode(8...10)(nil, nil, (8...10)), nil ), StatementsNode(13...20)( diff --git a/test/yarp/snapshots/whitequark/forwarded_kwrestarg_with_additional_kwarg.txt b/test/yarp/snapshots/whitequark/forwarded_kwrestarg_with_additional_kwarg.txt index 65f75e723a1793..e0d078128b6897 100644 --- a/test/yarp/snapshots/whitequark/forwarded_kwrestarg_with_additional_kwarg.txt +++ b/test/yarp/snapshots/whitequark/forwarded_kwrestarg_with_additional_kwarg.txt @@ -10,7 +10,7 @@ ProgramNode(0...41)( [], nil, [], - KeywordRestParameterNode(8...10)((8...10), nil), + KeywordRestParameterNode(8...10)(nil, nil, (8...10)), nil ), StatementsNode(13...36)( diff --git a/test/yarp/snapshots/whitequark/kwoptarg_with_kwrestarg_and_forwarded_args.txt b/test/yarp/snapshots/whitequark/kwoptarg_with_kwrestarg_and_forwarded_args.txt index c9e8989ef35bcb..bd1c1e6e54de28 100644 --- a/test/yarp/snapshots/whitequark/kwoptarg_with_kwrestarg_and_forwarded_args.txt +++ b/test/yarp/snapshots/whitequark/kwoptarg_with_kwrestarg_and_forwarded_args.txt @@ -10,7 +10,7 @@ ProgramNode(0...28)( [], nil, [KeywordParameterNode(6...12)(:a, (6...8), NilNode(9...12)())], - KeywordRestParameterNode(14...16)((14...16), nil), + KeywordRestParameterNode(14...16)(nil, nil, (14...16)), nil ), StatementsNode(19...24)( diff --git a/test/yarp/snapshots/whitequark/kwrestarg_named.txt b/test/yarp/snapshots/whitequark/kwrestarg_named.txt index 591c59dfba1c98..2dd4c0225e9a0d 100644 --- a/test/yarp/snapshots/whitequark/kwrestarg_named.txt +++ b/test/yarp/snapshots/whitequark/kwrestarg_named.txt @@ -10,7 +10,7 @@ ProgramNode(0...17)( [], nil, [], - KeywordRestParameterNode(6...11)((6...8), (8...11)), + KeywordRestParameterNode(6...11)(:foo, (8...11), (6...8)), nil ), nil, diff --git a/test/yarp/snapshots/whitequark/kwrestarg_unnamed.txt b/test/yarp/snapshots/whitequark/kwrestarg_unnamed.txt index 57bf8cc8b4551b..3fa1dcd7fedcc3 100644 --- a/test/yarp/snapshots/whitequark/kwrestarg_unnamed.txt +++ b/test/yarp/snapshots/whitequark/kwrestarg_unnamed.txt @@ -10,7 +10,7 @@ ProgramNode(0...14)( [], nil, [], - KeywordRestParameterNode(6...8)((6...8), nil), + KeywordRestParameterNode(6...8)(nil, nil, (6...8)), nil ), nil, diff --git a/yarp/config.yml b/yarp/config.yml index 91d6d81cb53b3c..b24490a3332012 100644 --- a/yarp/config.yml +++ b/yarp/config.yml @@ -1574,10 +1574,12 @@ nodes: end - name: KeywordRestParameterNode fields: - - name: operator_loc - type: location + - name: name + type: constant? - name: name_loc type: location? + - name: operator_loc + type: location comment: | Represents a keyword rest parameter to a method, block, or lambda definition. diff --git a/yarp/yarp.c b/yarp/yarp.c index 6596b876209399..7f9f3b5589f597 100644 --- a/yarp/yarp.c +++ b/yarp/yarp.c @@ -3088,8 +3088,9 @@ yp_keyword_rest_parameter_node_create(yp_parser_t *parser, const yp_token_t *ope .end = (name->type == YP_TOKEN_NOT_PROVIDED ? operator->end : name->end) }, }, - .operator_loc = YP_LOCATION_TOKEN_VALUE(operator), - .name_loc = YP_OPTIONAL_LOCATION_TOKEN_VALUE(name) + .name = yp_parser_optional_constant_id_token(parser, name), + .name_loc = YP_OPTIONAL_LOCATION_TOKEN_VALUE(name), + .operator_loc = YP_LOCATION_TOKEN_VALUE(operator) }; return node; From 9343ef250452c17b2842701805a4a0417165dd15 Mon Sep 17 00:00:00 2001 From: Kevin Newton Date: Wed, 6 Sep 2023 11:22:27 -0400 Subject: [PATCH 13/46] [ruby/yarp] Constants on rest parameter nodes https://github.com/ruby/yarp/commit/a6fdb8aae9 --- lib/yarp.rb | 2 +- test/yarp/errors_test.rb | 4 +-- test/yarp/snapshots/blocks.txt | 2 +- test/yarp/snapshots/methods.txt | 6 ++-- test/yarp/snapshots/procs.txt | 6 ++-- .../seattlerb/block_arg_opt_splat.txt | 2 +- .../block_arg_opt_splat_arg_block_omfg.txt | 2 +- .../seattlerb/block_arg_splat_arg.txt | 2 +- .../snapshots/seattlerb/block_opt_splat.txt | 2 +- .../block_opt_splat_arg_block_omfg.txt | 2 +- .../snapshots/seattlerb/block_splat_reg.txt | 2 +- test/yarp/snapshots/seattlerb/bug236.txt | 2 +- .../seattlerb/defn_arg_asplat_arg.txt | 2 +- .../seattlerb/defn_opt_splat_arg.txt | 2 +- .../snapshots/seattlerb/defn_splat_arg.txt | 2 +- .../yarp/snapshots/seattlerb/difficult3_2.txt | 2 +- .../yarp/snapshots/seattlerb/difficult3_3.txt | 2 +- .../snapshots/seattlerb/iter_args_10_1.txt | 2 +- .../snapshots/seattlerb/iter_args_10_2.txt | 2 +- .../snapshots/seattlerb/iter_args_11_1.txt | 2 +- .../snapshots/seattlerb/iter_args_11_2.txt | 2 +- test/yarp/snapshots/seattlerb/iter_args_4.txt | 2 +- .../snapshots/seattlerb/iter_args_7_1.txt | 2 +- .../snapshots/seattlerb/iter_args_7_2.txt | 2 +- .../snapshots/seattlerb/iter_args_8_1.txt | 2 +- .../snapshots/seattlerb/iter_args_8_2.txt | 2 +- .../stabby_arg_opt_splat_arg_block_omfg.txt | 2 +- .../unparser/corpus/literal/block.txt | 12 +++---- .../snapshots/unparser/corpus/literal/def.txt | 12 +++---- .../unparser/corpus/literal/since/32.txt | 2 +- test/yarp/snapshots/whitequark/args.txt | 18 +++++------ test/yarp/snapshots/whitequark/blockargs.txt | 32 +++++++++---------- .../forwarded_argument_with_restarg.txt | 2 +- .../whitequark/forwarded_restarg.txt | 2 +- .../snapshots/whitequark/parser_bug_507.txt | 2 +- .../snapshots/whitequark/restarg_named.txt | 2 +- .../snapshots/whitequark/restarg_unnamed.txt | 2 +- .../yarp/snapshots/whitequark/send_lambda.txt | 2 +- yarp/config.yml | 6 ++-- yarp/yarp.c | 5 +-- 40 files changed, 83 insertions(+), 80 deletions(-) diff --git a/lib/yarp.rb b/lib/yarp.rb index c445a31d32dacf..9ee9c4b341bc8a 100644 --- a/lib/yarp.rb +++ b/lib/yarp.rb @@ -540,7 +540,7 @@ def self.yarp_locals(source) sorted = [ *params.requireds.grep(RequiredParameterNode).map(&:name), *params.optionals.map(&:name), - *((params.rest.name ? params.rest.name.to_sym : :*) if params.rest && params.rest.operator != ","), + *((params.rest.name || :*) if params.rest && params.rest.operator != ","), *params.posts.grep(RequiredParameterNode).map(&:name), *params.keywords.reject(&:value).map(&:name), *params.keywords.select(&:value).map(&:name) diff --git a/test/yarp/errors_test.rb b/test/yarp/errors_test.rb index f4f3eab12fe638..adaac44b353635 100644 --- a/test/yarp/errors_test.rb +++ b/test/yarp/errors_test.rb @@ -1047,7 +1047,7 @@ def test_duplicated_parameter_names expected = DefNode( Location(), nil, - ParametersNode([RequiredParameterNode(:a), RequiredParameterNode(:b)], [], [], RestParameterNode(Location(), Location()), [], nil, nil), + ParametersNode([RequiredParameterNode(:a), RequiredParameterNode(:b)], [], [], RestParameterNode(:a, Location(), Location()), [], nil, nil), nil, [:a, :b], Location(), @@ -1101,7 +1101,7 @@ def test_duplicated_parameter_names expected = DefNode( Location(), nil, - ParametersNode([], [OptionalParameterNode(:a, Location(), Location(), IntegerNode())], [RequiredParameterNode(:b)], RestParameterNode(Location(), Location()), [], nil, nil), + ParametersNode([], [OptionalParameterNode(:a, Location(), Location(), IntegerNode())], [RequiredParameterNode(:b)], RestParameterNode(:c, Location(), Location()), [], nil, nil), nil, [:a, :b, :c], Location(), diff --git a/test/yarp/snapshots/blocks.txt b/test/yarp/snapshots/blocks.txt index 54a8d6f743f927..b23965960afcdf 100644 --- a/test/yarp/snapshots/blocks.txt +++ b/test/yarp/snapshots/blocks.txt @@ -604,7 +604,7 @@ ProgramNode(0...402)( [RequiredParameterNode(393...396)(:bar)], [], [], - RestParameterNode(396...397)((396...397), nil), + RestParameterNode(396...397)(nil, nil, (396...397)), [], nil, nil diff --git a/test/yarp/snapshots/methods.txt b/test/yarp/snapshots/methods.txt index ae808aba0dacb5..72fb1a704a26b1 100644 --- a/test/yarp/snapshots/methods.txt +++ b/test/yarp/snapshots/methods.txt @@ -549,7 +549,7 @@ ProgramNode(0...1194)( [], [], [], - RestParameterNode(509...511)((509...510), (510...511)), + RestParameterNode(509...511)(:b, (510...511), (509...510)), [], nil, nil @@ -570,7 +570,7 @@ ProgramNode(0...1194)( [], [], [], - RestParameterNode(523...524)((523...524), nil), + RestParameterNode(523...524)(nil, nil, (523...524)), [], nil, nil @@ -740,7 +740,7 @@ ProgramNode(0...1194)( [], [], [], - RestParameterNode(693...694)((693...694), nil), + RestParameterNode(693...694)(nil, nil, (693...694)), [], nil, nil diff --git a/test/yarp/snapshots/procs.txt b/test/yarp/snapshots/procs.txt index 3f6f1d7470702e..fca9ccb7103a9a 100644 --- a/test/yarp/snapshots/procs.txt +++ b/test/yarp/snapshots/procs.txt @@ -116,7 +116,7 @@ ProgramNode(0...266)( IntegerNode(142...143)() )], [], - RestParameterNode(145...147)((145...146), (146...147)), + RestParameterNode(145...147)(:c, (146...147), (145...146)), [KeywordParameterNode(149...151)(:d, (149...151), nil), KeywordParameterNode(153...155)(:e, (153...155), nil)], KeywordRestParameterNode(157...160)(:f, (159...160), (157...159)), @@ -143,7 +143,7 @@ ProgramNode(0...266)( IntegerNode(184...185)() )], [], - RestParameterNode(187...189)((187...188), (188...189)), + RestParameterNode(187...189)(:c, (188...189), (187...188)), [KeywordParameterNode(191...193)(:d, (191...193), nil), KeywordParameterNode(195...197)(:e, (195...197), nil)], KeywordRestParameterNode(199...202)(:f, (201...202), (199...201)), @@ -227,7 +227,7 @@ ProgramNode(0...266)( )], [], [], - RestParameterNode(259...261)((259...260), (260...261)), + RestParameterNode(259...261)(:c, (260...261), (259...260)), [], nil, nil diff --git a/test/yarp/snapshots/seattlerb/block_arg_opt_splat.txt b/test/yarp/snapshots/seattlerb/block_arg_opt_splat.txt index 096a00092d8fa0..28e355ebe55787 100644 --- a/test/yarp/snapshots/seattlerb/block_arg_opt_splat.txt +++ b/test/yarp/snapshots/seattlerb/block_arg_opt_splat.txt @@ -20,7 +20,7 @@ ProgramNode(0...20)( IntegerNode(12...13)() )], [], - RestParameterNode(15...17)((15...16), (16...17)), + RestParameterNode(15...17)(:d, (16...17), (15...16)), [], nil, nil diff --git a/test/yarp/snapshots/seattlerb/block_arg_opt_splat_arg_block_omfg.txt b/test/yarp/snapshots/seattlerb/block_arg_opt_splat_arg_block_omfg.txt index dc7500ce920e53..2bfb380f06be22 100644 --- a/test/yarp/snapshots/seattlerb/block_arg_opt_splat_arg_block_omfg.txt +++ b/test/yarp/snapshots/seattlerb/block_arg_opt_splat_arg_block_omfg.txt @@ -20,7 +20,7 @@ ProgramNode(0...25)( IntegerNode(10...11)() )], [RequiredParameterNode(17...18)(:e)], - RestParameterNode(13...15)((13...14), (14...15)), + RestParameterNode(13...15)(:d, (14...15), (13...14)), [], nil, BlockParameterNode(20...22)(:f, (21...22), (20...21)) diff --git a/test/yarp/snapshots/seattlerb/block_arg_splat_arg.txt b/test/yarp/snapshots/seattlerb/block_arg_splat_arg.txt index 01732f748e2652..bc2cb81b640946 100644 --- a/test/yarp/snapshots/seattlerb/block_arg_splat_arg.txt +++ b/test/yarp/snapshots/seattlerb/block_arg_splat_arg.txt @@ -15,7 +15,7 @@ ProgramNode(0...16)( [RequiredParameterNode(5...6)(:b)], [], [RequiredParameterNode(12...13)(:d)], - RestParameterNode(8...10)((8...9), (9...10)), + RestParameterNode(8...10)(:c, (9...10), (8...9)), [], nil, nil diff --git a/test/yarp/snapshots/seattlerb/block_opt_splat.txt b/test/yarp/snapshots/seattlerb/block_opt_splat.txt index 59b1a79e409c5b..7e5aebff1bc689 100644 --- a/test/yarp/snapshots/seattlerb/block_opt_splat.txt +++ b/test/yarp/snapshots/seattlerb/block_opt_splat.txt @@ -20,7 +20,7 @@ ProgramNode(0...17)( IntegerNode(9...10)() )], [], - RestParameterNode(12...14)((12...13), (13...14)), + RestParameterNode(12...14)(:c, (13...14), (12...13)), [], nil, nil diff --git a/test/yarp/snapshots/seattlerb/block_opt_splat_arg_block_omfg.txt b/test/yarp/snapshots/seattlerb/block_opt_splat_arg_block_omfg.txt index 0efcade2290767..89ee3553bff602 100644 --- a/test/yarp/snapshots/seattlerb/block_opt_splat_arg_block_omfg.txt +++ b/test/yarp/snapshots/seattlerb/block_opt_splat_arg_block_omfg.txt @@ -20,7 +20,7 @@ ProgramNode(0...22)( IntegerNode(7...8)() )], [RequiredParameterNode(14...15)(:d)], - RestParameterNode(10...12)((10...11), (11...12)), + RestParameterNode(10...12)(:c, (11...12), (10...11)), [], nil, BlockParameterNode(17...19)(:e, (18...19), (17...18)) diff --git a/test/yarp/snapshots/seattlerb/block_splat_reg.txt b/test/yarp/snapshots/seattlerb/block_splat_reg.txt index 85011bd7819cc7..b8d574b454080c 100644 --- a/test/yarp/snapshots/seattlerb/block_splat_reg.txt +++ b/test/yarp/snapshots/seattlerb/block_splat_reg.txt @@ -15,7 +15,7 @@ ProgramNode(0...13)( [], [], [RequiredParameterNode(9...10)(:c)], - RestParameterNode(5...7)((5...6), (6...7)), + RestParameterNode(5...7)(:b, (6...7), (5...6)), [], nil, nil diff --git a/test/yarp/snapshots/seattlerb/bug236.txt b/test/yarp/snapshots/seattlerb/bug236.txt index bf6b4298023775..c83125b65ff7fa 100644 --- a/test/yarp/snapshots/seattlerb/bug236.txt +++ b/test/yarp/snapshots/seattlerb/bug236.txt @@ -15,7 +15,7 @@ ProgramNode(0...15)( [RequiredParameterNode(3...4)(:a)], [], [], - RestParameterNode(4...5)((4...5), nil), + RestParameterNode(4...5)(nil, nil, (4...5)), [], nil, nil diff --git a/test/yarp/snapshots/seattlerb/defn_arg_asplat_arg.txt b/test/yarp/snapshots/seattlerb/defn_arg_asplat_arg.txt index 6e7e9478f14181..9f1f7980e8f426 100644 --- a/test/yarp/snapshots/seattlerb/defn_arg_asplat_arg.txt +++ b/test/yarp/snapshots/seattlerb/defn_arg_asplat_arg.txt @@ -8,7 +8,7 @@ ProgramNode(0...29)( [RequiredParameterNode(9...15)(:interp)], [], [RequiredParameterNode(20...24)(:args)], - RestParameterNode(17...18)((17...18), nil), + RestParameterNode(17...18)(nil, nil, (17...18)), [], nil, nil diff --git a/test/yarp/snapshots/seattlerb/defn_opt_splat_arg.txt b/test/yarp/snapshots/seattlerb/defn_opt_splat_arg.txt index cd181b55b3aa0a..5ce355141df37c 100644 --- a/test/yarp/snapshots/seattlerb/defn_opt_splat_arg.txt +++ b/test/yarp/snapshots/seattlerb/defn_opt_splat_arg.txt @@ -13,7 +13,7 @@ ProgramNode(0...24)( IntegerNode(11...12)() )], [RequiredParameterNode(18...19)(:c)], - RestParameterNode(14...16)((14...15), (15...16)), + RestParameterNode(14...16)(:b, (15...16), (14...15)), [], nil, nil diff --git a/test/yarp/snapshots/seattlerb/defn_splat_arg.txt b/test/yarp/snapshots/seattlerb/defn_splat_arg.txt index 0fb8bb01c157d9..63e8839a6c2ecc 100644 --- a/test/yarp/snapshots/seattlerb/defn_splat_arg.txt +++ b/test/yarp/snapshots/seattlerb/defn_splat_arg.txt @@ -8,7 +8,7 @@ ProgramNode(0...15)( [], [], [RequiredParameterNode(9...10)(:a)], - RestParameterNode(6...7)((6...7), nil), + RestParameterNode(6...7)(nil, nil, (6...7)), [], nil, nil diff --git a/test/yarp/snapshots/seattlerb/difficult3_2.txt b/test/yarp/snapshots/seattlerb/difficult3_2.txt index 39819370668a22..fffcbac8be6349 100644 --- a/test/yarp/snapshots/seattlerb/difficult3_2.txt +++ b/test/yarp/snapshots/seattlerb/difficult3_2.txt @@ -15,7 +15,7 @@ ProgramNode(0...13)( [], [], [RequiredParameterNode(9...10)(:b)], - RestParameterNode(5...7)((5...6), (6...7)), + RestParameterNode(5...7)(:a, (6...7), (5...6)), [], nil, nil diff --git a/test/yarp/snapshots/seattlerb/difficult3_3.txt b/test/yarp/snapshots/seattlerb/difficult3_3.txt index 5b1e1ca29d00b1..700f53cb673a7c 100644 --- a/test/yarp/snapshots/seattlerb/difficult3_3.txt +++ b/test/yarp/snapshots/seattlerb/difficult3_3.txt @@ -15,7 +15,7 @@ ProgramNode(0...17)( [], [], [RequiredParameterNode(9...10)(:b)], - RestParameterNode(5...7)((5...6), (6...7)), + RestParameterNode(5...7)(:a, (6...7), (5...6)), [], nil, BlockParameterNode(12...14)(:c, (13...14), (12...13)) diff --git a/test/yarp/snapshots/seattlerb/iter_args_10_1.txt b/test/yarp/snapshots/seattlerb/iter_args_10_1.txt index 5da1b5260a54bc..3086873b0d2b40 100644 --- a/test/yarp/snapshots/seattlerb/iter_args_10_1.txt +++ b/test/yarp/snapshots/seattlerb/iter_args_10_1.txt @@ -20,7 +20,7 @@ ProgramNode(0...21)( IntegerNode(12...14)() )], [], - RestParameterNode(16...18)((16...17), (17...18)), + RestParameterNode(16...18)(:c, (17...18), (16...17)), [], nil, nil diff --git a/test/yarp/snapshots/seattlerb/iter_args_10_2.txt b/test/yarp/snapshots/seattlerb/iter_args_10_2.txt index f847bcc0317ea2..1b6efea49f6478 100644 --- a/test/yarp/snapshots/seattlerb/iter_args_10_2.txt +++ b/test/yarp/snapshots/seattlerb/iter_args_10_2.txt @@ -20,7 +20,7 @@ ProgramNode(0...25)( IntegerNode(12...14)() )], [], - RestParameterNode(16...18)((16...17), (17...18)), + RestParameterNode(16...18)(:c, (17...18), (16...17)), [], nil, BlockParameterNode(20...22)(:d, (21...22), (20...21)) diff --git a/test/yarp/snapshots/seattlerb/iter_args_11_1.txt b/test/yarp/snapshots/seattlerb/iter_args_11_1.txt index 83f48569dc8a91..4b2e76f11675d9 100644 --- a/test/yarp/snapshots/seattlerb/iter_args_11_1.txt +++ b/test/yarp/snapshots/seattlerb/iter_args_11_1.txt @@ -20,7 +20,7 @@ ProgramNode(0...24)( IntegerNode(12...14)() )], [RequiredParameterNode(20...21)(:d)], - RestParameterNode(16...18)((16...17), (17...18)), + RestParameterNode(16...18)(:c, (17...18), (16...17)), [], nil, nil diff --git a/test/yarp/snapshots/seattlerb/iter_args_11_2.txt b/test/yarp/snapshots/seattlerb/iter_args_11_2.txt index bfd864e20e2649..e9fa853130be83 100644 --- a/test/yarp/snapshots/seattlerb/iter_args_11_2.txt +++ b/test/yarp/snapshots/seattlerb/iter_args_11_2.txt @@ -20,7 +20,7 @@ ProgramNode(0...28)( IntegerNode(12...14)() )], [RequiredParameterNode(20...21)(:d)], - RestParameterNode(16...18)((16...17), (17...18)), + RestParameterNode(16...18)(:c, (17...18), (16...17)), [], nil, BlockParameterNode(23...25)(:e, (24...25), (23...24)) diff --git a/test/yarp/snapshots/seattlerb/iter_args_4.txt b/test/yarp/snapshots/seattlerb/iter_args_4.txt index eaa140a522d62c..18671a18327b21 100644 --- a/test/yarp/snapshots/seattlerb/iter_args_4.txt +++ b/test/yarp/snapshots/seattlerb/iter_args_4.txt @@ -15,7 +15,7 @@ ProgramNode(0...16)( [RequiredParameterNode(5...6)(:a)], [], [RequiredParameterNode(12...13)(:c)], - RestParameterNode(8...10)((8...9), (9...10)), + RestParameterNode(8...10)(:b, (9...10), (8...9)), [], nil, nil diff --git a/test/yarp/snapshots/seattlerb/iter_args_7_1.txt b/test/yarp/snapshots/seattlerb/iter_args_7_1.txt index ad285d8cadee8d..8bfb90fc33a3ce 100644 --- a/test/yarp/snapshots/seattlerb/iter_args_7_1.txt +++ b/test/yarp/snapshots/seattlerb/iter_args_7_1.txt @@ -20,7 +20,7 @@ ProgramNode(0...18)( IntegerNode(9...11)() )], [], - RestParameterNode(13...15)((13...14), (14...15)), + RestParameterNode(13...15)(:b, (14...15), (13...14)), [], nil, nil diff --git a/test/yarp/snapshots/seattlerb/iter_args_7_2.txt b/test/yarp/snapshots/seattlerb/iter_args_7_2.txt index 3ce974e279027f..21d217da226218 100644 --- a/test/yarp/snapshots/seattlerb/iter_args_7_2.txt +++ b/test/yarp/snapshots/seattlerb/iter_args_7_2.txt @@ -20,7 +20,7 @@ ProgramNode(0...22)( IntegerNode(9...11)() )], [], - RestParameterNode(13...15)((13...14), (14...15)), + RestParameterNode(13...15)(:b, (14...15), (13...14)), [], nil, BlockParameterNode(17...19)(:c, (18...19), (17...18)) diff --git a/test/yarp/snapshots/seattlerb/iter_args_8_1.txt b/test/yarp/snapshots/seattlerb/iter_args_8_1.txt index 1a4ed0f5994266..6b94b67e0e4ac4 100644 --- a/test/yarp/snapshots/seattlerb/iter_args_8_1.txt +++ b/test/yarp/snapshots/seattlerb/iter_args_8_1.txt @@ -20,7 +20,7 @@ ProgramNode(0...21)( IntegerNode(9...11)() )], [RequiredParameterNode(17...18)(:c)], - RestParameterNode(13...15)((13...14), (14...15)), + RestParameterNode(13...15)(:b, (14...15), (13...14)), [], nil, nil diff --git a/test/yarp/snapshots/seattlerb/iter_args_8_2.txt b/test/yarp/snapshots/seattlerb/iter_args_8_2.txt index 8b2b3f2b85c46e..f16d2fca9a5af9 100644 --- a/test/yarp/snapshots/seattlerb/iter_args_8_2.txt +++ b/test/yarp/snapshots/seattlerb/iter_args_8_2.txt @@ -20,7 +20,7 @@ ProgramNode(0...25)( IntegerNode(9...11)() )], [RequiredParameterNode(17...18)(:c)], - RestParameterNode(13...15)((13...14), (14...15)), + RestParameterNode(13...15)(:b, (14...15), (13...14)), [], nil, BlockParameterNode(20...22)(:d, (21...22), (20...21)) diff --git a/test/yarp/snapshots/seattlerb/stabby_arg_opt_splat_arg_block_omfg.txt b/test/yarp/snapshots/seattlerb/stabby_arg_opt_splat_arg_block_omfg.txt index 4b16ebf090eb02..fa7b9fe5a4f165 100644 --- a/test/yarp/snapshots/seattlerb/stabby_arg_opt_splat_arg_block_omfg.txt +++ b/test/yarp/snapshots/seattlerb/stabby_arg_opt_splat_arg_block_omfg.txt @@ -16,7 +16,7 @@ ProgramNode(0...23)( IntegerNode(8...9)() )], [RequiredParameterNode(15...16)(:e)], - RestParameterNode(11...13)((11...12), (12...13)), + RestParameterNode(11...13)(:d, (12...13), (11...12)), [], nil, BlockParameterNode(18...20)(:f, (19...20), (18...19)) diff --git a/test/yarp/snapshots/unparser/corpus/literal/block.txt b/test/yarp/snapshots/unparser/corpus/literal/block.txt index 514ce627600655..43a1ead2e80f9e 100644 --- a/test/yarp/snapshots/unparser/corpus/literal/block.txt +++ b/test/yarp/snapshots/unparser/corpus/literal/block.txt @@ -56,7 +56,7 @@ ProgramNode(0...737)( [RequiredParameterNode(27...28)(:a)], [], [], - RestParameterNode(28...29)((28...29), nil), + RestParameterNode(28...29)(nil, nil, (28...29)), [], nil, nil @@ -86,7 +86,7 @@ ProgramNode(0...737)( [RequiredParameterNode(40...41)(:a)], [], [], - RestParameterNode(41...42)((41...42), nil), + RestParameterNode(41...42)(nil, nil, (41...42)), [], nil, nil @@ -164,7 +164,7 @@ ProgramNode(0...737)( [RequiredParameterNode(88...89)(:a)], [], [], - RestParameterNode(91...93)((91...92), (92...93)), + RestParameterNode(91...93)(:b, (92...93), (91...92)), [], nil, nil @@ -194,7 +194,7 @@ ProgramNode(0...737)( [RequiredParameterNode(110...111)(:a)], [], [], - RestParameterNode(113...114)((113...114), nil), + RestParameterNode(113...114)(nil, nil, (113...114)), [], nil, nil @@ -321,7 +321,7 @@ ProgramNode(0...737)( [], [], [], - RestParameterNode(177...179)((177...178), (178...179)), + RestParameterNode(177...179)(:a, (178...179), (177...178)), [], nil, nil @@ -434,7 +434,7 @@ ProgramNode(0...737)( [], [], [], - RestParameterNode(237...238)((237...238), nil), + RestParameterNode(237...238)(nil, nil, (237...238)), [], nil, nil diff --git a/test/yarp/snapshots/unparser/corpus/literal/def.txt b/test/yarp/snapshots/unparser/corpus/literal/def.txt index d4def391b701ef..d78d9623bac9ce 100644 --- a/test/yarp/snapshots/unparser/corpus/literal/def.txt +++ b/test/yarp/snapshots/unparser/corpus/literal/def.txt @@ -663,7 +663,7 @@ ProgramNode(0...913)( [], [], [], - RestParameterNode(528...529)((528...529), nil), + RestParameterNode(528...529)(nil, nil, (528...529)), [], nil, nil @@ -696,7 +696,7 @@ ProgramNode(0...913)( [], [], [], - RestParameterNode(550...554)((550...551), (551...554)), + RestParameterNode(550...554)(:bar, (551...554), (550...551)), [], nil, nil @@ -717,7 +717,7 @@ ProgramNode(0...913)( [RequiredParameterNode(575...578)(:bar)], [], [], - RestParameterNode(580...584)((580...581), (581...584)), + RestParameterNode(580...584)(:baz, (581...584), (580...581)), [], nil, nil @@ -743,7 +743,7 @@ ProgramNode(0...913)( TrueNode(611...615)() )], [], - RestParameterNode(617...621)((617...618), (618...621)), + RestParameterNode(617...621)(:bor, (618...621), (617...618)), [], nil, nil @@ -781,7 +781,7 @@ ProgramNode(0...913)( TrueNode(648...652)() )], [], - RestParameterNode(654...658)((654...655), (655...658)), + RestParameterNode(654...658)(:bor, (655...658), (654...655)), [], nil, BlockParameterNode(660...666)(:block, (661...666), (660...661)) @@ -819,7 +819,7 @@ ProgramNode(0...913)( TrueNode(698...702)() )], [], - RestParameterNode(704...708)((704...705), (705...708)), + RestParameterNode(704...708)(:bor, (705...708), (704...705)), [], nil, nil diff --git a/test/yarp/snapshots/unparser/corpus/literal/since/32.txt b/test/yarp/snapshots/unparser/corpus/literal/since/32.txt index fd07f07237685a..eeae33beb74905 100644 --- a/test/yarp/snapshots/unparser/corpus/literal/since/32.txt +++ b/test/yarp/snapshots/unparser/corpus/literal/since/32.txt @@ -46,7 +46,7 @@ ProgramNode(0...90)( [RequiredParameterNode(55...63)(:argument)], [], [], - RestParameterNode(65...66)((65...66), nil), + RestParameterNode(65...66)(nil, nil, (65...66)), [], nil, nil diff --git a/test/yarp/snapshots/whitequark/args.txt b/test/yarp/snapshots/whitequark/args.txt index 12d18fdaffe4d2..21764cccc2678c 100644 --- a/test/yarp/snapshots/whitequark/args.txt +++ b/test/yarp/snapshots/whitequark/args.txt @@ -380,7 +380,7 @@ ProgramNode(0...690)( [], [], [], - RestParameterNode(322...323)((322...323), nil), + RestParameterNode(322...323)(nil, nil, (322...323)), [], KeywordRestParameterNode(325...327)(nil, nil, (325...327)), nil @@ -401,7 +401,7 @@ ProgramNode(0...690)( [], [], [], - RestParameterNode(340...342)((340...341), (341...342)), + RestParameterNode(340...342)(:r, (341...342), (340...341)), [], nil, BlockParameterNode(344...346)(:b, (345...346), (344...345)) @@ -422,7 +422,7 @@ ProgramNode(0...690)( [], [], [RequiredParameterNode(363...364)(:p)], - RestParameterNode(359...361)((359...360), (360...361)), + RestParameterNode(359...361)(:r, (360...361), (359...360)), [], nil, BlockParameterNode(366...368)(:b, (367...368), (366...367)) @@ -477,7 +477,7 @@ ProgramNode(0...690)( [RequiredParameterNode(412...413)(:a)], [], [], - RestParameterNode(415...417)((415...416), (416...417)), + RestParameterNode(415...417)(:r, (416...417), (415...416)), [], nil, BlockParameterNode(419...421)(:b, (420...421), (419...420)) @@ -498,7 +498,7 @@ ProgramNode(0...690)( [RequiredParameterNode(434...435)(:a)], [], [RequiredParameterNode(441...442)(:p)], - RestParameterNode(437...439)((437...438), (438...439)), + RestParameterNode(437...439)(:r, (438...439), (437...438)), [], nil, BlockParameterNode(444...446)(:b, (445...446), (444...445)) @@ -550,7 +550,7 @@ ProgramNode(0...690)( IntegerNode(487...488)() )], [], - RestParameterNode(490...492)((490...491), (491...492)), + RestParameterNode(490...492)(:r, (491...492), (490...491)), [], nil, BlockParameterNode(494...496)(:b, (495...496), (494...495)) @@ -576,7 +576,7 @@ ProgramNode(0...690)( IntegerNode(514...515)() )], [RequiredParameterNode(521...522)(:p)], - RestParameterNode(517...519)((517...518), (518...519)), + RestParameterNode(517...519)(:r, (518...519), (517...518)), [], nil, BlockParameterNode(524...526)(:b, (525...526), (524...525)) @@ -700,7 +700,7 @@ ProgramNode(0...690)( IntegerNode(626...627)() )], [], - RestParameterNode(629...631)((629...630), (630...631)), + RestParameterNode(629...631)(:r, (630...631), (629...630)), [], nil, BlockParameterNode(633...635)(:b, (634...635), (633...634)) @@ -726,7 +726,7 @@ ProgramNode(0...690)( IntegerNode(650...651)() )], [RequiredParameterNode(657...658)(:p)], - RestParameterNode(653...655)((653...654), (654...655)), + RestParameterNode(653...655)(:r, (654...655), (653...654)), [], nil, BlockParameterNode(660...662)(:b, (661...662), (660...661)) diff --git a/test/yarp/snapshots/whitequark/blockargs.txt b/test/yarp/snapshots/whitequark/blockargs.txt index 4c51e4e1a8dfd4..dd0b942a291c63 100644 --- a/test/yarp/snapshots/whitequark/blockargs.txt +++ b/test/yarp/snapshots/whitequark/blockargs.txt @@ -103,7 +103,7 @@ ProgramNode(0...550)( [], [], [], - RestParameterNode(50...51)((50...51), nil), + RestParameterNode(50...51)(nil, nil, (50...51)), [], nil, BlockParameterNode(53...55)(:b, (54...55), (53...54)) @@ -133,7 +133,7 @@ ProgramNode(0...550)( [], [], [RequiredParameterNode(68...69)(:p)], - RestParameterNode(64...66)((64...65), (65...66)), + RestParameterNode(64...66)(:r, (65...66), (64...65)), [], nil, BlockParameterNode(71...73)(:b, (72...73), (71...72)) @@ -163,7 +163,7 @@ ProgramNode(0...550)( [], [], [], - RestParameterNode(82...84)((82...83), (83...84)), + RestParameterNode(82...84)(:s, (83...84), (82...83)), [], nil, BlockParameterNode(86...88)(:b, (87...88), (86...87)) @@ -193,7 +193,7 @@ ProgramNode(0...550)( [], [], [], - RestParameterNode(97...99)((97...98), (98...99)), + RestParameterNode(97...99)(:s, (98...99), (97...98)), [], nil, nil @@ -223,7 +223,7 @@ ProgramNode(0...550)( [], [], [], - RestParameterNode(108...109)((108...109), nil), + RestParameterNode(108...109)(nil, nil, (108...109)), [], nil, nil @@ -327,7 +327,7 @@ ProgramNode(0...550)( [RequiredParameterNode(156...157)(:a)], [], [], - RestParameterNode(159...160)((159...160), nil), + RestParameterNode(159...160)(nil, nil, (159...160)), [], nil, BlockParameterNode(162...164)(:b, (163...164), (162...163)) @@ -357,7 +357,7 @@ ProgramNode(0...550)( [RequiredParameterNode(173...174)(:a)], [], [RequiredParameterNode(180...181)(:p)], - RestParameterNode(176...178)((176...177), (177...178)), + RestParameterNode(176...178)(:r, (177...178), (176...177)), [], nil, BlockParameterNode(183...185)(:b, (184...185), (183...184)) @@ -387,7 +387,7 @@ ProgramNode(0...550)( [RequiredParameterNode(194...195)(:a)], [], [], - RestParameterNode(197...199)((197...198), (198...199)), + RestParameterNode(197...199)(:s, (198...199), (197...198)), [], nil, BlockParameterNode(201...203)(:b, (202...203), (201...202)) @@ -417,7 +417,7 @@ ProgramNode(0...550)( [RequiredParameterNode(212...213)(:a)], [], [], - RestParameterNode(215...217)((215...216), (216...217)), + RestParameterNode(215...217)(:s, (216...217), (215...216)), [], nil, nil @@ -447,7 +447,7 @@ ProgramNode(0...550)( [RequiredParameterNode(226...227)(:a)], [], [], - RestParameterNode(229...230)((229...230), nil), + RestParameterNode(229...230)(nil, nil, (229...230)), [], nil, nil @@ -478,7 +478,7 @@ ProgramNode(0...550)( RequiredParameterNode(242...243)(:b)], [], [], - RestParameterNode(243...244)((243...244), nil), + RestParameterNode(243...244)(nil, nil, (243...244)), [], nil, nil @@ -579,7 +579,7 @@ ProgramNode(0...550)( IntegerNode(290...291)() )], [RequiredParameterNode(297...298)(:p)], - RestParameterNode(293...295)((293...294), (294...295)), + RestParameterNode(293...295)(:r, (294...295), (293...294)), [], nil, BlockParameterNode(300...302)(:b, (301...302), (300...301)) @@ -620,7 +620,7 @@ ProgramNode(0...550)( IntegerNode(322...323)() )], [], - RestParameterNode(325...327)((325...326), (326...327)), + RestParameterNode(325...327)(:r, (326...327), (325...326)), [], nil, BlockParameterNode(329...331)(:b, (330...331), (329...330)) @@ -685,7 +685,7 @@ ProgramNode(0...550)( [RequiredParameterNode(362...363)(:a)], [], [], - RestParameterNode(363...364)((363...364), nil), + RestParameterNode(363...364)(nil, nil, (363...364)), [], nil, nil @@ -952,7 +952,7 @@ ProgramNode(0...550)( IntegerNode(487...488)() )], [], - RestParameterNode(490...492)((490...491), (491...492)), + RestParameterNode(490...492)(:r, (491...492), (490...491)), [], nil, BlockParameterNode(494...496)(:b, (495...496), (494...495)) @@ -987,7 +987,7 @@ ProgramNode(0...550)( IntegerNode(507...508)() )], [RequiredParameterNode(514...515)(:p)], - RestParameterNode(510...512)((510...511), (511...512)), + RestParameterNode(510...512)(:r, (511...512), (510...511)), [], nil, BlockParameterNode(517...519)(:b, (518...519), (517...518)) diff --git a/test/yarp/snapshots/whitequark/forwarded_argument_with_restarg.txt b/test/yarp/snapshots/whitequark/forwarded_argument_with_restarg.txt index ff0602c3982005..d2ef1999333a95 100644 --- a/test/yarp/snapshots/whitequark/forwarded_argument_with_restarg.txt +++ b/test/yarp/snapshots/whitequark/forwarded_argument_with_restarg.txt @@ -8,7 +8,7 @@ ProgramNode(0...43)( [RequiredParameterNode(8...16)(:argument)], [], [], - RestParameterNode(18...19)((18...19), nil), + RestParameterNode(18...19)(nil, nil, (18...19)), [], nil, nil diff --git a/test/yarp/snapshots/whitequark/forwarded_restarg.txt b/test/yarp/snapshots/whitequark/forwarded_restarg.txt index d45b60fc0a348b..485032d487d2fd 100644 --- a/test/yarp/snapshots/whitequark/forwarded_restarg.txt +++ b/test/yarp/snapshots/whitequark/forwarded_restarg.txt @@ -8,7 +8,7 @@ ProgramNode(0...23)( [], [], [], - RestParameterNode(8...9)((8...9), nil), + RestParameterNode(8...9)(nil, nil, (8...9)), [], nil, nil diff --git a/test/yarp/snapshots/whitequark/parser_bug_507.txt b/test/yarp/snapshots/whitequark/parser_bug_507.txt index f305b7daeab39a..07e5d8ed602b2a 100644 --- a/test/yarp/snapshots/whitequark/parser_bug_507.txt +++ b/test/yarp/snapshots/whitequark/parser_bug_507.txt @@ -15,7 +15,7 @@ ProgramNode(0...19)( [], [], [], - RestParameterNode(7...12)((7...8), (8...12)), + RestParameterNode(7...12)(:args, (8...12), (7...8)), [], nil, nil diff --git a/test/yarp/snapshots/whitequark/restarg_named.txt b/test/yarp/snapshots/whitequark/restarg_named.txt index ce26b2fc67a590..9883a44ed6ac67 100644 --- a/test/yarp/snapshots/whitequark/restarg_named.txt +++ b/test/yarp/snapshots/whitequark/restarg_named.txt @@ -8,7 +8,7 @@ ProgramNode(0...16)( [], [], [], - RestParameterNode(6...10)((6...7), (7...10)), + RestParameterNode(6...10)(:foo, (7...10), (6...7)), [], nil, nil diff --git a/test/yarp/snapshots/whitequark/restarg_unnamed.txt b/test/yarp/snapshots/whitequark/restarg_unnamed.txt index b6778e293ceba5..8f282e126a07a7 100644 --- a/test/yarp/snapshots/whitequark/restarg_unnamed.txt +++ b/test/yarp/snapshots/whitequark/restarg_unnamed.txt @@ -8,7 +8,7 @@ ProgramNode(0...13)( [], [], [], - RestParameterNode(6...7)((6...7), nil), + RestParameterNode(6...7)(nil, nil, (6...7)), [], nil, nil diff --git a/test/yarp/snapshots/whitequark/send_lambda.txt b/test/yarp/snapshots/whitequark/send_lambda.txt index c30ec09249f4e6..52d1fb26a5454a 100644 --- a/test/yarp/snapshots/whitequark/send_lambda.txt +++ b/test/yarp/snapshots/whitequark/send_lambda.txt @@ -11,7 +11,7 @@ ProgramNode(0...26)( [], [], [], - RestParameterNode(3...4)((3...4), nil), + RestParameterNode(3...4)(nil, nil, (3...4)), [], nil, nil diff --git a/yarp/config.yml b/yarp/config.yml index b24490a3332012..f62b591d4fb4c4 100644 --- a/yarp/config.yml +++ b/yarp/config.yml @@ -2059,10 +2059,12 @@ nodes: `ex` is in the `exception` field. - name: RestParameterNode fields: - - name: operator_loc - type: location + - name: name + type: constant? - name: name_loc type: location? + - name: operator_loc + type: location comment: | Represents a rest parameter to a method, block, or lambda definition. diff --git a/yarp/yarp.c b/yarp/yarp.c index 7f9f3b5589f597..c7c43e14bb939c 100644 --- a/yarp/yarp.c +++ b/yarp/yarp.c @@ -3900,8 +3900,9 @@ yp_rest_parameter_node_create(yp_parser_t *parser, const yp_token_t *operator, c .end = (name->type == YP_TOKEN_NOT_PROVIDED ? operator->end : name->end) } }, - .operator_loc = YP_LOCATION_TOKEN_VALUE(operator), - .name_loc = YP_OPTIONAL_LOCATION_TOKEN_VALUE(name) + .name = yp_parser_optional_constant_id_token(parser, name), + .name_loc = YP_OPTIONAL_LOCATION_TOKEN_VALUE(name), + .operator_loc = YP_LOCATION_TOKEN_VALUE(operator) }; return node; From 14970cfc8d4ae68d173a2df45abecc4c41220270 Mon Sep 17 00:00:00 2001 From: Kevin Newton Date: Wed, 6 Sep 2023 11:27:00 -0400 Subject: [PATCH 14/46] [ruby/yarp] Constants and def nodes https://github.com/ruby/yarp/commit/6b2421ce1b --- test/yarp/errors_test.rb | 22 ++++++++ test/yarp/snapshots/endless_methods.txt | 3 + test/yarp/snapshots/indented_file_end.txt | 1 + test/yarp/snapshots/keyword_method_names.txt | 8 +++ test/yarp/snapshots/methods.txt | 56 +++++++++++++++++++ .../snapshots/non_alphanumeric_methods.txt | 35 ++++++++++++ test/yarp/snapshots/rescue.txt | 2 + .../seattlerb/TestRubyParserShared.txt | 2 + .../snapshots/seattlerb/args_kw_block.txt | 1 + .../snapshots/seattlerb/block_arg__bare.txt | 1 + .../block_call_defn_call_block_call.txt | 1 + test/yarp/snapshots/seattlerb/bug_187.txt | 1 + test/yarp/snapshots/seattlerb/bug_249.txt | 1 + .../seattlerb/bug_call_arglist_parens.txt | 2 + .../snapshots/seattlerb/class_comments.txt | 1 + .../seattlerb/defn_arg_asplat_arg.txt | 1 + .../seattlerb/defn_arg_forward_args.txt | 1 + .../seattlerb/defn_args_forward_args.txt | 1 + .../snapshots/seattlerb/defn_comments.txt | 1 + .../seattlerb/defn_endless_command.txt | 1 + .../seattlerb/defn_endless_command_rescue.txt | 1 + .../snapshots/seattlerb/defn_forward_args.txt | 1 + .../defn_forward_args__no_parens.txt | 1 + .../snapshots/seattlerb/defn_kwarg_env.txt | 1 + .../snapshots/seattlerb/defn_kwarg_kwarg.txt | 1 + .../seattlerb/defn_kwarg_kwsplat.txt | 1 + .../seattlerb/defn_kwarg_kwsplat_anon.txt | 1 + .../snapshots/seattlerb/defn_kwarg_lvar.txt | 1 + .../seattlerb/defn_kwarg_no_parens.txt | 1 + .../snapshots/seattlerb/defn_kwarg_val.txt | 1 + .../snapshots/seattlerb/defn_no_kwargs.txt | 1 + .../snapshots/seattlerb/defn_oneliner.txt | 1 + .../snapshots/seattlerb/defn_oneliner_eq2.txt | 1 + .../seattlerb/defn_oneliner_noargs.txt | 1 + .../defn_oneliner_noargs_parentheses.txt | 1 + .../seattlerb/defn_oneliner_rescue.txt | 3 + .../snapshots/seattlerb/defn_opt_last_arg.txt | 1 + .../yarp/snapshots/seattlerb/defn_opt_reg.txt | 1 + .../seattlerb/defn_opt_splat_arg.txt | 1 + test/yarp/snapshots/seattlerb/defn_powarg.txt | 1 + .../snapshots/seattlerb/defn_reg_opt_reg.txt | 1 + .../snapshots/seattlerb/defn_splat_arg.txt | 1 + .../snapshots/seattlerb/defn_unary_not.txt | 1 + .../snapshots/seattlerb/defns_reserved.txt | 1 + .../defs_as_arg_with_do_block_inside.txt | 1 + .../snapshots/seattlerb/defs_comments.txt | 1 + .../seattlerb/defs_endless_command.txt | 1 + .../seattlerb/defs_endless_command_rescue.txt | 1 + test/yarp/snapshots/seattlerb/defs_kwarg.txt | 1 + .../snapshots/seattlerb/defs_oneliner.txt | 1 + .../snapshots/seattlerb/defs_oneliner_eq2.txt | 1 + .../seattlerb/defs_oneliner_rescue.txt | 3 + test/yarp/snapshots/seattlerb/f_kw.txt | 1 + .../snapshots/seattlerb/f_kw__required.txt | 1 + .../seattlerb/magic_encoding_comment.txt | 1 + .../snapshots/seattlerb/module_comments.txt | 1 + .../seattlerb/parse_def_special_name.txt | 1 + .../seattlerb/parse_line_defn_complex.txt | 1 + .../seattlerb/parse_line_defn_no_parens.txt | 2 + .../parse_line_defn_no_parens_args.txt | 1 + .../snapshots/seattlerb/parse_line_return.txt | 1 + .../seattlerb/required_kwarg_no_value.txt | 1 + .../unparser/corpus/literal/class.txt | 1 + .../snapshots/unparser/corpus/literal/def.txt | 30 ++++++++++ .../unparser/corpus/literal/defs.txt | 10 ++++ .../unparser/corpus/literal/module.txt | 1 + .../unparser/corpus/literal/send.txt | 3 + .../unparser/corpus/literal/since/31.txt | 2 + .../unparser/corpus/literal/since/32.txt | 2 + .../unparser/corpus/literal/while.txt | 1 + .../unparser/corpus/semantic/def.txt | 2 + test/yarp/snapshots/while.txt | 1 + .../whitequark/anonymous_blockarg.txt | 1 + test/yarp/snapshots/whitequark/arg.txt | 2 + .../whitequark/arg_duplicate_ignored.txt | 2 + test/yarp/snapshots/whitequark/arg_label.txt | 2 + test/yarp/snapshots/whitequark/args.txt | 31 ++++++++++ test/yarp/snapshots/whitequark/blockarg.txt | 1 + test/yarp/snapshots/whitequark/bug_481.txt | 1 + .../whitequark/bug_def_no_paren_eql_begin.txt | 1 + .../whitequark/bug_do_block_in_call_args.txt | 1 + .../snapshots/whitequark/const_op_asgn.txt | 2 + test/yarp/snapshots/whitequark/def.txt | 6 ++ test/yarp/snapshots/whitequark/defs.txt | 5 ++ .../whitequark/endless_comparison_method.txt | 6 ++ .../snapshots/whitequark/endless_method.txt | 4 ++ .../endless_method_command_syntax.txt | 8 +++ .../endless_method_forwarded_args_legacy.txt | 1 + .../endless_method_with_rescue_mod.txt | 2 + .../endless_method_without_args.txt | 4 ++ .../yarp/snapshots/whitequark/forward_arg.txt | 1 + .../whitequark/forward_arg_with_open_args.txt | 10 ++++ .../whitequark/forward_args_legacy.txt | 3 + .../forwarded_argument_with_kwrestarg.txt | 1 + .../forwarded_argument_with_restarg.txt | 1 + .../whitequark/forwarded_kwrestarg.txt | 1 + ...warded_kwrestarg_with_additional_kwarg.txt | 1 + .../whitequark/forwarded_restarg.txt | 1 + test/yarp/snapshots/whitequark/kwarg.txt | 1 + test/yarp/snapshots/whitequark/kwnilarg.txt | 1 + test/yarp/snapshots/whitequark/kwoptarg.txt | 1 + ...targ_with_kwrestarg_and_forwarded_args.txt | 1 + .../snapshots/whitequark/kwrestarg_named.txt | 1 + .../whitequark/kwrestarg_unnamed.txt | 1 + .../method_definition_in_while_cond.txt | 4 ++ .../whitequark/numparam_outside_block.txt | 1 + test/yarp/snapshots/whitequark/optarg.txt | 2 + .../snapshots/whitequark/parser_bug_490.txt | 3 + .../snapshots/whitequark/restarg_named.txt | 1 + .../snapshots/whitequark/restarg_unnamed.txt | 1 + .../snapshots/whitequark/ruby_bug_12073.txt | 1 + .../snapshots/whitequark/ruby_bug_9669.txt | 1 + .../whitequark/trailing_forward_arg.txt | 1 + .../yarp/snapshots/whitequark/var_op_asgn.txt | 1 + yarp/config.yml | 2 + yarp/yarp.c | 1 + 116 files changed, 366 insertions(+) diff --git a/test/yarp/errors_test.rb b/test/yarp/errors_test.rb index adaac44b353635..608af07795f7cc 100644 --- a/test/yarp/errors_test.rb +++ b/test/yarp/errors_test.rb @@ -390,6 +390,7 @@ def test_splat_argument_after_keyword_argument def test_module_definition_in_method_body expected = DefNode( + :foo, Location(), nil, nil, @@ -410,6 +411,7 @@ def test_module_definition_in_method_body def test_module_definition_in_method_body_within_block expected = DefNode( + :foo, Location(), nil, nil, @@ -452,6 +454,7 @@ module Foo;end def test_class_definition_in_method_body expected = DefNode( + :foo, Location(), nil, nil, @@ -483,6 +486,7 @@ def test_class_definition_in_method_body def test_bad_arguments expected = DefNode( + :foo, Location(), nil, ParametersNode([ @@ -550,6 +554,7 @@ def test_cannot_assign_to_a_reserved_numbered_parameter def test_do_not_allow_trailing_commas_in_method_parameters expected = DefNode( + :foo, Location(), nil, ParametersNode( @@ -633,6 +638,7 @@ def test_unterminated_unicode_brackets_should_be_a_syntax_error def test_method_parameters_after_block expected = DefNode( + :foo, Location(), nil, ParametersNode( @@ -660,6 +666,7 @@ def test_method_parameters_after_block def test_method_with_arguments_after_anonymous_block expected = DefNode( + :foo, Location(), nil, ParametersNode([], [], [RequiredParameterNode(:a)], nil, [], nil, BlockParameterNode(nil, nil, Location())), @@ -680,6 +687,7 @@ def test_method_with_arguments_after_anonymous_block def test_method_parameters_after_arguments_forwarding expected = DefNode( + :foo, Location(), nil, ParametersNode( @@ -707,6 +715,7 @@ def test_method_parameters_after_arguments_forwarding def test_keywords_parameters_before_required_parameters expected = DefNode( + :foo, Location(), nil, ParametersNode( @@ -734,6 +743,7 @@ def test_keywords_parameters_before_required_parameters def test_rest_keywords_parameters_before_required_parameters expected = DefNode( + :foo, Location(), nil, ParametersNode( @@ -754,6 +764,7 @@ def test_rest_keywords_parameters_before_required_parameters nil, Location() ) + assert_errors expected, "def foo(**rest, b:)\nend", [ ["Unexpected parameter order", 16..18] ] @@ -761,6 +772,7 @@ def test_rest_keywords_parameters_before_required_parameters def test_double_arguments_forwarding expected = DefNode( + :foo, Location(), nil, ParametersNode([], [], [], nil, [], ForwardingParameterNode(), nil), @@ -781,6 +793,7 @@ def test_double_arguments_forwarding def test_multiple_error_in_parameters_order expected = DefNode( + :foo, Location(), nil, ParametersNode( @@ -810,6 +823,7 @@ def test_multiple_error_in_parameters_order def test_switching_to_optional_arguments_twice expected = DefNode( + :foo, Location(), nil, ParametersNode( @@ -839,6 +853,7 @@ def test_switching_to_optional_arguments_twice def test_switching_to_named_arguments_twice expected = DefNode( + :foo, Location(), nil, ParametersNode( @@ -868,6 +883,7 @@ def test_switching_to_named_arguments_twice def test_returning_to_optional_parameters_multiple_times expected = DefNode( + :foo, Location(), nil, ParametersNode( @@ -913,6 +929,7 @@ def test_case_without_when_clauses_errors_on_else_clause def test_setter_method_cannot_be_defined_in_an_endless_method_definition expected = DefNode( + :a=, Location(), nil, nil, @@ -1026,6 +1043,7 @@ def test_duplicated_parameter_names # duplicated parameter names for positional parameters. unless RUBY_VERSION < "3.1.0" expected = DefNode( + :foo, Location(), nil, ParametersNode([RequiredParameterNode(:a), RequiredParameterNode(:b), RequiredParameterNode(:a)], [], [], nil, [], nil, nil), @@ -1045,6 +1063,7 @@ def test_duplicated_parameter_names end expected = DefNode( + :foo, Location(), nil, ParametersNode([RequiredParameterNode(:a), RequiredParameterNode(:b)], [], [], RestParameterNode(:a, Location(), Location()), [], nil, nil), @@ -1063,6 +1082,7 @@ def test_duplicated_parameter_names ] expected = DefNode( + :foo, Location(), nil, ParametersNode([RequiredParameterNode(:a), RequiredParameterNode(:b)], [], [], nil, [], KeywordRestParameterNode(:a, Location(), Location()), nil), @@ -1081,6 +1101,7 @@ def test_duplicated_parameter_names ] expected = DefNode( + :foo, Location(), nil, ParametersNode([RequiredParameterNode(:a), RequiredParameterNode(:b)], [], [], nil, [], nil, BlockParameterNode(:a, Location(), Location())), @@ -1099,6 +1120,7 @@ def test_duplicated_parameter_names ] expected = DefNode( + :foo, Location(), nil, ParametersNode([], [OptionalParameterNode(:a, Location(), Location(), IntegerNode())], [RequiredParameterNode(:b)], RestParameterNode(:c, Location(), Location()), [], nil, nil), diff --git a/test/yarp/snapshots/endless_methods.txt b/test/yarp/snapshots/endless_methods.txt index 2e67d9d76f58a0..61b7493847957d 100644 --- a/test/yarp/snapshots/endless_methods.txt +++ b/test/yarp/snapshots/endless_methods.txt @@ -2,6 +2,7 @@ ProgramNode(0...51)( [], StatementsNode(0...51)( [DefNode(0...11)( + :foo, (4...7), nil, nil, @@ -15,6 +16,7 @@ ProgramNode(0...51)( nil ), DefNode(13...27)( + :bar, (17...20), nil, nil, @@ -42,6 +44,7 @@ ProgramNode(0...51)( nil ), DefNode(29...51)( + :method, (33...39), nil, nil, diff --git a/test/yarp/snapshots/indented_file_end.txt b/test/yarp/snapshots/indented_file_end.txt index 513a7ab0f5ba48..bcdfba7302d90f 100644 --- a/test/yarp/snapshots/indented_file_end.txt +++ b/test/yarp/snapshots/indented_file_end.txt @@ -2,6 +2,7 @@ ProgramNode(4...23)( [], StatementsNode(4...23)( [DefNode(4...23)( + :hi, (8...10), nil, nil, diff --git a/test/yarp/snapshots/keyword_method_names.txt b/test/yarp/snapshots/keyword_method_names.txt index 37fc09d0affd6e..293164bb1e8371 100644 --- a/test/yarp/snapshots/keyword_method_names.txt +++ b/test/yarp/snapshots/keyword_method_names.txt @@ -2,6 +2,7 @@ ProgramNode(0...185)( [], StatementsNode(0...185)( [DefNode(0...11)( + :def, (4...7), nil, nil, @@ -15,6 +16,7 @@ ProgramNode(0...185)( (8...11) ), DefNode(13...32)( + :ensure, (22...28), SelfNode(17...21)(), nil, @@ -34,6 +36,7 @@ ProgramNode(0...185)( nil, ArgumentsNode(42...68)( [DefNode(42...68)( + :foo, (46...49), nil, nil, @@ -65,6 +68,7 @@ ProgramNode(0...185)( "private" ), DefNode(70...89)( + :m, (74...75), nil, ParametersNode(76...84)( @@ -86,6 +90,7 @@ ProgramNode(0...185)( (86...89) ), DefNode(91...113)( + :a, (108...109), SourceEncodingNode(95...107)(), nil, @@ -101,6 +106,7 @@ ProgramNode(0...185)( StringNode(115...121)((115...117), (117...120), (120...121), "abc"), StringNode(123...129)((123...125), (125...128), (128...129), "abc"), DefNode(131...149)( + :a, (144...145), SourceFileNode(135...143)("keyword_method_names.txt"), nil, @@ -114,6 +120,7 @@ ProgramNode(0...185)( (146...149) ), DefNode(151...169)( + :a, (164...165), SourceLineNode(155...163)(), nil, @@ -127,6 +134,7 @@ ProgramNode(0...185)( (166...169) ), DefNode(171...185)( + :a, (180...181), NilNode(175...178)(), nil, diff --git a/test/yarp/snapshots/methods.txt b/test/yarp/snapshots/methods.txt index 72fb1a704a26b1..3b0b5ca29997b4 100644 --- a/test/yarp/snapshots/methods.txt +++ b/test/yarp/snapshots/methods.txt @@ -2,6 +2,7 @@ ProgramNode(0...1194)( [:a, :c], StatementsNode(0...1194)( [DefNode(0...23)( + :foo, (4...7), nil, ParametersNode(8...18)( @@ -28,6 +29,7 @@ ProgramNode(0...1194)( (20...23) ), DefNode(25...74)( + :foo, (29...32), nil, ParametersNode(33...69)( @@ -64,6 +66,7 @@ ProgramNode(0...1194)( (71...74) ), DefNode(77...95)( + :a, (81...82), nil, nil, @@ -84,6 +87,7 @@ ProgramNode(0...1194)( (92...95) ), DefNode(97...110)( + :a, (105...106), ParenthesesNode(101...104)( CallNode(102...103)( @@ -111,6 +115,7 @@ ProgramNode(0...1194)( (107...110) ), DefNode(112...126)( + :b, (121...122), ParenthesesNode(116...119)( CallNode(117...118)( @@ -138,6 +143,7 @@ ProgramNode(0...1194)( (123...126) ), DefNode(128...143)( + :a, (138...139), FalseNode(132...137)(), nil, @@ -151,6 +157,7 @@ ProgramNode(0...1194)( (140...143) ), DefNode(145...159)( + :a, (149...150), nil, ParametersNode(151...154)( @@ -172,6 +179,7 @@ ProgramNode(0...1194)( (156...159) ), DefNode(161...175)( + :a, (170...171), GlobalVariableReadNode(165...169)(:$var), nil, @@ -185,6 +193,7 @@ ProgramNode(0...1194)( (172...175) ), DefNode(177...188)( + :b, (183...184), CallNode(181...182)(nil, nil, (181...182), nil, nil, nil, nil, 2, "a"), nil, @@ -198,6 +207,7 @@ ProgramNode(0...1194)( (185...188) ), DefNode(190...204)( + :a, (199...200), InstanceVariableReadNode(194...198)(:@var), nil, @@ -211,6 +221,7 @@ ProgramNode(0...1194)( (201...204) ), DefNode(206...219)( + :a, (210...211), nil, ParametersNode(212...214)( @@ -233,6 +244,7 @@ ProgramNode(0...1194)( ), StringNode(221...227)((221...223), (223...226), (226...227), "abc"), DefNode(229...242)( + :a, (233...234), nil, ParametersNode(235...237)( @@ -254,6 +266,7 @@ ProgramNode(0...1194)( (239...242) ), DefNode(244...258)( + :a, (248...249), nil, ParametersNode(250...253)( @@ -275,6 +288,7 @@ ProgramNode(0...1194)( (255...258) ), DefNode(260...273)( + :a, (264...265), nil, ParametersNode(266...268)( @@ -303,6 +317,7 @@ ProgramNode(0...1194)( (277...278) ), DefNode(282...291)( + :a, (286...287), nil, nil, @@ -316,6 +331,7 @@ ProgramNode(0...1194)( (288...291) ), DefNode(293...310)( + :a, (297...298), nil, ParametersNode(299...306)( @@ -339,6 +355,7 @@ ProgramNode(0...1194)( (307...310) ), DefNode(312...325)( + :a, (320...321), NilNode(316...319)(), nil, @@ -352,6 +369,7 @@ ProgramNode(0...1194)( (322...325) ), DefNode(327...345)( + :a, (331...332), nil, ParametersNode(333...341)( @@ -378,6 +396,7 @@ ProgramNode(0...1194)( (342...345) ), DefNode(347...366)( + :a, (351...352), nil, ParametersNode(353...361)( @@ -404,6 +423,7 @@ ProgramNode(0...1194)( (363...366) ), DefNode(368...389)( + :a, (372...373), nil, ParametersNode(374...384)( @@ -431,6 +451,7 @@ ProgramNode(0...1194)( ), StringNode(391...397)((391...393), (393...396), (396...397), "abc"), DefNode(399...421)( + :a, (403...404), nil, ParametersNode(405...417)( @@ -463,6 +484,7 @@ ProgramNode(0...1194)( (418...421) ), DefNode(423...434)( + :a, (427...428), nil, nil, @@ -476,6 +498,7 @@ ProgramNode(0...1194)( (431...434) ), DefNode(436...454)( + :a, (440...441), nil, ParametersNode(442...450)( @@ -502,6 +525,7 @@ ProgramNode(0...1194)( (451...454) ), DefNode(456...467)( + :a, (460...461), nil, ParametersNode(462...463)( @@ -523,6 +547,7 @@ ProgramNode(0...1194)( (464...467) ), DefNode(469...501)( + :a, (473...474), nil, nil, @@ -543,6 +568,7 @@ ProgramNode(0...1194)( (498...501) ), DefNode(503...515)( + :a, (507...508), nil, ParametersNode(509...511)( @@ -564,6 +590,7 @@ ProgramNode(0...1194)( (512...515) ), DefNode(517...529)( + :a, (521...522), nil, ParametersNode(523...524)( @@ -585,6 +612,7 @@ ProgramNode(0...1194)( (526...529) ), DefNode(531...546)( + :a, (535...536), nil, nil, @@ -606,6 +634,7 @@ ProgramNode(0...1194)( (543...546) ), DefNode(548...562)( + :a, (557...558), SelfNode(552...556)(), nil, @@ -619,6 +648,7 @@ ProgramNode(0...1194)( (559...562) ), DefNode(564...578)( + :a, (573...574), TrueNode(568...572)(), nil, @@ -632,6 +662,7 @@ ProgramNode(0...1194)( (575...578) ), DefNode(580...589)( + :a, (584...585), nil, nil, @@ -645,6 +676,7 @@ ProgramNode(0...1194)( (586...589) ), DefNode(591...625)( + :hi, (595...597), nil, nil, @@ -674,6 +706,7 @@ ProgramNode(0...1194)( (622...625) ), DefNode(627...638)( + :foo, (631...634), nil, nil, @@ -687,6 +720,7 @@ ProgramNode(0...1194)( nil ), DefNode(639...650)( + :bar, (643...646), nil, nil, @@ -700,6 +734,7 @@ ProgramNode(0...1194)( nil ), DefNode(652...670)( + :foo, (656...659), nil, ParametersNode(660...663)( @@ -721,6 +756,7 @@ ProgramNode(0...1194)( nil ), DefNode(672...685)( + :foo, (676...679), nil, nil, @@ -734,6 +770,7 @@ ProgramNode(0...1194)( nil ), DefNode(687...706)( + :a, (691...692), nil, ParametersNode(693...694)( @@ -767,6 +804,7 @@ ProgramNode(0...1194)( (703...706) ), DefNode(708...731)( + :a, (712...713), nil, ParametersNode(714...717)( @@ -800,6 +838,7 @@ ProgramNode(0...1194)( (728...731) ), DefNode(733...762)( + :a, (737...738), nil, ParametersNode(739...742)( @@ -837,6 +876,7 @@ ProgramNode(0...1194)( (759...762) ), DefNode(764...781)( + :a, (776...777), ParenthesesNode(768...775)( LocalVariableWriteNode(769...774)( @@ -870,6 +910,7 @@ ProgramNode(0...1194)( (778...781) ), DefNode(783...795)( + :a, (787...788), nil, ParametersNode(789...791)( @@ -891,6 +932,7 @@ ProgramNode(0...1194)( (792...795) ), DefNode(797...809)( + :a, (801...802), nil, ParametersNode(803...804)( @@ -912,6 +954,7 @@ ProgramNode(0...1194)( (806...809) ), DefNode(811...826)( + :a, (821...822), ClassVariableReadNode(815...820)(:@@var), nil, @@ -925,6 +968,7 @@ ProgramNode(0...1194)( (823...826) ), DefNode(828...845)( + :C, (840...841), ParenthesesNode(832...839)( LocalVariableWriteNode(833...838)( @@ -958,6 +1002,7 @@ ProgramNode(0...1194)( (842...845) ), DefNode(847...875)( + :Array_function, (856...870), SelfNode(851...855)(), nil, @@ -977,6 +1022,7 @@ ProgramNode(0...1194)( (883...884) ), DefNode(888...903)( + :a, (898...899), ConstantReadNode(892...897)(:Const), nil, @@ -990,6 +1036,7 @@ ProgramNode(0...1194)( (900...903) ), DefNode(905...936)( + :a, (909...910), nil, ParametersNode(911...914)( @@ -1036,6 +1083,7 @@ ProgramNode(0...1194)( (933...936) ), DefNode(938...980)( + :foo, (942...945), nil, nil, @@ -1106,6 +1154,7 @@ ProgramNode(0...1194)( (977...980) ), DefNode(982...1006)( + :bar, (986...989), nil, ParametersNode(990...1001)( @@ -1142,6 +1191,7 @@ ProgramNode(0...1194)( (1003...1006) ), DefNode(1008...1031)( + :bar, (1012...1015), nil, ParametersNode(1016...1026)( @@ -1178,6 +1228,7 @@ ProgramNode(0...1194)( (1028...1031) ), DefNode(1033...1055)( + :bar, (1037...1040), nil, ParametersNode(1041...1050)( @@ -1214,6 +1265,7 @@ ProgramNode(0...1194)( (1052...1055) ), DefNode(1057...1082)( + :bar, (1061...1064), nil, ParametersNode(1065...1077)( @@ -1251,6 +1303,7 @@ ProgramNode(0...1194)( (1079...1082) ), DefNode(1084...1108)( + :bar, (1088...1091), nil, ParametersNode(1092...1103)( @@ -1288,6 +1341,7 @@ ProgramNode(0...1194)( (1105...1108) ), DefNode(1110...1133)( + :bar, (1114...1117), nil, ParametersNode(1118...1128)( @@ -1325,6 +1379,7 @@ ProgramNode(0...1194)( (1130...1133) ), DefNode(1135...1167)( + :method, (1139...1145), nil, ParametersNode(1146...1147)( @@ -1386,6 +1441,7 @@ ProgramNode(0...1194)( (1164...1167) ), DefNode(1169...1194)( + :foo, (1173...1176), nil, ParametersNode(1177...1189)( diff --git a/test/yarp/snapshots/non_alphanumeric_methods.txt b/test/yarp/snapshots/non_alphanumeric_methods.txt index cf87adc48c9c0b..a4cc39b6d3984e 100644 --- a/test/yarp/snapshots/non_alphanumeric_methods.txt +++ b/test/yarp/snapshots/non_alphanumeric_methods.txt @@ -2,6 +2,7 @@ ProgramNode(0...434)( [], StatementsNode(0...434)( [DefNode(0...9)( + :!, (4...5), nil, nil, @@ -15,6 +16,7 @@ ProgramNode(0...434)( (6...9) ), DefNode(11...21)( + :!=, (15...17), nil, nil, @@ -28,6 +30,7 @@ ProgramNode(0...434)( (18...21) ), DefNode(23...33)( + :!~, (27...29), nil, nil, @@ -41,6 +44,7 @@ ProgramNode(0...434)( (30...33) ), DefNode(35...44)( + :%, (39...40), nil, nil, @@ -54,6 +58,7 @@ ProgramNode(0...434)( (41...44) ), DefNode(46...60)( + :+, (55...56), SelfNode(50...54)(), nil, @@ -67,6 +72,7 @@ ProgramNode(0...434)( (57...60) ), DefNode(62...71)( + :&, (66...67), nil, nil, @@ -80,6 +86,7 @@ ProgramNode(0...434)( (68...71) ), DefNode(73...82)( + :*, (77...78), nil, nil, @@ -93,6 +100,7 @@ ProgramNode(0...434)( (79...82) ), DefNode(84...94)( + :**, (88...90), nil, nil, @@ -107,6 +115,7 @@ ProgramNode(0...434)( ), StringNode(96...102)((96...98), (98...101), (101...102), "abc"), DefNode(104...117)( + :+, (108...109), nil, ParametersNode(110...113)( @@ -128,6 +137,7 @@ ProgramNode(0...434)( (114...117) ), DefNode(119...130)( + :+, (123...124), nil, nil, @@ -141,6 +151,7 @@ ProgramNode(0...434)( (127...130) ), DefNode(132...143)( + :+, (136...137), nil, ParametersNode(138...139)( @@ -162,6 +173,7 @@ ProgramNode(0...434)( (140...143) ), DefNode(145...159)( + :+, (154...155), SelfNode(149...153)(), nil, @@ -175,6 +187,7 @@ ProgramNode(0...434)( (156...159) ), DefNode(161...170)( + :+, (165...166), nil, nil, @@ -188,6 +201,7 @@ ProgramNode(0...434)( (167...170) ), DefNode(172...182)( + :+@, (176...178), nil, nil, @@ -201,6 +215,7 @@ ProgramNode(0...434)( (179...182) ), DefNode(184...193)( + :-, (188...189), nil, nil, @@ -214,6 +229,7 @@ ProgramNode(0...434)( (190...193) ), DefNode(195...206)( + :-, (201...202), CallNode(199...200)(nil, nil, (199...200), nil, nil, nil, nil, 2, "a"), nil, @@ -227,6 +243,7 @@ ProgramNode(0...434)( (203...206) ), DefNode(208...218)( + :-@, (212...214), nil, nil, @@ -240,6 +257,7 @@ ProgramNode(0...434)( (215...218) ), DefNode(220...229)( + :/, (224...225), nil, nil, @@ -253,6 +271,7 @@ ProgramNode(0...434)( (226...229) ), DefNode(231...240)( + :<, (235...236), nil, nil, @@ -266,6 +285,7 @@ ProgramNode(0...434)( (237...240) ), DefNode(242...252)( + :<<, (246...248), nil, nil, @@ -279,6 +299,7 @@ ProgramNode(0...434)( (249...252) ), DefNode(254...264)( + :<=, (258...260), nil, nil, @@ -292,6 +313,7 @@ ProgramNode(0...434)( (261...264) ), DefNode(266...277)( + :<=>, (270...273), nil, nil, @@ -305,6 +327,7 @@ ProgramNode(0...434)( (274...277) ), DefNode(279...289)( + :==, (283...285), nil, nil, @@ -318,6 +341,7 @@ ProgramNode(0...434)( (286...289) ), DefNode(291...302)( + :===, (295...298), nil, nil, @@ -331,6 +355,7 @@ ProgramNode(0...434)( (299...302) ), DefNode(304...314)( + :=~, (308...310), nil, nil, @@ -344,6 +369,7 @@ ProgramNode(0...434)( (311...314) ), DefNode(316...325)( + :>, (320...321), nil, nil, @@ -357,6 +383,7 @@ ProgramNode(0...434)( (322...325) ), DefNode(327...337)( + :>=, (331...333), nil, nil, @@ -370,6 +397,7 @@ ProgramNode(0...434)( (334...337) ), DefNode(339...349)( + :>>, (343...345), nil, nil, @@ -383,6 +411,7 @@ ProgramNode(0...434)( (346...349) ), DefNode(351...361)( + :[], (355...357), nil, nil, @@ -396,6 +425,7 @@ ProgramNode(0...434)( (358...361) ), DefNode(363...374)( + :[]=, (367...370), nil, nil, @@ -409,6 +439,7 @@ ProgramNode(0...434)( (371...374) ), DefNode(376...385)( + :^, (380...381), nil, nil, @@ -422,6 +453,7 @@ ProgramNode(0...434)( (382...385) ), DefNode(387...396)( + :`, (391...392), nil, nil, @@ -435,6 +467,7 @@ ProgramNode(0...434)( (393...396) ), DefNode(398...412)( + :`, (407...408), SelfNode(402...406)(), nil, @@ -448,6 +481,7 @@ ProgramNode(0...434)( (409...412) ), DefNode(414...423)( + :|, (418...419), nil, nil, @@ -461,6 +495,7 @@ ProgramNode(0...434)( (420...423) ), DefNode(425...434)( + :~, (429...430), nil, nil, diff --git a/test/yarp/snapshots/rescue.txt b/test/yarp/snapshots/rescue.txt index c52a261fceee6f..9decb56292bf2c 100644 --- a/test/yarp/snapshots/rescue.txt +++ b/test/yarp/snapshots/rescue.txt @@ -227,6 +227,7 @@ ProgramNode(0...316)( (242...245) ), DefNode(247...291)( + :some_method, (251...262), nil, nil, @@ -258,6 +259,7 @@ ProgramNode(0...316)( nil ), DefNode(293...316)( + :a, (297...298), nil, nil, diff --git a/test/yarp/snapshots/seattlerb/TestRubyParserShared.txt b/test/yarp/snapshots/seattlerb/TestRubyParserShared.txt index d839450b2cb5d0..8c4c0ecc509c01 100644 --- a/test/yarp/snapshots/seattlerb/TestRubyParserShared.txt +++ b/test/yarp/snapshots/seattlerb/TestRubyParserShared.txt @@ -50,6 +50,7 @@ ProgramNode(0...689)( nil, StatementsNode(168...246)( [DefNode(168...246)( + :y, (177...178), SelfNode(172...176)(), ParametersNode(179...200)( @@ -125,6 +126,7 @@ ProgramNode(0...689)( nil, StatementsNode(417...480)( [DefNode(417...480)( + :y, (421...422), nil, ParametersNode(423...444)( diff --git a/test/yarp/snapshots/seattlerb/args_kw_block.txt b/test/yarp/snapshots/seattlerb/args_kw_block.txt index 3ccb7472787ecb..6aef28d170489f 100644 --- a/test/yarp/snapshots/seattlerb/args_kw_block.txt +++ b/test/yarp/snapshots/seattlerb/args_kw_block.txt @@ -2,6 +2,7 @@ ProgramNode(0...20)( [], StatementsNode(0...20)( [DefNode(0...20)( + :f, (4...5), nil, ParametersNode(6...14)( diff --git a/test/yarp/snapshots/seattlerb/block_arg__bare.txt b/test/yarp/snapshots/seattlerb/block_arg__bare.txt index c660aeb54e725e..2634a94099c612 100644 --- a/test/yarp/snapshots/seattlerb/block_arg__bare.txt +++ b/test/yarp/snapshots/seattlerb/block_arg__bare.txt @@ -2,6 +2,7 @@ ProgramNode(0...13)( [], StatementsNode(0...13)( [DefNode(0...13)( + :x, (4...5), nil, ParametersNode(6...7)( diff --git a/test/yarp/snapshots/seattlerb/block_call_defn_call_block_call.txt b/test/yarp/snapshots/seattlerb/block_call_defn_call_block_call.txt index 46b55171fab0af..79c6b347e5a622 100644 --- a/test/yarp/snapshots/seattlerb/block_call_defn_call_block_call.txt +++ b/test/yarp/snapshots/seattlerb/block_call_defn_call_block_call.txt @@ -8,6 +8,7 @@ ProgramNode(0...30)( nil, ArgumentsNode(2...18)( [DefNode(2...18)( + :b, (6...7), nil, ParametersNode(8...9)( diff --git a/test/yarp/snapshots/seattlerb/bug_187.txt b/test/yarp/snapshots/seattlerb/bug_187.txt index f4ca89ff6d9066..a62a9f30be1110 100644 --- a/test/yarp/snapshots/seattlerb/bug_187.txt +++ b/test/yarp/snapshots/seattlerb/bug_187.txt @@ -8,6 +8,7 @@ ProgramNode(0...28)( nil, ArgumentsNode(8...28)( [DefNode(8...28)( + :f, (12...13), nil, nil, diff --git a/test/yarp/snapshots/seattlerb/bug_249.txt b/test/yarp/snapshots/seattlerb/bug_249.txt index 26e918c4f7a857..776132c6d2cb39 100644 --- a/test/yarp/snapshots/seattlerb/bug_249.txt +++ b/test/yarp/snapshots/seattlerb/bug_249.txt @@ -22,6 +22,7 @@ ProgramNode(0...67)( nil, StatementsNode(20...38)( [DefNode(20...38)( + :initialize, (24...34), nil, nil, diff --git a/test/yarp/snapshots/seattlerb/bug_call_arglist_parens.txt b/test/yarp/snapshots/seattlerb/bug_call_arglist_parens.txt index 61193bb0a631cb..67934a28dc1cdb 100644 --- a/test/yarp/snapshots/seattlerb/bug_call_arglist_parens.txt +++ b/test/yarp/snapshots/seattlerb/bug_call_arglist_parens.txt @@ -2,6 +2,7 @@ ProgramNode(6...94)( [], StatementsNode(6...94)( [DefNode(6...39)( + :f, (10...11), nil, nil, @@ -34,6 +35,7 @@ ProgramNode(6...94)( (36...39) ), DefNode(48...82)( + :f, (52...53), nil, nil, diff --git a/test/yarp/snapshots/seattlerb/class_comments.txt b/test/yarp/snapshots/seattlerb/class_comments.txt index 85d9d91067cec5..5314c70cc4bafe 100644 --- a/test/yarp/snapshots/seattlerb/class_comments.txt +++ b/test/yarp/snapshots/seattlerb/class_comments.txt @@ -9,6 +9,7 @@ ProgramNode(19...71)( nil, StatementsNode(40...67)( [DefNode(40...67)( + :blah, (44...48), nil, nil, diff --git a/test/yarp/snapshots/seattlerb/defn_arg_asplat_arg.txt b/test/yarp/snapshots/seattlerb/defn_arg_asplat_arg.txt index 9f1f7980e8f426..207e45aab9eed4 100644 --- a/test/yarp/snapshots/seattlerb/defn_arg_asplat_arg.txt +++ b/test/yarp/snapshots/seattlerb/defn_arg_asplat_arg.txt @@ -2,6 +2,7 @@ ProgramNode(0...29)( [], StatementsNode(0...29)( [DefNode(0...29)( + :call, (4...8), nil, ParametersNode(9...24)( diff --git a/test/yarp/snapshots/seattlerb/defn_arg_forward_args.txt b/test/yarp/snapshots/seattlerb/defn_arg_forward_args.txt index c3e8e7d010e494..908be093371206 100644 --- a/test/yarp/snapshots/seattlerb/defn_arg_forward_args.txt +++ b/test/yarp/snapshots/seattlerb/defn_arg_forward_args.txt @@ -2,6 +2,7 @@ ProgramNode(0...29)( [], StatementsNode(0...29)( [DefNode(0...29)( + :a, (4...5), nil, ParametersNode(6...12)( diff --git a/test/yarp/snapshots/seattlerb/defn_args_forward_args.txt b/test/yarp/snapshots/seattlerb/defn_args_forward_args.txt index c14a1868edcdfe..bdb721f2d21d27 100644 --- a/test/yarp/snapshots/seattlerb/defn_args_forward_args.txt +++ b/test/yarp/snapshots/seattlerb/defn_args_forward_args.txt @@ -2,6 +2,7 @@ ProgramNode(0...41)( [], StatementsNode(0...41)( [DefNode(0...41)( + :a, (4...5), nil, ParametersNode(6...18)( diff --git a/test/yarp/snapshots/seattlerb/defn_comments.txt b/test/yarp/snapshots/seattlerb/defn_comments.txt index 1ff1c127bd0550..a9b5501204745a 100644 --- a/test/yarp/snapshots/seattlerb/defn_comments.txt +++ b/test/yarp/snapshots/seattlerb/defn_comments.txt @@ -2,6 +2,7 @@ ProgramNode(19...31)( [], StatementsNode(19...31)( [DefNode(19...31)( + :blah, (23...27), nil, nil, diff --git a/test/yarp/snapshots/seattlerb/defn_endless_command.txt b/test/yarp/snapshots/seattlerb/defn_endless_command.txt index 7e1989cf6fbc1c..4e8833808043a2 100644 --- a/test/yarp/snapshots/seattlerb/defn_endless_command.txt +++ b/test/yarp/snapshots/seattlerb/defn_endless_command.txt @@ -2,6 +2,7 @@ ProgramNode(0...33)( [], StatementsNode(0...33)( [DefNode(0...33)( + :some_method, (4...15), nil, nil, diff --git a/test/yarp/snapshots/seattlerb/defn_endless_command_rescue.txt b/test/yarp/snapshots/seattlerb/defn_endless_command_rescue.txt index bed7b31b5a41b4..30e99d44fef538 100644 --- a/test/yarp/snapshots/seattlerb/defn_endless_command_rescue.txt +++ b/test/yarp/snapshots/seattlerb/defn_endless_command_rescue.txt @@ -2,6 +2,7 @@ ProgramNode(0...43)( [], StatementsNode(0...43)( [DefNode(0...43)( + :some_method, (4...15), nil, nil, diff --git a/test/yarp/snapshots/seattlerb/defn_forward_args.txt b/test/yarp/snapshots/seattlerb/defn_forward_args.txt index 0fbe6f0d709460..6b06726352def1 100644 --- a/test/yarp/snapshots/seattlerb/defn_forward_args.txt +++ b/test/yarp/snapshots/seattlerb/defn_forward_args.txt @@ -2,6 +2,7 @@ ProgramNode(0...23)( [], StatementsNode(0...23)( [DefNode(0...23)( + :a, (4...5), nil, ParametersNode(6...9)( diff --git a/test/yarp/snapshots/seattlerb/defn_forward_args__no_parens.txt b/test/yarp/snapshots/seattlerb/defn_forward_args__no_parens.txt index 14d94bc244a9cc..b0a199c7bd7300 100644 --- a/test/yarp/snapshots/seattlerb/defn_forward_args__no_parens.txt +++ b/test/yarp/snapshots/seattlerb/defn_forward_args__no_parens.txt @@ -2,6 +2,7 @@ ProgramNode(0...22)( [], StatementsNode(0...22)( [DefNode(0...22)( + :f, (4...5), nil, ParametersNode(6...9)( diff --git a/test/yarp/snapshots/seattlerb/defn_kwarg_env.txt b/test/yarp/snapshots/seattlerb/defn_kwarg_env.txt index 4364d661881ff7..ec45e1790ba45a 100644 --- a/test/yarp/snapshots/seattlerb/defn_kwarg_env.txt +++ b/test/yarp/snapshots/seattlerb/defn_kwarg_env.txt @@ -2,6 +2,7 @@ ProgramNode(0...45)( [], StatementsNode(0...45)( [DefNode(0...45)( + :test, (4...8), nil, ParametersNode(9...18)( diff --git a/test/yarp/snapshots/seattlerb/defn_kwarg_kwarg.txt b/test/yarp/snapshots/seattlerb/defn_kwarg_kwarg.txt index 6a1abc0d205792..aa90849328282c 100644 --- a/test/yarp/snapshots/seattlerb/defn_kwarg_kwarg.txt +++ b/test/yarp/snapshots/seattlerb/defn_kwarg_kwarg.txt @@ -2,6 +2,7 @@ ProgramNode(0...24)( [], StatementsNode(0...24)( [DefNode(0...24)( + :f, (4...5), nil, ParametersNode(6...19)( diff --git a/test/yarp/snapshots/seattlerb/defn_kwarg_kwsplat.txt b/test/yarp/snapshots/seattlerb/defn_kwarg_kwsplat.txt index 040bca4c5d5f57..83e1bc2f23e8bd 100644 --- a/test/yarp/snapshots/seattlerb/defn_kwarg_kwsplat.txt +++ b/test/yarp/snapshots/seattlerb/defn_kwarg_kwsplat.txt @@ -2,6 +2,7 @@ ProgramNode(0...20)( [], StatementsNode(0...20)( [DefNode(0...20)( + :a, (4...5), nil, ParametersNode(6...15)( diff --git a/test/yarp/snapshots/seattlerb/defn_kwarg_kwsplat_anon.txt b/test/yarp/snapshots/seattlerb/defn_kwarg_kwsplat_anon.txt index 080b3ed2abc7d0..58930bb8477fad 100644 --- a/test/yarp/snapshots/seattlerb/defn_kwarg_kwsplat_anon.txt +++ b/test/yarp/snapshots/seattlerb/defn_kwarg_kwsplat_anon.txt @@ -2,6 +2,7 @@ ProgramNode(0...19)( [], StatementsNode(0...19)( [DefNode(0...19)( + :a, (4...5), nil, ParametersNode(6...14)( diff --git a/test/yarp/snapshots/seattlerb/defn_kwarg_lvar.txt b/test/yarp/snapshots/seattlerb/defn_kwarg_lvar.txt index e118d362a49f6c..2e1afdea71ad33 100644 --- a/test/yarp/snapshots/seattlerb/defn_kwarg_lvar.txt +++ b/test/yarp/snapshots/seattlerb/defn_kwarg_lvar.txt @@ -2,6 +2,7 @@ ProgramNode(0...26)( [], StatementsNode(0...26)( [DefNode(0...26)( + :fun, (4...7), nil, ParametersNode(8...16)( diff --git a/test/yarp/snapshots/seattlerb/defn_kwarg_no_parens.txt b/test/yarp/snapshots/seattlerb/defn_kwarg_no_parens.txt index 27982d5cb80179..c98e8317b66abd 100644 --- a/test/yarp/snapshots/seattlerb/defn_kwarg_no_parens.txt +++ b/test/yarp/snapshots/seattlerb/defn_kwarg_no_parens.txt @@ -2,6 +2,7 @@ ProgramNode(0...14)( [], StatementsNode(0...14)( [DefNode(0...14)( + :f, (4...5), nil, ParametersNode(6...10)( diff --git a/test/yarp/snapshots/seattlerb/defn_kwarg_val.txt b/test/yarp/snapshots/seattlerb/defn_kwarg_val.txt index 2ae853d3f4b4a0..8a0be77d223bfb 100644 --- a/test/yarp/snapshots/seattlerb/defn_kwarg_val.txt +++ b/test/yarp/snapshots/seattlerb/defn_kwarg_val.txt @@ -2,6 +2,7 @@ ProgramNode(0...17)( [], StatementsNode(0...17)( [DefNode(0...17)( + :f, (4...5), nil, ParametersNode(6...12)( diff --git a/test/yarp/snapshots/seattlerb/defn_no_kwargs.txt b/test/yarp/snapshots/seattlerb/defn_no_kwargs.txt index a5046e04e41b66..a810609fbc31a6 100644 --- a/test/yarp/snapshots/seattlerb/defn_no_kwargs.txt +++ b/test/yarp/snapshots/seattlerb/defn_no_kwargs.txt @@ -2,6 +2,7 @@ ProgramNode(0...17)( [], StatementsNode(0...17)( [DefNode(0...17)( + :x, (4...5), nil, ParametersNode(6...11)( diff --git a/test/yarp/snapshots/seattlerb/defn_oneliner.txt b/test/yarp/snapshots/seattlerb/defn_oneliner.txt index 053400c564c6e2..1b1600dfedab9a 100644 --- a/test/yarp/snapshots/seattlerb/defn_oneliner.txt +++ b/test/yarp/snapshots/seattlerb/defn_oneliner.txt @@ -2,6 +2,7 @@ ProgramNode(0...27)( [], StatementsNode(0...27)( [DefNode(0...27)( + :exec, (4...8), nil, ParametersNode(9...12)( diff --git a/test/yarp/snapshots/seattlerb/defn_oneliner_eq2.txt b/test/yarp/snapshots/seattlerb/defn_oneliner_eq2.txt index b2d59818591f7e..db923d773e7f31 100644 --- a/test/yarp/snapshots/seattlerb/defn_oneliner_eq2.txt +++ b/test/yarp/snapshots/seattlerb/defn_oneliner_eq2.txt @@ -9,6 +9,7 @@ ProgramNode(0...28)( nil, StatementsNode(10...24)( [DefNode(10...24)( + :==, (14...16), nil, ParametersNode(17...18)( diff --git a/test/yarp/snapshots/seattlerb/defn_oneliner_noargs.txt b/test/yarp/snapshots/seattlerb/defn_oneliner_noargs.txt index 683c405b1853f0..2da92bf5598b9e 100644 --- a/test/yarp/snapshots/seattlerb/defn_oneliner_noargs.txt +++ b/test/yarp/snapshots/seattlerb/defn_oneliner_noargs.txt @@ -2,6 +2,7 @@ ProgramNode(0...17)( [], StatementsNode(0...17)( [DefNode(0...17)( + :exec, (4...8), nil, nil, diff --git a/test/yarp/snapshots/seattlerb/defn_oneliner_noargs_parentheses.txt b/test/yarp/snapshots/seattlerb/defn_oneliner_noargs_parentheses.txt index bbf7fd2dcaebd9..b416121718ccde 100644 --- a/test/yarp/snapshots/seattlerb/defn_oneliner_noargs_parentheses.txt +++ b/test/yarp/snapshots/seattlerb/defn_oneliner_noargs_parentheses.txt @@ -2,6 +2,7 @@ ProgramNode(0...19)( [], StatementsNode(0...19)( [DefNode(0...19)( + :exec, (4...8), nil, nil, diff --git a/test/yarp/snapshots/seattlerb/defn_oneliner_rescue.txt b/test/yarp/snapshots/seattlerb/defn_oneliner_rescue.txt index 5032c52203f98c..0a1f6cbd931e88 100644 --- a/test/yarp/snapshots/seattlerb/defn_oneliner_rescue.txt +++ b/test/yarp/snapshots/seattlerb/defn_oneliner_rescue.txt @@ -2,6 +2,7 @@ ProgramNode(0...130)( [], StatementsNode(0...130)( [DefNode(0...44)( + :exec, (4...8), nil, ParametersNode(9...12)( @@ -51,6 +52,7 @@ ProgramNode(0...130)( (41...44) ), DefNode(47...89)( + :exec, (51...55), nil, ParametersNode(56...59)( @@ -90,6 +92,7 @@ ProgramNode(0...130)( (86...89) ), DefNode(92...130)( + :exec, (96...100), nil, ParametersNode(101...104)( diff --git a/test/yarp/snapshots/seattlerb/defn_opt_last_arg.txt b/test/yarp/snapshots/seattlerb/defn_opt_last_arg.txt index d4064d0f345026..b9fe1dcf52a679 100644 --- a/test/yarp/snapshots/seattlerb/defn_opt_last_arg.txt +++ b/test/yarp/snapshots/seattlerb/defn_opt_last_arg.txt @@ -2,6 +2,7 @@ ProgramNode(0...21)( [], StatementsNode(0...21)( [DefNode(0...21)( + :m, (4...5), nil, ParametersNode(6...17)( diff --git a/test/yarp/snapshots/seattlerb/defn_opt_reg.txt b/test/yarp/snapshots/seattlerb/defn_opt_reg.txt index 5796adf1e9011c..0ae5037d598a19 100644 --- a/test/yarp/snapshots/seattlerb/defn_opt_reg.txt +++ b/test/yarp/snapshots/seattlerb/defn_opt_reg.txt @@ -2,6 +2,7 @@ ProgramNode(0...19)( [], StatementsNode(0...19)( [DefNode(0...19)( + :f, (4...5), nil, ParametersNode(6...14)( diff --git a/test/yarp/snapshots/seattlerb/defn_opt_splat_arg.txt b/test/yarp/snapshots/seattlerb/defn_opt_splat_arg.txt index 5ce355141df37c..2148a93df5071d 100644 --- a/test/yarp/snapshots/seattlerb/defn_opt_splat_arg.txt +++ b/test/yarp/snapshots/seattlerb/defn_opt_splat_arg.txt @@ -2,6 +2,7 @@ ProgramNode(0...24)( [], StatementsNode(0...24)( [DefNode(0...24)( + :f, (4...5), nil, ParametersNode(7...19)( diff --git a/test/yarp/snapshots/seattlerb/defn_powarg.txt b/test/yarp/snapshots/seattlerb/defn_powarg.txt index 6965fca97e027a..b57aa3c9c707c1 100644 --- a/test/yarp/snapshots/seattlerb/defn_powarg.txt +++ b/test/yarp/snapshots/seattlerb/defn_powarg.txt @@ -2,6 +2,7 @@ ProgramNode(0...17)( [], StatementsNode(0...17)( [DefNode(0...17)( + :f, (4...5), nil, ParametersNode(6...12)( diff --git a/test/yarp/snapshots/seattlerb/defn_reg_opt_reg.txt b/test/yarp/snapshots/seattlerb/defn_reg_opt_reg.txt index c7e9c640872efc..ee789ca0ae3e3d 100644 --- a/test/yarp/snapshots/seattlerb/defn_reg_opt_reg.txt +++ b/test/yarp/snapshots/seattlerb/defn_reg_opt_reg.txt @@ -2,6 +2,7 @@ ProgramNode(0...23)( [], StatementsNode(0...23)( [DefNode(0...23)( + :f, (4...5), nil, ParametersNode(6...18)( diff --git a/test/yarp/snapshots/seattlerb/defn_splat_arg.txt b/test/yarp/snapshots/seattlerb/defn_splat_arg.txt index 63e8839a6c2ecc..95a16a11b56e25 100644 --- a/test/yarp/snapshots/seattlerb/defn_splat_arg.txt +++ b/test/yarp/snapshots/seattlerb/defn_splat_arg.txt @@ -2,6 +2,7 @@ ProgramNode(0...15)( [], StatementsNode(0...15)( [DefNode(0...15)( + :f, (4...5), nil, ParametersNode(6...10)( diff --git a/test/yarp/snapshots/seattlerb/defn_unary_not.txt b/test/yarp/snapshots/seattlerb/defn_unary_not.txt index 9fbee1764f425a..e167c2aee9b9f2 100644 --- a/test/yarp/snapshots/seattlerb/defn_unary_not.txt +++ b/test/yarp/snapshots/seattlerb/defn_unary_not.txt @@ -2,6 +2,7 @@ ProgramNode(0...17)( [], StatementsNode(0...17)( [DefNode(0...17)( + :"!@", (4...6), nil, nil, diff --git a/test/yarp/snapshots/seattlerb/defns_reserved.txt b/test/yarp/snapshots/seattlerb/defns_reserved.txt index 07b165898eb927..7d12edeb9b3d5c 100644 --- a/test/yarp/snapshots/seattlerb/defns_reserved.txt +++ b/test/yarp/snapshots/seattlerb/defns_reserved.txt @@ -2,6 +2,7 @@ ProgramNode(0...20)( [], StatementsNode(0...20)( [DefNode(0...20)( + :return, (9...15), SelfNode(4...8)(), nil, diff --git a/test/yarp/snapshots/seattlerb/defs_as_arg_with_do_block_inside.txt b/test/yarp/snapshots/seattlerb/defs_as_arg_with_do_block_inside.txt index d223e069137481..5474d1e825d4d8 100644 --- a/test/yarp/snapshots/seattlerb/defs_as_arg_with_do_block_inside.txt +++ b/test/yarp/snapshots/seattlerb/defs_as_arg_with_do_block_inside.txt @@ -8,6 +8,7 @@ ProgramNode(0...30)( nil, ArgumentsNode(2...30)( [DefNode(2...30)( + :b, (11...12), SelfNode(6...10)(), nil, diff --git a/test/yarp/snapshots/seattlerb/defs_comments.txt b/test/yarp/snapshots/seattlerb/defs_comments.txt index 55a3054373ffd8..640576684b0ef2 100644 --- a/test/yarp/snapshots/seattlerb/defs_comments.txt +++ b/test/yarp/snapshots/seattlerb/defs_comments.txt @@ -2,6 +2,7 @@ ProgramNode(19...36)( [], StatementsNode(19...36)( [DefNode(19...36)( + :blah, (28...32), SelfNode(23...27)(), nil, diff --git a/test/yarp/snapshots/seattlerb/defs_endless_command.txt b/test/yarp/snapshots/seattlerb/defs_endless_command.txt index 3675f26ddffe77..068e7de9b3ab96 100644 --- a/test/yarp/snapshots/seattlerb/defs_endless_command.txt +++ b/test/yarp/snapshots/seattlerb/defs_endless_command.txt @@ -2,6 +2,7 @@ ProgramNode(0...35)( [], StatementsNode(0...35)( [DefNode(0...35)( + :some_method, (6...17), CallNode(4...5)(nil, nil, (4...5), nil, nil, nil, nil, 2, "x"), nil, diff --git a/test/yarp/snapshots/seattlerb/defs_endless_command_rescue.txt b/test/yarp/snapshots/seattlerb/defs_endless_command_rescue.txt index e032fff9a6b45f..00b4472689b978 100644 --- a/test/yarp/snapshots/seattlerb/defs_endless_command_rescue.txt +++ b/test/yarp/snapshots/seattlerb/defs_endless_command_rescue.txt @@ -2,6 +2,7 @@ ProgramNode(0...45)( [], StatementsNode(0...45)( [DefNode(0...45)( + :some_method, (6...17), CallNode(4...5)(nil, nil, (4...5), nil, nil, nil, nil, 2, "x"), nil, diff --git a/test/yarp/snapshots/seattlerb/defs_kwarg.txt b/test/yarp/snapshots/seattlerb/defs_kwarg.txt index d7288bc1e05f03..6b1e60d602cada 100644 --- a/test/yarp/snapshots/seattlerb/defs_kwarg.txt +++ b/test/yarp/snapshots/seattlerb/defs_kwarg.txt @@ -2,6 +2,7 @@ ProgramNode(0...19)( [], StatementsNode(0...19)( [DefNode(0...19)( + :a, (9...10), SelfNode(4...8)(), ParametersNode(11...15)( diff --git a/test/yarp/snapshots/seattlerb/defs_oneliner.txt b/test/yarp/snapshots/seattlerb/defs_oneliner.txt index 60ea01092f7caa..f8214ef3f6f503 100644 --- a/test/yarp/snapshots/seattlerb/defs_oneliner.txt +++ b/test/yarp/snapshots/seattlerb/defs_oneliner.txt @@ -2,6 +2,7 @@ ProgramNode(0...32)( [], StatementsNode(0...32)( [DefNode(0...32)( + :exec, (9...13), SelfNode(4...8)(), ParametersNode(14...17)( diff --git a/test/yarp/snapshots/seattlerb/defs_oneliner_eq2.txt b/test/yarp/snapshots/seattlerb/defs_oneliner_eq2.txt index cebb94c32f412d..ee69fa0752562e 100644 --- a/test/yarp/snapshots/seattlerb/defs_oneliner_eq2.txt +++ b/test/yarp/snapshots/seattlerb/defs_oneliner_eq2.txt @@ -9,6 +9,7 @@ ProgramNode(0...33)( nil, StatementsNode(10...29)( [DefNode(10...29)( + :==, (19...21), SelfNode(14...18)(), ParametersNode(22...23)( diff --git a/test/yarp/snapshots/seattlerb/defs_oneliner_rescue.txt b/test/yarp/snapshots/seattlerb/defs_oneliner_rescue.txt index 90269cc14aa8c4..9f510cdb72ba4f 100644 --- a/test/yarp/snapshots/seattlerb/defs_oneliner_rescue.txt +++ b/test/yarp/snapshots/seattlerb/defs_oneliner_rescue.txt @@ -2,6 +2,7 @@ ProgramNode(0...145)( [], StatementsNode(0...145)( [DefNode(0...49)( + :exec, (9...13), SelfNode(4...8)(), ParametersNode(14...17)( @@ -51,6 +52,7 @@ ProgramNode(0...145)( (46...49) ), DefNode(52...99)( + :exec, (61...65), SelfNode(56...60)(), ParametersNode(66...69)( @@ -90,6 +92,7 @@ ProgramNode(0...145)( (96...99) ), DefNode(102...145)( + :exec, (111...115), SelfNode(106...110)(), ParametersNode(116...119)( diff --git a/test/yarp/snapshots/seattlerb/f_kw.txt b/test/yarp/snapshots/seattlerb/f_kw.txt index 420dab984dc1a8..053e093303e625 100644 --- a/test/yarp/snapshots/seattlerb/f_kw.txt +++ b/test/yarp/snapshots/seattlerb/f_kw.txt @@ -2,6 +2,7 @@ ProgramNode(0...15)( [], StatementsNode(0...15)( [DefNode(0...15)( + :x, (4...5), nil, ParametersNode(6...10)( diff --git a/test/yarp/snapshots/seattlerb/f_kw__required.txt b/test/yarp/snapshots/seattlerb/f_kw__required.txt index 30cd82d52c6684..8f29a7a9c9877a 100644 --- a/test/yarp/snapshots/seattlerb/f_kw__required.txt +++ b/test/yarp/snapshots/seattlerb/f_kw__required.txt @@ -2,6 +2,7 @@ ProgramNode(0...13)( [], StatementsNode(0...13)( [DefNode(0...13)( + :x, (4...5), nil, ParametersNode(6...8)( diff --git a/test/yarp/snapshots/seattlerb/magic_encoding_comment.txt b/test/yarp/snapshots/seattlerb/magic_encoding_comment.txt index 2baa7bab0b323f..010fe793941105 100644 --- a/test/yarp/snapshots/seattlerb/magic_encoding_comment.txt +++ b/test/yarp/snapshots/seattlerb/magic_encoding_comment.txt @@ -9,6 +9,7 @@ ProgramNode(18...90)( nil, StatementsNode(54...86)( [DefNode(54...86)( + :è, (63...65), SelfNode(58...62)(), nil, diff --git a/test/yarp/snapshots/seattlerb/module_comments.txt b/test/yarp/snapshots/seattlerb/module_comments.txt index 0a818d3116ae69..a049665ce0529c 100644 --- a/test/yarp/snapshots/seattlerb/module_comments.txt +++ b/test/yarp/snapshots/seattlerb/module_comments.txt @@ -7,6 +7,7 @@ ProgramNode(24...77)( ConstantReadNode(31...32)(:X), StatementsNode(46...73)( [DefNode(46...73)( + :blah, (50...54), nil, nil, diff --git a/test/yarp/snapshots/seattlerb/parse_def_special_name.txt b/test/yarp/snapshots/seattlerb/parse_def_special_name.txt index a266ddf0946237..0b6b0eae7fb7ab 100644 --- a/test/yarp/snapshots/seattlerb/parse_def_special_name.txt +++ b/test/yarp/snapshots/seattlerb/parse_def_special_name.txt @@ -2,6 +2,7 @@ ProgramNode(0...13)( [], StatementsNode(0...13)( [DefNode(0...13)( + :next, (4...8), nil, nil, diff --git a/test/yarp/snapshots/seattlerb/parse_line_defn_complex.txt b/test/yarp/snapshots/seattlerb/parse_line_defn_complex.txt index 170b9bc81e321e..7e1ea50f46a6b3 100644 --- a/test/yarp/snapshots/seattlerb/parse_line_defn_complex.txt +++ b/test/yarp/snapshots/seattlerb/parse_line_defn_complex.txt @@ -2,6 +2,7 @@ ProgramNode(0...40)( [], StatementsNode(0...40)( [DefNode(0...40)( + :x, (4...5), nil, ParametersNode(6...7)( diff --git a/test/yarp/snapshots/seattlerb/parse_line_defn_no_parens.txt b/test/yarp/snapshots/seattlerb/parse_line_defn_no_parens.txt index ff61047cbb848e..3bbc2bf9cdb05d 100644 --- a/test/yarp/snapshots/seattlerb/parse_line_defn_no_parens.txt +++ b/test/yarp/snapshots/seattlerb/parse_line_defn_no_parens.txt @@ -2,6 +2,7 @@ ProgramNode(0...21)( [], StatementsNode(0...21)( [DefNode(0...10)( + :f, (4...5), nil, nil, @@ -15,6 +16,7 @@ ProgramNode(0...21)( (7...10) ), DefNode(12...21)( + :f, (16...17), nil, nil, diff --git a/test/yarp/snapshots/seattlerb/parse_line_defn_no_parens_args.txt b/test/yarp/snapshots/seattlerb/parse_line_defn_no_parens_args.txt index eec5acfcd7d062..2040cdca68621e 100644 --- a/test/yarp/snapshots/seattlerb/parse_line_defn_no_parens_args.txt +++ b/test/yarp/snapshots/seattlerb/parse_line_defn_no_parens_args.txt @@ -2,6 +2,7 @@ ProgramNode(0...11)( [], StatementsNode(0...11)( [DefNode(0...11)( + :f, (4...5), nil, ParametersNode(6...7)( diff --git a/test/yarp/snapshots/seattlerb/parse_line_return.txt b/test/yarp/snapshots/seattlerb/parse_line_return.txt index 17ba7af0a5a7ec..87016474356b3d 100644 --- a/test/yarp/snapshots/seattlerb/parse_line_return.txt +++ b/test/yarp/snapshots/seattlerb/parse_line_return.txt @@ -2,6 +2,7 @@ ProgramNode(6...77)( [], StatementsNode(6...77)( [DefNode(6...77)( + :blah, (10...14), nil, nil, diff --git a/test/yarp/snapshots/seattlerb/required_kwarg_no_value.txt b/test/yarp/snapshots/seattlerb/required_kwarg_no_value.txt index 3f95094fef4353..942400bfa12d4f 100644 --- a/test/yarp/snapshots/seattlerb/required_kwarg_no_value.txt +++ b/test/yarp/snapshots/seattlerb/required_kwarg_no_value.txt @@ -2,6 +2,7 @@ ProgramNode(0...16)( [], StatementsNode(0...16)( [DefNode(0...16)( + :x, (4...5), nil, ParametersNode(6...12)( diff --git a/test/yarp/snapshots/unparser/corpus/literal/class.txt b/test/yarp/snapshots/unparser/corpus/literal/class.txt index 4d8b7056232891..5d0ca9da7bb9c5 100644 --- a/test/yarp/snapshots/unparser/corpus/literal/class.txt +++ b/test/yarp/snapshots/unparser/corpus/literal/class.txt @@ -134,6 +134,7 @@ ProgramNode(0...213)( "include" ), DefNode(172...194)( + :foo, (176...179), nil, nil, diff --git a/test/yarp/snapshots/unparser/corpus/literal/def.txt b/test/yarp/snapshots/unparser/corpus/literal/def.txt index d78d9623bac9ce..9bb03d20f2eb54 100644 --- a/test/yarp/snapshots/unparser/corpus/literal/def.txt +++ b/test/yarp/snapshots/unparser/corpus/literal/def.txt @@ -2,6 +2,7 @@ ProgramNode(0...913)( [], StatementsNode(0...913)( [DefNode(0...46)( + :foo, (4...7), nil, nil, @@ -75,6 +76,7 @@ ProgramNode(0...913)( (43...46) ), DefNode(48...103)( + :foo, (52...55), nil, nil, @@ -172,6 +174,7 @@ ProgramNode(0...913)( (100...103) ), DefNode(105...128)( + :foo, (109...112), nil, ParametersNode(113...123)( @@ -194,6 +197,7 @@ ProgramNode(0...913)( (125...128) ), DefNode(130...141)( + :foo, (134...137), nil, nil, @@ -207,6 +211,7 @@ ProgramNode(0...913)( (138...141) ), DefNode(143...160)( + :foo, (147...150), nil, nil, @@ -232,6 +237,7 @@ ProgramNode(0...913)( (157...160) ), DefNode(162...205)( + :foo, (166...169), nil, nil, @@ -299,6 +305,7 @@ ProgramNode(0...913)( (202...205) ), DefNode(207...237)( + :foo, (211...214), nil, nil, @@ -347,6 +354,7 @@ ProgramNode(0...913)( (234...237) ), DefNode(239...269)( + :foo, (243...246), nil, nil, @@ -398,6 +406,7 @@ ProgramNode(0...913)( (266...269) ), DefNode(271...293)( + :foo, (275...278), nil, ParametersNode(279...282)( @@ -419,6 +428,7 @@ ProgramNode(0...913)( (290...293) ), DefNode(295...322)( + :foo, (299...302), nil, ParametersNode(303...311)( @@ -441,6 +451,7 @@ ProgramNode(0...913)( (319...322) ), DefNode(324...351)( + :foo, (328...331), nil, ParametersNode(332...340)( @@ -467,6 +478,7 @@ ProgramNode(0...913)( (348...351) ), DefNode(353...382)( + :foo, (357...360), nil, ParametersNode(361...377)( @@ -510,6 +522,7 @@ ProgramNode(0...913)( (379...382) ), DefNode(384...413)( + :foo, (388...391), nil, ParametersNode(392...402)( @@ -536,6 +549,7 @@ ProgramNode(0...913)( (410...413) ), DefNode(415...449)( + :foo, (419...422), nil, ParametersNode(423...438)( @@ -562,6 +576,7 @@ ProgramNode(0...913)( (446...449) ), DefNode(451...470)( + :foo, (455...458), nil, ParametersNode(459...465)( @@ -587,6 +602,7 @@ ProgramNode(0...913)( (467...470) ), DefNode(472...493)( + :foo, (476...479), nil, ParametersNode(480...488)( @@ -622,6 +638,7 @@ ProgramNode(0...913)( (490...493) ), DefNode(495...518)( + :foo, (499...502), nil, ParametersNode(503...513)( @@ -657,6 +674,7 @@ ProgramNode(0...913)( (515...518) ), DefNode(520...540)( + :foo, (524...527), nil, ParametersNode(528...529)( @@ -690,6 +708,7 @@ ProgramNode(0...913)( (537...540) ), DefNode(542...565)( + :foo, (546...549), nil, ParametersNode(550...554)( @@ -711,6 +730,7 @@ ProgramNode(0...913)( (562...565) ), DefNode(567...595)( + :foo, (571...574), nil, ParametersNode(575...584)( @@ -732,6 +752,7 @@ ProgramNode(0...913)( (592...595) ), DefNode(597...632)( + :foo, (601...604), nil, ParametersNode(605...621)( @@ -770,6 +791,7 @@ ProgramNode(0...913)( (629...632) ), DefNode(634...677)( + :foo, (638...641), nil, ParametersNode(642...666)( @@ -808,6 +830,7 @@ ProgramNode(0...913)( (674...677) ), DefNode(679...719)( + :foo, (683...686), nil, ParametersNode(687...708)( @@ -834,6 +857,7 @@ ProgramNode(0...913)( (716...719) ), DefNode(721...746)( + :foo, (725...728), nil, ParametersNode(729...735)( @@ -867,6 +891,7 @@ ProgramNode(0...913)( (743...746) ), DefNode(748...778)( + :foo, (752...755), nil, ParametersNode(756...767)( @@ -888,6 +913,7 @@ ProgramNode(0...913)( (775...778) ), DefNode(780...803)( + :foo, (784...787), nil, nil, @@ -924,6 +950,7 @@ ProgramNode(0...913)( (800...803) ), DefNode(805...821)( + :f, (809...810), nil, ParametersNode(811...816)( @@ -953,6 +980,7 @@ ProgramNode(0...913)( (818...821) ), DefNode(823...854)( + :foo, (827...830), nil, ParametersNode(831...849)( @@ -984,6 +1012,7 @@ ProgramNode(0...913)( (851...854) ), DefNode(856...896)( + :f, (860...861), nil, nil, @@ -1005,6 +1034,7 @@ ProgramNode(0...913)( (893...896) ), DefNode(898...913)( + :f, (902...903), nil, nil, diff --git a/test/yarp/snapshots/unparser/corpus/literal/defs.txt b/test/yarp/snapshots/unparser/corpus/literal/defs.txt index 0d18f430af83f9..fdc08dcc593218 100644 --- a/test/yarp/snapshots/unparser/corpus/literal/defs.txt +++ b/test/yarp/snapshots/unparser/corpus/literal/defs.txt @@ -2,6 +2,7 @@ ProgramNode(0...266)( [], StatementsNode(0...266)( [DefNode(0...16)( + :foo, (9...12), SelfNode(4...8)(), nil, @@ -15,6 +16,7 @@ ProgramNode(0...266)( (13...16) ), DefNode(18...40)( + :foo, (27...30), SelfNode(22...26)(), nil, @@ -30,6 +32,7 @@ ProgramNode(0...266)( (37...40) ), DefNode(42...70)( + :foo, (51...54), SelfNode(46...50)(), nil, @@ -46,6 +49,7 @@ ProgramNode(0...266)( (67...70) ), DefNode(72...93)( + :bar, (80...83), ConstantReadNode(76...79)(:Foo), nil, @@ -61,6 +65,7 @@ ProgramNode(0...266)( (90...93) ), DefNode(95...128)( + :bar, (115...118), ParenthesesNode(99...114)( CallNode(100...113)( @@ -119,6 +124,7 @@ ProgramNode(0...266)( (125...128) ), DefNode(130...156)( + :bar, (143...146), ParenthesesNode(134...142)( CallNode(135...141)( @@ -158,6 +164,7 @@ ProgramNode(0...266)( (153...156) ), DefNode(158...190)( + :bar, (177...180), ParenthesesNode(162...176)( CallNode(163...175)( @@ -201,6 +208,7 @@ ProgramNode(0...266)( (187...190) ), DefNode(192...220)( + :bar, (207...210), ParenthesesNode(196...206)( ConstantPathNode(197...205)( @@ -234,6 +242,7 @@ ProgramNode(0...266)( (217...220) ), DefNode(222...243)( + :bar, (230...233), ConstantReadNode(226...229)(:Foo), nil, @@ -259,6 +268,7 @@ ProgramNode(0...266)( (240...243) ), DefNode(245...266)( + :bar, (253...256), CallNode(249...252)( nil, diff --git a/test/yarp/snapshots/unparser/corpus/literal/module.txt b/test/yarp/snapshots/unparser/corpus/literal/module.txt index e9b4470d6f02d3..355b57ac531e21 100644 --- a/test/yarp/snapshots/unparser/corpus/literal/module.txt +++ b/test/yarp/snapshots/unparser/corpus/literal/module.txt @@ -66,6 +66,7 @@ ProgramNode(0...106)( "include" ), DefNode(80...102)( + :foo, (84...87), nil, nil, diff --git a/test/yarp/snapshots/unparser/corpus/literal/send.txt b/test/yarp/snapshots/unparser/corpus/literal/send.txt index cc3f23beedbe06..67f3222a0e7eac 100644 --- a/test/yarp/snapshots/unparser/corpus/literal/send.txt +++ b/test/yarp/snapshots/unparser/corpus/literal/send.txt @@ -128,6 +128,7 @@ ProgramNode(0...999)( ParenthesesNode(133...152)( StatementsNode(134...151)( [DefNode(134...145)( + :foo, (138...141), nil, nil, @@ -234,6 +235,7 @@ ProgramNode(0...999)( ), CallNode(218...238)( DefNode(218...234)( + :foo, (227...230), SelfNode(222...226)(), nil, @@ -257,6 +259,7 @@ ProgramNode(0...999)( ), CallNode(239...254)( DefNode(239...250)( + :foo, (243...246), nil, nil, diff --git a/test/yarp/snapshots/unparser/corpus/literal/since/31.txt b/test/yarp/snapshots/unparser/corpus/literal/since/31.txt index f21bf30e0473d2..c5f903bbeb431b 100644 --- a/test/yarp/snapshots/unparser/corpus/literal/since/31.txt +++ b/test/yarp/snapshots/unparser/corpus/literal/since/31.txt @@ -2,6 +2,7 @@ ProgramNode(0...51)( [], StatementsNode(0...51)( [DefNode(0...23)( + :foo, (4...7), nil, ParametersNode(8...9)( @@ -37,6 +38,7 @@ ProgramNode(0...51)( (20...23) ), DefNode(25...51)( + :foo, (29...32), nil, ParametersNode(33...37)( diff --git a/test/yarp/snapshots/unparser/corpus/literal/since/32.txt b/test/yarp/snapshots/unparser/corpus/literal/since/32.txt index eeae33beb74905..b6335ced8668eb 100644 --- a/test/yarp/snapshots/unparser/corpus/literal/since/32.txt +++ b/test/yarp/snapshots/unparser/corpus/literal/since/32.txt @@ -2,6 +2,7 @@ ProgramNode(0...90)( [], StatementsNode(0...90)( [DefNode(0...45)( + :foo, (4...7), nil, ParametersNode(8...20)( @@ -40,6 +41,7 @@ ProgramNode(0...90)( (42...45) ), DefNode(47...90)( + :foo, (51...54), nil, ParametersNode(55...66)( diff --git a/test/yarp/snapshots/unparser/corpus/literal/while.txt b/test/yarp/snapshots/unparser/corpus/literal/while.txt index 6d90f455398891..f6dc399041a381 100644 --- a/test/yarp/snapshots/unparser/corpus/literal/while.txt +++ b/test/yarp/snapshots/unparser/corpus/literal/while.txt @@ -67,6 +67,7 @@ ProgramNode(0...620)( :A ), DefNode(70...110)( + :foo, (74...77), nil, nil, diff --git a/test/yarp/snapshots/unparser/corpus/semantic/def.txt b/test/yarp/snapshots/unparser/corpus/semantic/def.txt index 46c69936a44504..428b7138cb4051 100644 --- a/test/yarp/snapshots/unparser/corpus/semantic/def.txt +++ b/test/yarp/snapshots/unparser/corpus/semantic/def.txt @@ -2,6 +2,7 @@ ProgramNode(0...55)( [], StatementsNode(0...55)( [DefNode(0...21)( + :foo, (4...7), nil, nil, @@ -55,6 +56,7 @@ ProgramNode(0...55)( (18...21) ), DefNode(23...55)( + :foo, (27...30), nil, nil, diff --git a/test/yarp/snapshots/while.txt b/test/yarp/snapshots/while.txt index aeb0fc9b0dde7a..078df5066c7aa2 100644 --- a/test/yarp/snapshots/while.txt +++ b/test/yarp/snapshots/while.txt @@ -72,6 +72,7 @@ ProgramNode(0...314)( (111...116), (158...161), DefNode(117...149)( + :foo, (126...129), SelfNode(121...125)(), ParametersNode(130...144)( diff --git a/test/yarp/snapshots/whitequark/anonymous_blockarg.txt b/test/yarp/snapshots/whitequark/anonymous_blockarg.txt index d5c7ef56dd86ea..af34a92864742f 100644 --- a/test/yarp/snapshots/whitequark/anonymous_blockarg.txt +++ b/test/yarp/snapshots/whitequark/anonymous_blockarg.txt @@ -2,6 +2,7 @@ ProgramNode(0...23)( [], StatementsNode(0...23)( [DefNode(0...23)( + :foo, (4...7), nil, ParametersNode(8...9)( diff --git a/test/yarp/snapshots/whitequark/arg.txt b/test/yarp/snapshots/whitequark/arg.txt index 403c382cb7b180..037d3eb070782d 100644 --- a/test/yarp/snapshots/whitequark/arg.txt +++ b/test/yarp/snapshots/whitequark/arg.txt @@ -2,6 +2,7 @@ ProgramNode(0...37)( [], StatementsNode(0...37)( [DefNode(0...15)( + :f, (4...5), nil, ParametersNode(6...9)( @@ -23,6 +24,7 @@ ProgramNode(0...37)( (12...15) ), DefNode(17...37)( + :f, (21...22), nil, ParametersNode(23...31)( diff --git a/test/yarp/snapshots/whitequark/arg_duplicate_ignored.txt b/test/yarp/snapshots/whitequark/arg_duplicate_ignored.txt index 5c88c71d506105..304ca36eba773c 100644 --- a/test/yarp/snapshots/whitequark/arg_duplicate_ignored.txt +++ b/test/yarp/snapshots/whitequark/arg_duplicate_ignored.txt @@ -2,6 +2,7 @@ ProgramNode(0...40)( [], StatementsNode(0...40)( [DefNode(0...18)( + :foo, (4...7), nil, ParametersNode(8...12)( @@ -24,6 +25,7 @@ ProgramNode(0...40)( (15...18) ), DefNode(20...40)( + :foo, (24...27), nil, ParametersNode(28...34)( diff --git a/test/yarp/snapshots/whitequark/arg_label.txt b/test/yarp/snapshots/whitequark/arg_label.txt index cfa55d0124f8b5..40014d7289896f 100644 --- a/test/yarp/snapshots/whitequark/arg_label.txt +++ b/test/yarp/snapshots/whitequark/arg_label.txt @@ -2,6 +2,7 @@ ProgramNode(0...49)( [], StatementsNode(0...49)( [DefNode(0...16)( + :foo, (4...7), nil, nil, @@ -29,6 +30,7 @@ ProgramNode(0...49)( (13...16) ), DefNode(18...35)( + :foo, (22...25), nil, nil, diff --git a/test/yarp/snapshots/whitequark/args.txt b/test/yarp/snapshots/whitequark/args.txt index 21764cccc2678c..7ee971121e4319 100644 --- a/test/yarp/snapshots/whitequark/args.txt +++ b/test/yarp/snapshots/whitequark/args.txt @@ -2,6 +2,7 @@ ProgramNode(0...690)( [], StatementsNode(0...690)( [DefNode(0...13)( + :f, (4...5), nil, ParametersNode(6...8)( @@ -23,6 +24,7 @@ ProgramNode(0...690)( (10...13) ), DefNode(15...33)( + :f, (19...20), nil, ParametersNode(22...27)( @@ -52,6 +54,7 @@ ProgramNode(0...690)( (30...33) ), DefNode(35...51)( + :f, (39...40), nil, ParametersNode(42...45)( @@ -77,6 +80,7 @@ ProgramNode(0...690)( (48...51) ), DefNode(53...72)( + :f, (57...58), nil, ParametersNode(60...66)( @@ -103,6 +107,7 @@ ProgramNode(0...690)( (69...72) ), DefNode(74...91)( + :f, (78...79), nil, ParametersNode(81...85)( @@ -131,6 +136,7 @@ ProgramNode(0...690)( (88...91) ), DefNode(93...113)( + :f, (97...98), nil, ParametersNode(100...107)( @@ -160,6 +166,7 @@ ProgramNode(0...690)( (110...113) ), DefNode(115...134)( + :f, (119...120), nil, ParametersNode(122...128)( @@ -186,6 +193,7 @@ ProgramNode(0...690)( (131...134) ), DefNode(136...158)( + :f, (140...141), nil, ParametersNode(143...152)( @@ -213,6 +221,7 @@ ProgramNode(0...690)( (155...158) ), DefNode(160...180)( + :f, (164...165), nil, ParametersNode(167...174)( @@ -242,6 +251,7 @@ ProgramNode(0...690)( (177...180) ), DefNode(182...205)( + :f, (186...187), nil, ParametersNode(189...199)( @@ -272,6 +282,7 @@ ProgramNode(0...690)( (202...205) ), DefNode(207...227)( + :f, (211...212), nil, ParametersNode(214...221)( @@ -298,6 +309,7 @@ ProgramNode(0...690)( (224...227) ), DefNode(229...252)( + :f, (233...234), nil, ParametersNode(236...246)( @@ -323,6 +335,7 @@ ProgramNode(0...690)( (249...252) ), DefNode(254...292)( + :f, (258...259), nil, ParametersNode(261...286)( @@ -353,6 +366,7 @@ ProgramNode(0...690)( (289...292) ), DefNode(294...314)( + :f, (298...299), nil, ParametersNode(300...309)( @@ -374,6 +388,7 @@ ProgramNode(0...690)( (311...314) ), DefNode(316...332)( + :f, (320...321), nil, ParametersNode(322...327)( @@ -395,6 +410,7 @@ ProgramNode(0...690)( (329...332) ), DefNode(334...351)( + :f, (338...339), nil, ParametersNode(340...346)( @@ -416,6 +432,7 @@ ProgramNode(0...690)( (348...351) ), DefNode(353...373)( + :f, (357...358), nil, ParametersNode(359...368)( @@ -437,6 +454,7 @@ ProgramNode(0...690)( (370...373) ), DefNode(375...386)( + :f, (379...380), nil, nil, @@ -450,6 +468,7 @@ ProgramNode(0...690)( (383...386) ), DefNode(388...404)( + :f, (392...393), nil, ParametersNode(394...399)( @@ -471,6 +490,7 @@ ProgramNode(0...690)( (401...404) ), DefNode(406...426)( + :f, (410...411), nil, ParametersNode(412...421)( @@ -492,6 +512,7 @@ ProgramNode(0...690)( (423...426) ), DefNode(428...451)( + :f, (432...433), nil, ParametersNode(434...446)( @@ -513,6 +534,7 @@ ProgramNode(0...690)( (448...451) ), DefNode(453...474)( + :f, (457...458), nil, ParametersNode(459...469)( @@ -539,6 +561,7 @@ ProgramNode(0...690)( (471...474) ), DefNode(476...501)( + :f, (480...481), nil, ParametersNode(482...496)( @@ -565,6 +588,7 @@ ProgramNode(0...690)( (498...501) ), DefNode(503...531)( + :f, (507...508), nil, ParametersNode(509...526)( @@ -591,6 +615,7 @@ ProgramNode(0...690)( (528...531) ), DefNode(533...557)( + :f, (537...538), nil, ParametersNode(539...552)( @@ -617,6 +642,7 @@ ProgramNode(0...690)( (554...557) ), DefNode(559...575)( + :f, (563...564), nil, ParametersNode(565...569)( @@ -638,6 +664,7 @@ ProgramNode(0...690)( (572...575) ), DefNode(577...596)( + :f, (581...582), nil, ParametersNode(583...590)( @@ -663,6 +690,7 @@ ProgramNode(0...690)( (593...596) ), DefNode(598...616)( + :f, (602...603), nil, ParametersNode(604...611)( @@ -689,6 +717,7 @@ ProgramNode(0...690)( (613...616) ), DefNode(618...640)( + :f, (622...623), nil, ParametersNode(624...635)( @@ -715,6 +744,7 @@ ProgramNode(0...690)( (637...640) ), DefNode(642...667)( + :f, (646...647), nil, ParametersNode(648...662)( @@ -741,6 +771,7 @@ ProgramNode(0...690)( (664...667) ), DefNode(669...690)( + :f, (673...674), nil, ParametersNode(675...685)( diff --git a/test/yarp/snapshots/whitequark/blockarg.txt b/test/yarp/snapshots/whitequark/blockarg.txt index 4e31eac3d8bf36..67e1db44df6148 100644 --- a/test/yarp/snapshots/whitequark/blockarg.txt +++ b/test/yarp/snapshots/whitequark/blockarg.txt @@ -2,6 +2,7 @@ ProgramNode(0...18)( [], StatementsNode(0...18)( [DefNode(0...18)( + :f, (4...5), nil, ParametersNode(6...12)( diff --git a/test/yarp/snapshots/whitequark/bug_481.txt b/test/yarp/snapshots/whitequark/bug_481.txt index 1bd74e12353bfe..5bdeaf1d47b6fe 100644 --- a/test/yarp/snapshots/whitequark/bug_481.txt +++ b/test/yarp/snapshots/whitequark/bug_481.txt @@ -8,6 +8,7 @@ ProgramNode(0...28)( nil, ArgumentsNode(2...14)( [DefNode(2...14)( + :x, (6...7), nil, nil, diff --git a/test/yarp/snapshots/whitequark/bug_def_no_paren_eql_begin.txt b/test/yarp/snapshots/whitequark/bug_def_no_paren_eql_begin.txt index 12efa14109cf3b..24159031ce2c6b 100644 --- a/test/yarp/snapshots/whitequark/bug_def_no_paren_eql_begin.txt +++ b/test/yarp/snapshots/whitequark/bug_def_no_paren_eql_begin.txt @@ -2,6 +2,7 @@ ProgramNode(0...23)( [], StatementsNode(0...23)( [DefNode(0...23)( + :foo, (4...7), nil, nil, diff --git a/test/yarp/snapshots/whitequark/bug_do_block_in_call_args.txt b/test/yarp/snapshots/whitequark/bug_do_block_in_call_args.txt index 555819dfbd0584..70ce5db09ba15c 100644 --- a/test/yarp/snapshots/whitequark/bug_do_block_in_call_args.txt +++ b/test/yarp/snapshots/whitequark/bug_do_block_in_call_args.txt @@ -8,6 +8,7 @@ ProgramNode(0...33)( nil, ArgumentsNode(4...33)( [DefNode(4...33)( + :foo, (8...11), nil, nil, diff --git a/test/yarp/snapshots/whitequark/const_op_asgn.txt b/test/yarp/snapshots/whitequark/const_op_asgn.txt index d417c5d1c915a0..1b177334156c3e 100644 --- a/test/yarp/snapshots/whitequark/const_op_asgn.txt +++ b/test/yarp/snapshots/whitequark/const_op_asgn.txt @@ -25,6 +25,7 @@ ProgramNode(0...77)( :+ ), DefNode(29...50)( + :x, (33...34), nil, nil, @@ -48,6 +49,7 @@ ProgramNode(0...77)( (47...50) ), DefNode(52...77)( + :x, (56...57), nil, nil, diff --git a/test/yarp/snapshots/whitequark/def.txt b/test/yarp/snapshots/whitequark/def.txt index f7454765332967..383b2a666cffbc 100644 --- a/test/yarp/snapshots/whitequark/def.txt +++ b/test/yarp/snapshots/whitequark/def.txt @@ -2,6 +2,7 @@ ProgramNode(0...93)( [], StatementsNode(0...93)( [DefNode(0...14)( + :BEGIN, (4...9), nil, nil, @@ -15,6 +16,7 @@ ProgramNode(0...93)( (11...14) ), DefNode(16...28)( + :END, (20...23), nil, nil, @@ -28,6 +30,7 @@ ProgramNode(0...93)( (25...28) ), DefNode(30...45)( + :String, (34...40), nil, nil, @@ -41,6 +44,7 @@ ProgramNode(0...93)( (42...45) ), DefNode(47...63)( + :String=, (51...58), nil, nil, @@ -54,6 +58,7 @@ ProgramNode(0...93)( (60...63) ), DefNode(65...77)( + :foo, (69...72), nil, nil, @@ -67,6 +72,7 @@ ProgramNode(0...93)( (74...77) ), DefNode(79...93)( + :until, (83...88), nil, nil, diff --git a/test/yarp/snapshots/whitequark/defs.txt b/test/yarp/snapshots/whitequark/defs.txt index 372edbfdcd0eee..6072d21645f4c7 100644 --- a/test/yarp/snapshots/whitequark/defs.txt +++ b/test/yarp/snapshots/whitequark/defs.txt @@ -2,6 +2,7 @@ ProgramNode(0...100)( [], StatementsNode(0...100)( [DefNode(0...18)( + :foo, (10...13), ParenthesesNode(4...9)( CallNode(5...8)(nil, nil, (5...8), nil, nil, nil, nil, 2, "foo"), @@ -19,6 +20,7 @@ ProgramNode(0...100)( (15...18) ), DefNode(20...39)( + :foo, (31...34), ConstantReadNode(24...30)(:String), nil, @@ -32,6 +34,7 @@ ProgramNode(0...100)( (36...39) ), DefNode(41...61)( + :foo, (53...56), ConstantReadNode(45...51)(:String), nil, @@ -45,6 +48,7 @@ ProgramNode(0...100)( (58...61) ), DefNode(63...80)( + :foo, (72...75), SelfNode(67...71)(), nil, @@ -58,6 +62,7 @@ ProgramNode(0...100)( (77...80) ), DefNode(82...100)( + :foo, (92...95), SelfNode(86...90)(), nil, diff --git a/test/yarp/snapshots/whitequark/endless_comparison_method.txt b/test/yarp/snapshots/whitequark/endless_comparison_method.txt index fa83705659563d..b0d3b33aca3106 100644 --- a/test/yarp/snapshots/whitequark/endless_comparison_method.txt +++ b/test/yarp/snapshots/whitequark/endless_comparison_method.txt @@ -2,6 +2,7 @@ ProgramNode(0...179)( [], StatementsNode(0...179)( [DefNode(0...28)( + :!=, (4...6), nil, ParametersNode(7...12)( @@ -35,6 +36,7 @@ ProgramNode(0...179)( nil ), DefNode(30...58)( + :!=, (34...36), nil, ParametersNode(37...42)( @@ -68,6 +70,7 @@ ProgramNode(0...179)( nil ), DefNode(60...88)( + :<=, (64...66), nil, ParametersNode(67...72)( @@ -101,6 +104,7 @@ ProgramNode(0...179)( nil ), DefNode(90...118)( + :==, (94...96), nil, ParametersNode(97...102)( @@ -134,6 +138,7 @@ ProgramNode(0...179)( nil ), DefNode(120...149)( + :===, (124...127), nil, ParametersNode(128...133)( @@ -167,6 +172,7 @@ ProgramNode(0...179)( nil ), DefNode(151...179)( + :>=, (155...157), nil, ParametersNode(158...163)( diff --git a/test/yarp/snapshots/whitequark/endless_method.txt b/test/yarp/snapshots/whitequark/endless_method.txt index a80e6b57db8414..c81dd69456c359 100644 --- a/test/yarp/snapshots/whitequark/endless_method.txt +++ b/test/yarp/snapshots/whitequark/endless_method.txt @@ -2,6 +2,7 @@ ProgramNode(0...78)( [], StatementsNode(0...78)( [DefNode(0...14)( + :foo, (4...7), nil, nil, @@ -15,6 +16,7 @@ ProgramNode(0...78)( nil ), DefNode(16...34)( + :inc, (20...23), nil, ParametersNode(24...25)( @@ -48,6 +50,7 @@ ProgramNode(0...78)( nil ), DefNode(36...54)( + :foo, (44...47), CallNode(40...43)(nil, nil, (40...43), nil, nil, nil, nil, 2, "obj"), nil, @@ -61,6 +64,7 @@ ProgramNode(0...78)( nil ), DefNode(56...78)( + :inc, (64...67), CallNode(60...63)(nil, nil, (60...63), nil, nil, nil, nil, 2, "obj"), ParametersNode(68...69)( diff --git a/test/yarp/snapshots/whitequark/endless_method_command_syntax.txt b/test/yarp/snapshots/whitequark/endless_method_command_syntax.txt index 33c64edfed2456..3015996dde90db 100644 --- a/test/yarp/snapshots/whitequark/endless_method_command_syntax.txt +++ b/test/yarp/snapshots/whitequark/endless_method_command_syntax.txt @@ -2,6 +2,7 @@ ProgramNode(0...278)( [], StatementsNode(0...278)( [DefNode(0...22)( + :foo, (4...7), nil, nil, @@ -29,6 +30,7 @@ ProgramNode(0...278)( nil ), DefNode(24...48)( + :foo, (28...31), nil, nil, @@ -56,6 +58,7 @@ ProgramNode(0...278)( nil ), DefNode(50...69)( + :foo, (54...57), nil, ParametersNode(58...59)( @@ -89,6 +92,7 @@ ProgramNode(0...278)( nil ), DefNode(71...97)( + :foo, (79...82), CallNode(75...78)(nil, nil, (75...78), nil, nil, nil, nil, 2, "obj"), nil, @@ -116,6 +120,7 @@ ProgramNode(0...278)( nil ), DefNode(99...127)( + :foo, (107...110), CallNode(103...106)( nil, @@ -158,6 +163,7 @@ ProgramNode(0...278)( nil ), DefNode(129...152)( + :foo, (137...140), CallNode(133...136)( nil, @@ -203,6 +209,7 @@ ProgramNode(0...278)( nil ), DefNode(154...214)( + :rescued, (158...165), nil, ParametersNode(166...167)( @@ -258,6 +265,7 @@ ProgramNode(0...278)( nil ), DefNode(216...278)( + :rescued, (225...232), SelfNode(220...224)(), ParametersNode(233...234)( diff --git a/test/yarp/snapshots/whitequark/endless_method_forwarded_args_legacy.txt b/test/yarp/snapshots/whitequark/endless_method_forwarded_args_legacy.txt index 87c50ca846c80c..c60263dc9afbbb 100644 --- a/test/yarp/snapshots/whitequark/endless_method_forwarded_args_legacy.txt +++ b/test/yarp/snapshots/whitequark/endless_method_forwarded_args_legacy.txt @@ -2,6 +2,7 @@ ProgramNode(0...23)( [], StatementsNode(0...23)( [DefNode(0...23)( + :foo, (4...7), nil, ParametersNode(8...11)( diff --git a/test/yarp/snapshots/whitequark/endless_method_with_rescue_mod.txt b/test/yarp/snapshots/whitequark/endless_method_with_rescue_mod.txt index ac757efdbb7b30..3f77cf8c238a3b 100644 --- a/test/yarp/snapshots/whitequark/endless_method_with_rescue_mod.txt +++ b/test/yarp/snapshots/whitequark/endless_method_with_rescue_mod.txt @@ -2,6 +2,7 @@ ProgramNode(0...47)( [], StatementsNode(0...47)( [DefNode(0...20)( + :m, (4...5), nil, nil, @@ -21,6 +22,7 @@ ProgramNode(0...47)( nil ), DefNode(22...47)( + :m, (31...32), SelfNode(26...30)(), nil, diff --git a/test/yarp/snapshots/whitequark/endless_method_without_args.txt b/test/yarp/snapshots/whitequark/endless_method_without_args.txt index 778c2b595b97da..7287c14cd8564a 100644 --- a/test/yarp/snapshots/whitequark/endless_method_without_args.txt +++ b/test/yarp/snapshots/whitequark/endless_method_without_args.txt @@ -2,6 +2,7 @@ ProgramNode(0...86)( [], StatementsNode(0...86)( [DefNode(0...12)( + :foo, (4...7), nil, nil, @@ -15,6 +16,7 @@ ProgramNode(0...86)( nil ), DefNode(14...37)( + :foo, (18...21), nil, nil, @@ -34,6 +36,7 @@ ProgramNode(0...86)( nil ), DefNode(39...56)( + :foo, (48...51), SelfNode(43...47)(), nil, @@ -47,6 +50,7 @@ ProgramNode(0...86)( nil ), DefNode(58...86)( + :foo, (67...70), SelfNode(62...66)(), nil, diff --git a/test/yarp/snapshots/whitequark/forward_arg.txt b/test/yarp/snapshots/whitequark/forward_arg.txt index 449db10831ea72..896555a27e8979 100644 --- a/test/yarp/snapshots/whitequark/forward_arg.txt +++ b/test/yarp/snapshots/whitequark/forward_arg.txt @@ -2,6 +2,7 @@ ProgramNode(0...27)( [], StatementsNode(0...27)( [DefNode(0...27)( + :foo, (4...7), nil, ParametersNode(8...11)( diff --git a/test/yarp/snapshots/whitequark/forward_arg_with_open_args.txt b/test/yarp/snapshots/whitequark/forward_arg_with_open_args.txt index 55352e9d70ca24..e4ebb2d950c85b 100644 --- a/test/yarp/snapshots/whitequark/forward_arg_with_open_args.txt +++ b/test/yarp/snapshots/whitequark/forward_arg_with_open_args.txt @@ -4,6 +4,7 @@ ProgramNode(0...292)( [ParenthesesNode(0...28)( StatementsNode(1...27)( [DefNode(1...27)( + :foo, (5...8), nil, ParametersNode(9...12)( @@ -43,6 +44,7 @@ ProgramNode(0...292)( ParenthesesNode(30...58)( StatementsNode(31...57)( [DefNode(31...57)( + :foo, (35...38), nil, ParametersNode(39...42)( @@ -80,6 +82,7 @@ ProgramNode(0...292)( (57...58) ), DefNode(60...75)( + :foo, (64...67), nil, ParametersNode(68...71)( @@ -101,6 +104,7 @@ ProgramNode(0...292)( (72...75) ), DefNode(77...103)( + :foo, (81...84), nil, ParametersNode(85...88)( @@ -134,6 +138,7 @@ ProgramNode(0...292)( (100...103) ), DefNode(105...134)( + :foo, (109...112), nil, ParametersNode(113...119)( @@ -167,6 +172,7 @@ ProgramNode(0...292)( (131...134) ), DefNode(136...165)( + :foo, (140...143), nil, ParametersNode(144...150)( @@ -200,6 +206,7 @@ ProgramNode(0...292)( (162...165) ), DefNode(167...192)( + :foo, (171...174), nil, ParametersNode(175...188)( @@ -226,6 +233,7 @@ ProgramNode(0...292)( (189...192) ), DefNode(194...227)( + :foo, (198...201), nil, ParametersNode(202...212)( @@ -264,6 +272,7 @@ ProgramNode(0...292)( (224...227) ), DefNode(229...262)( + :foo, (233...236), nil, ParametersNode(237...247)( @@ -302,6 +311,7 @@ ProgramNode(0...292)( (259...262) ), DefNode(264...292)( + :foo, (268...271), nil, ParametersNode(272...278)( diff --git a/test/yarp/snapshots/whitequark/forward_args_legacy.txt b/test/yarp/snapshots/whitequark/forward_args_legacy.txt index eeaf4f1d537c89..39b5cdbbaf87c4 100644 --- a/test/yarp/snapshots/whitequark/forward_args_legacy.txt +++ b/test/yarp/snapshots/whitequark/forward_args_legacy.txt @@ -2,6 +2,7 @@ ProgramNode(0...77)( [], StatementsNode(0...77)( [DefNode(0...27)( + :foo, (4...7), nil, ParametersNode(8...11)( @@ -35,6 +36,7 @@ ProgramNode(0...77)( (24...27) ), DefNode(29...46)( + :foo, (33...36), nil, ParametersNode(37...40)( @@ -56,6 +58,7 @@ ProgramNode(0...77)( (43...46) ), DefNode(48...77)( + :foo, (52...55), nil, ParametersNode(56...59)( diff --git a/test/yarp/snapshots/whitequark/forwarded_argument_with_kwrestarg.txt b/test/yarp/snapshots/whitequark/forwarded_argument_with_kwrestarg.txt index da165e8e71a72a..9008112a49ff2f 100644 --- a/test/yarp/snapshots/whitequark/forwarded_argument_with_kwrestarg.txt +++ b/test/yarp/snapshots/whitequark/forwarded_argument_with_kwrestarg.txt @@ -2,6 +2,7 @@ ProgramNode(0...45)( [], StatementsNode(0...45)( [DefNode(0...45)( + :foo, (4...7), nil, ParametersNode(8...20)( diff --git a/test/yarp/snapshots/whitequark/forwarded_argument_with_restarg.txt b/test/yarp/snapshots/whitequark/forwarded_argument_with_restarg.txt index d2ef1999333a95..842def39c5cca8 100644 --- a/test/yarp/snapshots/whitequark/forwarded_argument_with_restarg.txt +++ b/test/yarp/snapshots/whitequark/forwarded_argument_with_restarg.txt @@ -2,6 +2,7 @@ ProgramNode(0...43)( [], StatementsNode(0...43)( [DefNode(0...43)( + :foo, (4...7), nil, ParametersNode(8...19)( diff --git a/test/yarp/snapshots/whitequark/forwarded_kwrestarg.txt b/test/yarp/snapshots/whitequark/forwarded_kwrestarg.txt index 51d8720fe6c819..264c73a6c32020 100644 --- a/test/yarp/snapshots/whitequark/forwarded_kwrestarg.txt +++ b/test/yarp/snapshots/whitequark/forwarded_kwrestarg.txt @@ -2,6 +2,7 @@ ProgramNode(0...25)( [], StatementsNode(0...25)( [DefNode(0...25)( + :foo, (4...7), nil, ParametersNode(8...10)( diff --git a/test/yarp/snapshots/whitequark/forwarded_kwrestarg_with_additional_kwarg.txt b/test/yarp/snapshots/whitequark/forwarded_kwrestarg_with_additional_kwarg.txt index e0d078128b6897..aa815fce8e35b0 100644 --- a/test/yarp/snapshots/whitequark/forwarded_kwrestarg_with_additional_kwarg.txt +++ b/test/yarp/snapshots/whitequark/forwarded_kwrestarg_with_additional_kwarg.txt @@ -2,6 +2,7 @@ ProgramNode(0...41)( [], StatementsNode(0...41)( [DefNode(0...41)( + :foo, (4...7), nil, ParametersNode(8...10)( diff --git a/test/yarp/snapshots/whitequark/forwarded_restarg.txt b/test/yarp/snapshots/whitequark/forwarded_restarg.txt index 485032d487d2fd..40384fce94e885 100644 --- a/test/yarp/snapshots/whitequark/forwarded_restarg.txt +++ b/test/yarp/snapshots/whitequark/forwarded_restarg.txt @@ -2,6 +2,7 @@ ProgramNode(0...23)( [], StatementsNode(0...23)( [DefNode(0...23)( + :foo, (4...7), nil, ParametersNode(8...9)( diff --git a/test/yarp/snapshots/whitequark/kwarg.txt b/test/yarp/snapshots/whitequark/kwarg.txt index 9b605f5c5e5933..b63c7ac9f53fba 100644 --- a/test/yarp/snapshots/whitequark/kwarg.txt +++ b/test/yarp/snapshots/whitequark/kwarg.txt @@ -2,6 +2,7 @@ ProgramNode(0...16)( [], StatementsNode(0...16)( [DefNode(0...16)( + :f, (4...5), nil, ParametersNode(6...10)( diff --git a/test/yarp/snapshots/whitequark/kwnilarg.txt b/test/yarp/snapshots/whitequark/kwnilarg.txt index 0995a597c26dfa..402d0d3fb28028 100644 --- a/test/yarp/snapshots/whitequark/kwnilarg.txt +++ b/test/yarp/snapshots/whitequark/kwnilarg.txt @@ -23,6 +23,7 @@ ProgramNode(0...46)( nil ), DefNode(14...31)( + :f, (18...19), nil, ParametersNode(20...25)( diff --git a/test/yarp/snapshots/whitequark/kwoptarg.txt b/test/yarp/snapshots/whitequark/kwoptarg.txt index effee043fad37b..06ad7985233118 100644 --- a/test/yarp/snapshots/whitequark/kwoptarg.txt +++ b/test/yarp/snapshots/whitequark/kwoptarg.txt @@ -2,6 +2,7 @@ ProgramNode(0...18)( [], StatementsNode(0...18)( [DefNode(0...18)( + :f, (4...5), nil, ParametersNode(6...12)( diff --git a/test/yarp/snapshots/whitequark/kwoptarg_with_kwrestarg_and_forwarded_args.txt b/test/yarp/snapshots/whitequark/kwoptarg_with_kwrestarg_and_forwarded_args.txt index bd1c1e6e54de28..dfc20df0b4cf81 100644 --- a/test/yarp/snapshots/whitequark/kwoptarg_with_kwrestarg_and_forwarded_args.txt +++ b/test/yarp/snapshots/whitequark/kwoptarg_with_kwrestarg_and_forwarded_args.txt @@ -2,6 +2,7 @@ ProgramNode(0...28)( [], StatementsNode(0...28)( [DefNode(0...28)( + :f, (4...5), nil, ParametersNode(6...16)( diff --git a/test/yarp/snapshots/whitequark/kwrestarg_named.txt b/test/yarp/snapshots/whitequark/kwrestarg_named.txt index 2dd4c0225e9a0d..cf0086619fe2bd 100644 --- a/test/yarp/snapshots/whitequark/kwrestarg_named.txt +++ b/test/yarp/snapshots/whitequark/kwrestarg_named.txt @@ -2,6 +2,7 @@ ProgramNode(0...17)( [], StatementsNode(0...17)( [DefNode(0...17)( + :f, (4...5), nil, ParametersNode(6...11)( diff --git a/test/yarp/snapshots/whitequark/kwrestarg_unnamed.txt b/test/yarp/snapshots/whitequark/kwrestarg_unnamed.txt index 3fa1dcd7fedcc3..e59e72c3042ef1 100644 --- a/test/yarp/snapshots/whitequark/kwrestarg_unnamed.txt +++ b/test/yarp/snapshots/whitequark/kwrestarg_unnamed.txt @@ -2,6 +2,7 @@ ProgramNode(0...14)( [], StatementsNode(0...14)( [DefNode(0...14)( + :f, (4...5), nil, ParametersNode(6...8)( diff --git a/test/yarp/snapshots/whitequark/method_definition_in_while_cond.txt b/test/yarp/snapshots/whitequark/method_definition_in_while_cond.txt index 3179d39b959edc..099ae9398640c2 100644 --- a/test/yarp/snapshots/whitequark/method_definition_in_while_cond.txt +++ b/test/yarp/snapshots/whitequark/method_definition_in_while_cond.txt @@ -5,6 +5,7 @@ ProgramNode(0...190)( (0...5), (42...45), DefNode(6...33)( + :foo, (10...13), nil, ParametersNode(14...28)( @@ -47,6 +48,7 @@ ProgramNode(0...190)( (47...52), (86...89), DefNode(53...77)( + :foo, (57...60), nil, nil, @@ -78,6 +80,7 @@ ProgramNode(0...190)( (91...96), (138...141), DefNode(97...129)( + :foo, (106...109), SelfNode(101...105)(), ParametersNode(110...124)( @@ -120,6 +123,7 @@ ProgramNode(0...190)( (143...148), (187...190), DefNode(149...178)( + :foo, (158...161), SelfNode(153...157)(), nil, diff --git a/test/yarp/snapshots/whitequark/numparam_outside_block.txt b/test/yarp/snapshots/whitequark/numparam_outside_block.txt index 5b41378aa7438c..0dff33b0a99b56 100644 --- a/test/yarp/snapshots/whitequark/numparam_outside_block.txt +++ b/test/yarp/snapshots/whitequark/numparam_outside_block.txt @@ -25,6 +25,7 @@ ProgramNode(0...83)( :A ), DefNode(45...64)( + :m, (54...55), SelfNode(49...53)(), nil, diff --git a/test/yarp/snapshots/whitequark/optarg.txt b/test/yarp/snapshots/whitequark/optarg.txt index 2cbb681c617ec8..f2a0dd24371dd7 100644 --- a/test/yarp/snapshots/whitequark/optarg.txt +++ b/test/yarp/snapshots/whitequark/optarg.txt @@ -2,6 +2,7 @@ ProgramNode(0...44)( [], StatementsNode(0...44)( [DefNode(0...18)( + :f, (4...5), nil, ParametersNode(6...13)( @@ -28,6 +29,7 @@ ProgramNode(0...44)( (15...18) ), DefNode(20...44)( + :f, (24...25), nil, ParametersNode(26...38)( diff --git a/test/yarp/snapshots/whitequark/parser_bug_490.txt b/test/yarp/snapshots/whitequark/parser_bug_490.txt index a82c7d1bb79059..5c087b60f659e7 100644 --- a/test/yarp/snapshots/whitequark/parser_bug_490.txt +++ b/test/yarp/snapshots/whitequark/parser_bug_490.txt @@ -2,6 +2,7 @@ ProgramNode(0...132)( [], StatementsNode(0...132)( [DefNode(0...39)( + :m, (4...5), nil, nil, @@ -31,6 +32,7 @@ ProgramNode(0...132)( (36...39) ), DefNode(41...85)( + :m, (45...46), nil, nil, @@ -64,6 +66,7 @@ ProgramNode(0...132)( (82...85) ), DefNode(87...132)( + :m, (91...92), nil, nil, diff --git a/test/yarp/snapshots/whitequark/restarg_named.txt b/test/yarp/snapshots/whitequark/restarg_named.txt index 9883a44ed6ac67..d3eed889c6f03e 100644 --- a/test/yarp/snapshots/whitequark/restarg_named.txt +++ b/test/yarp/snapshots/whitequark/restarg_named.txt @@ -2,6 +2,7 @@ ProgramNode(0...16)( [], StatementsNode(0...16)( [DefNode(0...16)( + :f, (4...5), nil, ParametersNode(6...10)( diff --git a/test/yarp/snapshots/whitequark/restarg_unnamed.txt b/test/yarp/snapshots/whitequark/restarg_unnamed.txt index 8f282e126a07a7..a15f667603c2ea 100644 --- a/test/yarp/snapshots/whitequark/restarg_unnamed.txt +++ b/test/yarp/snapshots/whitequark/restarg_unnamed.txt @@ -2,6 +2,7 @@ ProgramNode(0...13)( [], StatementsNode(0...13)( [DefNode(0...13)( + :f, (4...5), nil, ParametersNode(6...7)( diff --git a/test/yarp/snapshots/whitequark/ruby_bug_12073.txt b/test/yarp/snapshots/whitequark/ruby_bug_12073.txt index 0688332fd34292..29ac50831d05a7 100644 --- a/test/yarp/snapshots/whitequark/ruby_bug_12073.txt +++ b/test/yarp/snapshots/whitequark/ruby_bug_12073.txt @@ -28,6 +28,7 @@ ProgramNode(0...49)( "a" ), DefNode(15...49)( + :foo, (19...22), nil, ParametersNode(23...28)( diff --git a/test/yarp/snapshots/whitequark/ruby_bug_9669.txt b/test/yarp/snapshots/whitequark/ruby_bug_9669.txt index aad27053bbcc7c..c79fad99415a43 100644 --- a/test/yarp/snapshots/whitequark/ruby_bug_9669.txt +++ b/test/yarp/snapshots/whitequark/ruby_bug_9669.txt @@ -2,6 +2,7 @@ ProgramNode(0...33)( [:o], StatementsNode(0...33)( [DefNode(0...19)( + :a, (4...5), nil, ParametersNode(6...8)( diff --git a/test/yarp/snapshots/whitequark/trailing_forward_arg.txt b/test/yarp/snapshots/whitequark/trailing_forward_arg.txt index 61f29acca5a1d3..f250529610a3bf 100644 --- a/test/yarp/snapshots/whitequark/trailing_forward_arg.txt +++ b/test/yarp/snapshots/whitequark/trailing_forward_arg.txt @@ -2,6 +2,7 @@ ProgramNode(0...40)( [], StatementsNode(0...40)( [DefNode(0...40)( + :foo, (4...7), nil, ParametersNode(8...17)( diff --git a/test/yarp/snapshots/whitequark/var_op_asgn.txt b/test/yarp/snapshots/whitequark/var_op_asgn.txt index 0927e8b8f3aebc..48abb4ebf67ba5 100644 --- a/test/yarp/snapshots/whitequark/var_op_asgn.txt +++ b/test/yarp/snapshots/whitequark/var_op_asgn.txt @@ -24,6 +24,7 @@ ProgramNode(0...53)( 0 ), DefNode(30...53)( + :a, (34...35), nil, nil, diff --git a/yarp/config.yml b/yarp/config.yml index f62b591d4fb4c4..2808a0310d58ad 100644 --- a/yarp/config.yml +++ b/yarp/config.yml @@ -1039,6 +1039,8 @@ nodes: ^^^^^^^ - name: DefNode fields: + - name: name + type: constant - name: name_loc type: location - name: receiver diff --git a/yarp/yarp.c b/yarp/yarp.c index c7c43e14bb939c..6f232712cd757c 100644 --- a/yarp/yarp.c +++ b/yarp/yarp.c @@ -2028,6 +2028,7 @@ yp_def_node_create( .type = YP_DEF_NODE, .location = { .start = def_keyword->start, .end = end }, }, + .name = yp_parser_constant_id_token(parser, name), .name_loc = YP_LOCATION_TOKEN_VALUE(name), .receiver = receiver, .parameters = parameters, From 0c8928721e19dda1ce7b1a8797b18d199207708c Mon Sep 17 00:00:00 2001 From: Kevin Newton Date: Thu, 7 Sep 2023 09:10:50 -0400 Subject: [PATCH 15/46] [YARP] Use the correct field for the name on classes and modules --- yarp/yarp_compiler.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/yarp/yarp_compiler.c b/yarp/yarp_compiler.c index 10ef6a1e8c4d9f..8b9190cad83ada 100644 --- a/yarp/yarp_compiler.c +++ b/yarp/yarp_compiler.c @@ -597,7 +597,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, yp_scope_node_t scope_node; yp_scope_node_init((yp_node_t *)class_node, &scope_node); - ID class_id = yp_constant_id_lookup(compile_context, class_node->name_constant); + ID class_id = yp_constant_id_lookup(compile_context, class_node->name); VALUE class_name = rb_str_freeze(rb_sprintf("", rb_id2str(class_id))); @@ -1463,7 +1463,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, yp_scope_node_t scope_node; yp_scope_node_init((yp_node_t *)module_node, &scope_node); - ID module_id = yp_constant_id_lookup(compile_context, module_node->name_constant); + ID module_id = yp_constant_id_lookup(compile_context, module_node->name); VALUE module_name = rb_str_freeze(rb_sprintf("", rb_id2str(module_id))); const rb_iseq_t *module_iseq = NEW_CHILD_ISEQ(&scope_node, module_name, ISEQ_TYPE_CLASS, lineno); From 0adca625ee34ced92da68ba144de32f44e7300cd Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Thu, 7 Sep 2023 06:54:05 -0700 Subject: [PATCH 16/46] Remove function call for String#bytesize (#8389) * Remove function call for String#bytesize String size is stored in a consistent location, so we can eliminate the function call. * Update yjit/src/codegen.rs Co-authored-by: Takashi Kokubun --------- Co-authored-by: Maxime Chevalier-Boisvert Co-authored-by: Takashi Kokubun --- yjit/src/codegen.rs | 15 +++++++++++++-- yjit/src/cruby.rs | 1 - 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs index 92dd239c8b9f66..a99594c3abd8d3 100644 --- a/yjit/src/codegen.rs +++ b/yjit/src/codegen.rs @@ -4697,10 +4697,21 @@ fn jit_rb_str_bytesize( asm.comment("String#bytesize"); let recv = asm.stack_pop(1); - let ret_opnd = asm.ccall(rb_str_bytesize as *const u8, vec![recv]); + + asm.comment("get string length"); + let str_len_opnd = Opnd::mem( + std::os::raw::c_long::BITS as u8, + asm.load(recv), + RUBY_OFFSET_RSTRING_LEN as i32, + ); + + let len = asm.load(str_len_opnd); + let shifted_val = asm.lshift(len, Opnd::UImm(1)); + let out_val = asm.or(shifted_val, Opnd::UImm(RUBY_FIXNUM_FLAG as u64)); let out_opnd = asm.stack_push(Type::Fixnum); - asm.mov(out_opnd, ret_opnd); + + asm.mov(out_opnd, out_val); true } diff --git a/yjit/src/cruby.rs b/yjit/src/cruby.rs index a8234e744aeae8..274331755f2579 100644 --- a/yjit/src/cruby.rs +++ b/yjit/src/cruby.rs @@ -135,7 +135,6 @@ extern "C" { ic: ICVARC, ) -> VALUE; pub fn rb_vm_ic_hit_p(ic: IC, reg_ep: *const VALUE) -> bool; - pub fn rb_str_bytesize(str: VALUE) -> VALUE; } // Renames From 194584f20277a63164789aa83ae3841ef6e6eb8c Mon Sep 17 00:00:00 2001 From: Kevin Newton Date: Wed, 6 Sep 2023 12:43:36 -0400 Subject: [PATCH 17/46] [ruby/yarp] Introduce owned constants Before this commit, constants in the constant pool were assumed to be slices of the source string. This works in _almost_ all cases. There are times, however, when a string needs to be synthesized. This can occur when passing in locals that need to be scoped through eval, or when generating method names like `foo=`. After this commit, there is a single bit `owned` boolean on constants in the pool that indicates whether or not it is a slice of the source string. If it is not, it is assumed to be allocated memory that should be freed by the constant pool when the constant pool is freed. When serializing, the most significant bit in the location of the contents of the constant indicates whether or not it is owned. When it is, instead of 4 bytes for the source offset and 4 bytes for the length it is instead 4 bytes for the buffer offset and 4 bytes the length. The contents of the owned constants are embedded into the buffer after the constant pool itself. https://github.com/ruby/yarp/commit/461c047365 --- test/yarp/parse_serialize_test.rb | 10 +++++ yarp/templates/ext/yarp/api_node.c.erb | 11 ++++++ yarp/templates/lib/yarp/serialize.rb.erb | 9 ++++- yarp/templates/src/serialize.c.erb | 27 +++++++++++-- yarp/util/yp_constant_pool.c | 49 ++++++++++++++++++++---- yarp/util/yp_constant_pool.h | 15 ++++++-- yarp/yarp.c | 47 +++++++++++++++++++---- 7 files changed, 142 insertions(+), 26 deletions(-) diff --git a/test/yarp/parse_serialize_test.rb b/test/yarp/parse_serialize_test.rb index 82a1c29d48a10f..d3474f7104d95f 100644 --- a/test/yarp/parse_serialize_test.rb +++ b/test/yarp/parse_serialize_test.rb @@ -14,6 +14,16 @@ def test_parse_serialize assert_equal __FILE__, find_file_node(result)&.filepath, "Expected the filepath to be set correctly" end + def test_parse_serialize_with_locals + filepath = __FILE__ + metadata = [filepath.bytesize, filepath.b, 1, 1, 1, "foo".b].pack("LA*LLLA*") + + dumped = Debug.parse_serialize_file_metadata(filepath, metadata) + result = YARP.load(File.read(__FILE__), dumped) + + assert_kind_of ParseResult, result, "Expected the return value to be a ParseResult" + end + private def find_file_node(result) diff --git a/yarp/templates/ext/yarp/api_node.c.erb b/yarp/templates/ext/yarp/api_node.c.erb index 0d075112c8f96f..a9f5115d7f1f45 100644 --- a/yarp/templates/ext/yarp/api_node.c.erb +++ b/yarp/templates/ext/yarp/api_node.c.erb @@ -144,30 +144,41 @@ yp_ast_new(yp_parser_t *parser, yp_node_t *node, rb_encoding *encoding) { // <%= field.name %> <%- case field -%> <%- when YARP::NodeField, YARP::OptionalNodeField -%> +#line <%= __LINE__ + 1 %> "<%= File.basename(__FILE__) %>" argv[<%= index %>] = rb_ary_pop(value_stack); <%- when YARP::NodeListField -%> +#line <%= __LINE__ + 1 %> "<%= File.basename(__FILE__) %>" argv[<%= index %>] = rb_ary_new_capa(cast-><%= field.name %>.size); for (size_t index = 0; index < cast-><%= field.name %>.size; index++) { rb_ary_push(argv[<%= index %>], rb_ary_pop(value_stack)); } <%- when YARP::StringField -%> +#line <%= __LINE__ + 1 %> "<%= File.basename(__FILE__) %>" argv[<%= index %>] = yp_string_new(&cast-><%= field.name %>, encoding); <%- when YARP::ConstantField -%> +#line <%= __LINE__ + 1 %> "<%= File.basename(__FILE__) %>" + assert(cast-><%= field.name %> != 0); argv[<%= index %>] = rb_id2sym(constants[cast-><%= field.name %> - 1]); <%- when YARP::OptionalConstantField -%> argv[<%= index %>] = cast-><%= field.name %> == 0 ? Qnil : rb_id2sym(constants[cast-><%= field.name %> - 1]); <%- when YARP::ConstantListField -%> +#line <%= __LINE__ + 1 %> "<%= File.basename(__FILE__) %>" argv[<%= index %>] = rb_ary_new_capa(cast-><%= field.name %>.size); for (size_t index = 0; index < cast-><%= field.name %>.size; index++) { + assert(cast-><%= field.name %>.ids[index] != 0); rb_ary_push(argv[<%= index %>], rb_id2sym(constants[cast-><%= field.name %>.ids[index] - 1])); } <%- when YARP::LocationField -%> +#line <%= __LINE__ + 1 %> "<%= File.basename(__FILE__) %>" argv[<%= index %>] = yp_location_new(parser, cast-><%= field.name %>.start, cast-><%= field.name %>.end, source); <%- when YARP::OptionalLocationField -%> +#line <%= __LINE__ + 1 %> "<%= File.basename(__FILE__) %>" argv[<%= index %>] = cast-><%= field.name %>.start == NULL ? Qnil : yp_location_new(parser, cast-><%= field.name %>.start, cast-><%= field.name %>.end, source); <%- when YARP::UInt32Field -%> +#line <%= __LINE__ + 1 %> "<%= File.basename(__FILE__) %>" argv[<%= index %>] = ULONG2NUM(cast-><%= field.name %>); <%- when YARP::FlagsField -%> +#line <%= __LINE__ + 1 %> "<%= File.basename(__FILE__) %>" argv[<%= index %>] = ULONG2NUM(node->flags >> <%= YARP::COMMON_FLAGS %>); <%- else -%> <%- raise -%> diff --git a/yarp/templates/lib/yarp/serialize.rb.erb b/yarp/templates/lib/yarp/serialize.rb.erb index c8d7f422cdb5ba..3f5329e3a9cdc5 100644 --- a/yarp/templates/lib/yarp/serialize.rb.erb +++ b/yarp/templates/lib/yarp/serialize.rb.erb @@ -163,11 +163,16 @@ module YARP unless constant offset = constant_pool_offset + index * 8 - start = serialized.unpack1("L", offset: offset) length = serialized.unpack1("L", offset: offset + 4) - constant = input.byteslice(start, length).to_sym + constant = + if start.nobits?(1 << 31) + input.byteslice(start, length).to_sym + else + serialized.byteslice(start & ((1 << 31) - 1), length).to_sym + end + constant_pool[index] = constant end diff --git a/yarp/templates/src/serialize.c.erb b/yarp/templates/src/serialize.c.erb index 8e0b0905dcc5d1..b60bce21138acc 100644 --- a/yarp/templates/src/serialize.c.erb +++ b/yarp/templates/src/serialize.c.erb @@ -206,12 +206,31 @@ yp_serialize_content(yp_parser_t *parser, yp_node_t *node, yp_buffer_t *buffer) // If we find a constant at this index, serialize it at the correct // index in the buffer. if (constant->id != 0) { - size_t buffer_offset = offset + ((constant->id - 1) * 8); + size_t buffer_offset = offset + ((((size_t) constant->id) - 1) * 8); + + if (constant->owned) { + // Since this is an owned constant, we are going to write its + // contents into the buffer after the constant pool. So + // effectively in place of the source offset, we have a buffer + // offset. We will add a leading 1 to indicate that this is a + // buffer offset. + uint32_t content_offset = yp_sizet_to_u32(buffer->length); + uint32_t owned_mask = (uint32_t) (1 << 31); + + assert(content_offset < owned_mask); + content_offset |= owned_mask; + + memcpy(buffer->value + buffer_offset, &content_offset, 4); + yp_buffer_append_bytes(buffer, constant->start, constant->length); + } else { + // Since this is a shared constant, we are going to write its + // source offset directly into the buffer. + uint32_t source_offset = yp_ptrdifft_to_u32(constant->start - parser->start); + memcpy(buffer->value + buffer_offset, &source_offset, 4); + } - uint32_t source_offset = yp_ptrdifft_to_u32(constant->start - parser->start); + // Now we can write the length of the constant into the buffer. uint32_t constant_length = yp_sizet_to_u32(constant->length); - - memcpy(buffer->value + buffer_offset, &source_offset, 4); memcpy(buffer->value + buffer_offset + 4, &constant_length, 4); } } diff --git a/yarp/util/yp_constant_pool.c b/yarp/util/yp_constant_pool.c index 3ad241a9d1bb54..8be96138a1325e 100644 --- a/yarp/util/yp_constant_pool.c +++ b/yarp/util/yp_constant_pool.c @@ -106,12 +106,11 @@ yp_constant_pool_init(yp_constant_pool_t *pool, size_t capacity) { return true; } -// Insert a constant into a constant pool. Returns the id of the constant, or 0 -// if any potential calls to resize fail. -yp_constant_id_t +// Insert a constant into a constant pool and return its index in the pool. +static size_t yp_constant_pool_insert(yp_constant_pool_t *pool, const uint8_t *start, size_t length) { if (pool->size >= (pool->capacity / 4 * 3)) { - if (!yp_constant_pool_resize(pool)) return 0; + if (!yp_constant_pool_resize(pool)) return pool->capacity; } size_t hash = yp_constant_pool_hash(start, length); @@ -123,25 +122,59 @@ yp_constant_pool_insert(yp_constant_pool_t *pool, const uint8_t *start, size_t l // same as the content we are trying to insert. If it is, then we can // return the id of the existing constant. if ((constant->length == length) && memcmp(constant->start, start, length) == 0) { - return pool->constants[index].id; + return index; } index = (index + 1) % pool->capacity; } - yp_constant_id_t id = (yp_constant_id_t)++pool->size; + pool->size++; + assert(pool->size < ((size_t) (1 << 31))); + pool->constants[index] = (yp_constant_t) { - .id = id, + .id = (unsigned int) (pool->size & 0x7FFFFFFF), .start = start, .length = length, .hash = hash }; - return id; + return index; +} + +// Insert a constant into a constant pool. Returns the id of the constant, or 0 +// if any potential calls to resize fail. +yp_constant_id_t +yp_constant_pool_insert_shared(yp_constant_pool_t *pool, const uint8_t *start, size_t length) { + size_t index = yp_constant_pool_insert(pool, start, length); + return index == pool->capacity ? 0 : ((yp_constant_id_t) pool->constants[index].id); +} + +// Insert a constant into a constant pool from memory that is now owned by the +// constant pool. Returns the id of the constant, or 0 if any potential calls to +// resize fail. +yp_constant_id_t +yp_constant_pool_insert_owned(yp_constant_pool_t *pool, const uint8_t *start, size_t length) { + size_t index = yp_constant_pool_insert(pool, start, length); + if (index == pool->capacity) return 0; + + yp_constant_t *constant = &pool->constants[index]; + constant->owned = true; + return ((yp_constant_id_t) constant->id); } // Free the memory associated with a constant pool. void yp_constant_pool_free(yp_constant_pool_t *pool) { + // For each constant in the current constant pool, free the contents if the + // contents are owned. + for (uint32_t index = 0; index < pool->capacity; index++) { + yp_constant_t *constant = &pool->constants[index]; + + // If an id is set on this constant, then we know we have content here. + if (constant->id != 0 && constant->owned) { + free((void *) constant->start); + } + } + free(pool->constants); } diff --git a/yarp/util/yp_constant_pool.h b/yarp/util/yp_constant_pool.h index 1ac23cf88bbf28..ecd3ff619e3033 100644 --- a/yarp/util/yp_constant_pool.h +++ b/yarp/util/yp_constant_pool.h @@ -8,6 +8,7 @@ #include "yarp/defines.h" +#include #include #include #include @@ -39,7 +40,8 @@ size_t yp_constant_id_list_memsize(yp_constant_id_list_t *list); void yp_constant_id_list_free(yp_constant_id_list_t *list); typedef struct { - yp_constant_id_t id; + unsigned int id: 31; + bool owned: 1; const uint8_t *start; size_t length; size_t hash; @@ -57,9 +59,14 @@ typedef struct { // Initialize a new constant pool with a given capacity. bool yp_constant_pool_init(yp_constant_pool_t *pool, size_t capacity); -// Insert a constant into a constant pool. Returns the id of the constant, or 0 -// if any potential calls to resize fail. -yp_constant_id_t yp_constant_pool_insert(yp_constant_pool_t *pool, const uint8_t *start, size_t length); +// Insert a constant into a constant pool that is a slice of a source string. +// Returns the id of the constant, or 0 if any potential calls to resize fail. +yp_constant_id_t yp_constant_pool_insert_shared(yp_constant_pool_t *pool, const uint8_t *start, size_t length); + +// Insert a constant into a constant pool from memory that is now owned by the +// constant pool. Returns the id of the constant, or 0 if any potential calls to +// resize fail. +yp_constant_id_t yp_constant_pool_insert_owned(yp_constant_pool_t *pool, const uint8_t *start, size_t length); // Free the memory associated with a constant pool. void yp_constant_pool_free(yp_constant_pool_t *pool); diff --git a/yarp/yarp.c b/yarp/yarp.c index 6f232712cd757c..22928071258bd2 100644 --- a/yarp/yarp.c +++ b/yarp/yarp.c @@ -428,7 +428,13 @@ debug_lex_state_set(yp_parser_t *parser, yp_lex_state_t state, char const * call // Retrieve the constant pool id for the given location. static inline yp_constant_id_t yp_parser_constant_id_location(yp_parser_t *parser, const uint8_t *start, const uint8_t *end) { - return yp_constant_pool_insert(&parser->constant_pool, start, (size_t) (end - start)); + return yp_constant_pool_insert_shared(&parser->constant_pool, start, (size_t) (end - start)); +} + +// Retrieve the constant pool id for the given string. +static inline yp_constant_id_t +yp_parser_constant_id_owned(yp_parser_t *parser, const uint8_t *start, size_t length) { + return yp_constant_pool_insert_owned(&parser->constant_pool, start, length); } // Retrieve the constant pool id for the given token. @@ -4610,15 +4616,19 @@ yp_parser_local_depth(yp_parser_t *parser, yp_token_t *token) { return -1; } -// Add a local variable from a location to the current scope. -static yp_constant_id_t -yp_parser_local_add_location(yp_parser_t *parser, const uint8_t *start, const uint8_t *end) { - yp_constant_id_t constant_id = yp_parser_constant_id_location(parser, start, end); - +// Add a constant id to the local table of the current scope. +static inline void +yp_parser_local_add(yp_parser_t *parser, yp_constant_id_t constant_id) { if (!yp_constant_id_list_includes(&parser->current_scope->locals, constant_id)) { yp_constant_id_list_append(&parser->current_scope->locals, constant_id); } +} +// Add a local variable from a location to the current scope. +static yp_constant_id_t +yp_parser_local_add_location(yp_parser_t *parser, const uint8_t *start, const uint8_t *end) { + yp_constant_id_t constant_id = yp_parser_constant_id_location(parser, start, end); + if (constant_id != 0) yp_parser_local_add(parser, constant_id); return constant_id; } @@ -4628,6 +4638,13 @@ yp_parser_local_add_token(yp_parser_t *parser, yp_token_t *token) { yp_parser_local_add_location(parser, token->start, token->end); } +// Add a local variable from an owned string to the current scope. +static inline void +yp_parser_local_add_owned(yp_parser_t *parser, const uint8_t *start, size_t length) { + yp_constant_id_t constant_id = yp_parser_constant_id_owned(parser, start, length); + if (constant_id != 0) yp_parser_local_add(parser, constant_id); +} + // Add a parameter name to the current scope and check whether the name of the // parameter is unique or not. static void @@ -4644,7 +4661,9 @@ yp_parser_parameter_name_check(yp_parser_t *parser, yp_token_t *name) { } } -// Pop the current scope off the scope stack. +// Pop the current scope off the scope stack. Note that we specifically do not +// free the associated constant list because we assume that we have already +// transferred ownership of the list to the AST somewhere. static void yp_parser_scope_pop(yp_parser_t *parser) { yp_scope_t *scope = parser->current_scope; @@ -13757,7 +13776,10 @@ yp_parser_metadata(yp_parser_t *parser, const char *metadata) { uint32_t local_size = yp_metadata_read_u32(metadata); metadata += 4; - yp_parser_local_add_location(parser, (const uint8_t *) metadata, (const uint8_t *) (metadata + local_size)); + uint8_t *constant = malloc(local_size); + memcpy(constant, metadata, local_size); + + yp_parser_local_add_owned(parser, constant, (size_t) local_size); metadata += local_size; } } @@ -13896,6 +13918,15 @@ yp_parser_free(yp_parser_t *parser) { yp_constant_pool_free(&parser->constant_pool); yp_newline_list_free(&parser->newline_list); + while (parser->current_scope != NULL) { + // Normally, popping the scope doesn't free the locals since it is + // assumed that ownership has transferred to the AST. However if we have + // scopes while we're freeing the parser, it's likely they came from + // eval scopes and we need to free them explicitly here. + yp_constant_id_list_free(&parser->current_scope->locals); + yp_parser_scope_pop(parser); + } + while (parser->lex_modes.index >= YP_LEX_STACK_SIZE) { lex_mode_pop(parser); } From 44b52c54164116b38462085916bffcda00a41a2a Mon Sep 17 00:00:00 2001 From: Nathan Froyd Date: Thu, 7 Sep 2023 08:44:18 -0400 Subject: [PATCH 18/46] [ruby/yarp] use `YP_LOCATION_*_VALUE` macros more consistently https://github.com/ruby/yarp/commit/bcad93e2fc --- yarp/yarp.c | 102 +++++++++++++++++++++++----------------------------- 1 file changed, 44 insertions(+), 58 deletions(-) diff --git a/yarp/yarp.c b/yarp/yarp.c index 22928071258bd2..0ca5253a05551c 100644 --- a/yarp/yarp.c +++ b/yarp/yarp.c @@ -817,10 +817,7 @@ yp_array_node_create(yp_parser_t *parser, const yp_token_t *opening) { *node = (yp_array_node_t) { { .type = YP_ARRAY_NODE, - .location = { - .start = opening->start, - .end = opening->end - }, + .location = YP_LOCATION_TOKEN_VALUE(opening) }, .opening_loc = YP_OPTIONAL_LOCATION_TOKEN_VALUE(opening), .closing_loc = YP_OPTIONAL_LOCATION_TOKEN_VALUE(opening), @@ -1188,7 +1185,7 @@ yp_block_parameters_node_create(yp_parser_t *parser, yp_parameters_node_t *param }, .parameters = parameters, .opening_loc = YP_OPTIONAL_LOCATION_TOKEN_VALUE(opening), - .closing_loc = { .start = NULL, .end = NULL }, + .closing_loc = YP_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE, .locals = YP_EMPTY_NODE_LIST }; @@ -1449,9 +1446,7 @@ static yp_call_node_t * yp_call_node_variable_call_create(yp_parser_t *parser, yp_token_t *message) { yp_call_node_t *node = yp_call_node_create(parser); - node->base.location.start = message->start; - node->base.location.end = message->end; - + node->base.location = YP_LOCATION_TOKEN_VALUE(message); node->message_loc = YP_OPTIONAL_LOCATION_TOKEN_VALUE(message); yp_string_shared_init(&node->name, message->start, message->end); @@ -2538,10 +2533,7 @@ yp_hash_node_create(yp_parser_t *parser, const yp_token_t *opening) { *node = (yp_hash_node_t) { { .type = YP_HASH_NODE, - .location = { - .start = opening->start, - .end = opening->end - }, + .location = YP_LOCATION_TOKEN_VALUE(opening) }, .opening_loc = YP_LOCATION_TOKEN_VALUE(opening), .closing_loc = YP_LOCATION_NULL_VALUE(parser), @@ -3040,10 +3032,7 @@ yp_keyword_hash_node_create(yp_parser_t *parser) { *node = (yp_keyword_hash_node_t) { .base = { .type = YP_KEYWORD_HASH_NODE, - .location = { - .start = NULL, - .end = NULL - }, + .location = YP_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE }, .elements = YP_EMPTY_NODE_LIST }; @@ -3495,7 +3484,7 @@ yp_parameters_node_create(yp_parser_t *parser) { *node = (yp_parameters_node_t) { { .type = YP_PARAMETERS_NODE, - .location = { .start = parser->current.start, .end = parser->current.start }, + .location = YP_LOCATION_TOKEN_VALUE(&parser->current) }, .rest = NULL, .keyword_rest = NULL, @@ -3778,7 +3767,7 @@ yp_required_destructured_parameter_node_create(yp_parser_t *parser, const yp_tok .location = YP_LOCATION_TOKEN_VALUE(opening) }, .opening_loc = YP_LOCATION_TOKEN_VALUE(opening), - .closing_loc = { .start = NULL, .end = NULL }, + .closing_loc = YP_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE, .parameters = YP_EMPTY_NODE_LIST }; @@ -3843,10 +3832,7 @@ yp_rescue_node_create(yp_parser_t *parser, const yp_token_t *keyword) { *node = (yp_rescue_node_t) { { .type = YP_RESCUE_NODE, - .location = { - .start = keyword->start, - .end = keyword->end - } + .location = YP_LOCATION_TOKEN_VALUE(keyword) }, .keyword_loc = YP_LOCATION_TOKEN_VALUE(keyword), .operator_loc = YP_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE, @@ -4574,10 +4560,6 @@ yp_yield_node_create(yp_parser_t *parser, const yp_token_t *keyword, const yp_lo #undef YP_EMPTY_STRING -#undef YP_LOCATION_NULL_VALUE -#undef YP_LOCATION_TOKEN_VALUE -#undef YP_LOCATION_NODE_VALUE -#undef YP_LOCATION_NODE_BASE_VALUE #undef YP_TOKEN_NOT_PROVIDED_VALUE #undef YP_ALLOC_NODE @@ -8103,7 +8085,7 @@ parse_target(yp_parser_t *parser, yp_node_t *target) { } yp_token_t operator = not_provided(parser); - yp_location_t location = { .start = NULL, .end = NULL }; + yp_location_t location = YP_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE; yp_multi_write_node_t *multi_write = yp_multi_write_node_create(parser, &operator, NULL, &location, &location); yp_multi_write_node_targets_append(multi_write, (yp_node_t *) splat); @@ -8249,7 +8231,7 @@ parse_write(yp_parser_t *parser, yp_node_t *target, yp_token_t *operator, yp_nod splat->expression = parse_write(parser, splat->expression, operator, value); } - yp_location_t location = { .start = NULL, .end = NULL }; + yp_location_t location = YP_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE; yp_multi_write_node_t *multi_write = yp_multi_write_node_create(parser, operator, value, &location, &location); yp_multi_write_node_targets_append(multi_write, (yp_node_t *) splat); @@ -8384,7 +8366,7 @@ parse_targets(yp_parser_t *parser, yp_node_t *first_target, yp_binding_power_t b } } - yp_location_t lparen_loc = { .start = NULL, .end = NULL }; + yp_location_t lparen_loc = YP_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE; yp_multi_write_node_t *result = yp_multi_write_node_create(parser, &operator, NULL, &lparen_loc, &lparen_loc); if (first_target != NULL) { @@ -8432,8 +8414,8 @@ parse_targets(yp_parser_t *parser, yp_node_t *first_target, yp_binding_power_t b result = (yp_multi_write_node_t *) child_target; result->base.location.start = lparen.start; result->base.location.end = rparen.end; - result->lparen_loc = (yp_location_t) { .start = lparen.start, .end = lparen.end }; - result->rparen_loc = (yp_location_t) { .start = rparen.start, .end = rparen.end }; + result->lparen_loc = YP_LOCATION_TOKEN_VALUE(&lparen); + result->rparen_loc = YP_LOCATION_TOKEN_VALUE(&rparen); } else { yp_multi_write_node_t *target; @@ -8441,8 +8423,8 @@ parse_targets(yp_parser_t *parser, yp_node_t *first_target, yp_binding_power_t b target = (yp_multi_write_node_t *) child_target; target->base.location.start = lparen.start; target->base.location.end = rparen.end; - target->lparen_loc = (yp_location_t) { .start = lparen.start, .end = lparen.end }; - target->rparen_loc = (yp_location_t) { .start = rparen.start, .end = rparen.end }; + target->lparen_loc = YP_LOCATION_TOKEN_VALUE(&lparen); + target->rparen_loc = YP_LOCATION_TOKEN_VALUE(&rparen); } else { yp_token_t operator = not_provided(parser); @@ -8450,8 +8432,8 @@ parse_targets(yp_parser_t *parser, yp_node_t *first_target, yp_binding_power_t b parser, &operator, NULL, - &(yp_location_t) { .start = lparen.start, .end = lparen.end }, - &(yp_location_t) { .start = rparen.start, .end = rparen.end } + &YP_LOCATION_TOKEN_VALUE(&lparen), + &YP_LOCATION_TOKEN_VALUE(&rparen) ); yp_multi_write_node_targets_append(target, child_target); @@ -9473,10 +9455,10 @@ parse_arguments_list(yp_parser_t *parser, yp_arguments_t *arguments, bool accept if (accept(parser, YP_TOKEN_PARENTHESIS_LEFT)) { found |= true; - arguments->opening_loc = ((yp_location_t) { .start = parser->previous.start, .end = parser->previous.end }); + arguments->opening_loc = YP_LOCATION_TOKEN_VALUE(&parser->previous); if (accept(parser, YP_TOKEN_PARENTHESIS_RIGHT)) { - arguments->closing_loc = ((yp_location_t) { .start = parser->previous.start, .end = parser->previous.end }); + arguments->closing_loc = YP_LOCATION_TOKEN_VALUE(&parser->previous); } else { arguments->arguments = yp_arguments_node_create(parser); @@ -9485,7 +9467,7 @@ parse_arguments_list(yp_parser_t *parser, yp_arguments_t *arguments, bool accept expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, "Expected a ')' to close the argument list."); yp_accepts_block_stack_pop(parser); - arguments->closing_loc = ((yp_location_t) { .start = parser->previous.start, .end = parser->previous.end }); + arguments->closing_loc = YP_LOCATION_TOKEN_VALUE(&parser->previous); } } else if ((token_begins_expression_p(parser->current.type) || match_any_type_p(parser, 3, YP_TOKEN_USTAR, YP_TOKEN_USTAR_STAR, YP_TOKEN_UAMPERSAND)) && !match_type_p(parser, YP_TOKEN_BRACE_LEFT)) { found |= true; @@ -10263,8 +10245,8 @@ parse_pattern_constant_path(yp_parser_t *parser, yp_node_t *node) { pattern_node->base.location.end = closing.end; pattern_node->constant = node; - pattern_node->opening_loc = (yp_location_t) { .start = opening.start, .end = opening.end }; - pattern_node->closing_loc = (yp_location_t) { .start = closing.start, .end = closing.end }; + pattern_node->opening_loc = YP_LOCATION_TOKEN_VALUE(&opening); + pattern_node->closing_loc = YP_LOCATION_TOKEN_VALUE(&closing); return (yp_node_t *) pattern_node; } @@ -10279,8 +10261,8 @@ parse_pattern_constant_path(yp_parser_t *parser, yp_node_t *node) { pattern_node->base.location.end = closing.end; pattern_node->constant = node; - pattern_node->opening_loc = (yp_location_t) { .start = opening.start, .end = opening.end }; - pattern_node->closing_loc = (yp_location_t) { .start = closing.start, .end = closing.end }; + pattern_node->opening_loc = YP_LOCATION_TOKEN_VALUE(&opening); + pattern_node->closing_loc = YP_LOCATION_TOKEN_VALUE(&closing); return (yp_node_t *) pattern_node; } @@ -10295,8 +10277,8 @@ parse_pattern_constant_path(yp_parser_t *parser, yp_node_t *node) { pattern_node->base.location.end = closing.end; pattern_node->constant = node; - pattern_node->opening_loc = (yp_location_t) { .start = opening.start, .end = opening.end }; - pattern_node->closing_loc = (yp_location_t) { .start = closing.start, .end = closing.end }; + pattern_node->opening_loc = YP_LOCATION_TOKEN_VALUE(&opening); + pattern_node->closing_loc = YP_LOCATION_TOKEN_VALUE(&closing); return (yp_node_t *) pattern_node; } @@ -10452,8 +10434,8 @@ parse_pattern_primitive(yp_parser_t *parser, const char *message) { pattern_node->base.location.start = opening.start; pattern_node->base.location.end = closing.end; - pattern_node->opening_loc = (yp_location_t) { .start = opening.start, .end = opening.end }; - pattern_node->closing_loc = (yp_location_t) { .start = closing.start, .end = closing.end }; + pattern_node->opening_loc = YP_LOCATION_TOKEN_VALUE(&opening); + pattern_node->closing_loc = YP_LOCATION_TOKEN_VALUE(&closing); return (yp_node_t *) pattern_node; } @@ -10466,8 +10448,8 @@ parse_pattern_primitive(yp_parser_t *parser, const char *message) { pattern_node->base.location.start = opening.start; pattern_node->base.location.end = closing.end; - pattern_node->opening_loc = (yp_location_t) { .start = opening.start, .end = opening.end }; - pattern_node->closing_loc = (yp_location_t) { .start = closing.start, .end = closing.end }; + pattern_node->opening_loc = YP_LOCATION_TOKEN_VALUE(&opening); + pattern_node->closing_loc = YP_LOCATION_TOKEN_VALUE(&closing); return (yp_node_t *) pattern_node; } @@ -10529,8 +10511,8 @@ parse_pattern_primitive(yp_parser_t *parser, const char *message) { node->base.location.start = opening.start; node->base.location.end = closing.end; - node->opening_loc = (yp_location_t) { .start = opening.start, .end = opening.end }; - node->closing_loc = (yp_location_t) { .start = closing.start, .end = closing.end }; + node->opening_loc = YP_LOCATION_TOKEN_VALUE(&opening); + node->closing_loc = YP_LOCATION_TOKEN_VALUE(&closing); } parser->pattern_matching_newlines = previous_pattern_matching_newlines; @@ -10972,8 +10954,8 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { yp_multi_write_node_t *multi_statement = (yp_multi_write_node_t *) statement; if (multi_statement->value == NULL) { - yp_location_t lparen_loc = { .start = opening.start, .end = opening.end }; - yp_location_t rparen_loc = { .start = parser->previous.start, .end = parser->previous.end }; + yp_location_t lparen_loc = YP_LOCATION_TOKEN_VALUE(&opening); + yp_location_t rparen_loc = YP_LOCATION_TOKEN_VALUE(&parser->previous); yp_multi_write_node_t *multi_write; if (multi_statement->lparen_loc.start == NULL) { @@ -11953,7 +11935,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { &lparen, expression, &rparen, - &(yp_location_t) { .start = keyword.start, .end = keyword.end } + &YP_LOCATION_TOKEN_VALUE(&keyword) ); } case YP_TOKEN_KEYWORD_END_UPCASE: { @@ -12039,10 +12021,10 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { accept(parser, YP_TOKEN_NEWLINE); if (accept(parser, YP_TOKEN_PARENTHESIS_LEFT)) { - arguments.opening_loc = ((yp_location_t) { .start = parser->previous.start, .end = parser->previous.end }); + arguments.opening_loc = YP_LOCATION_TOKEN_VALUE(&parser->previous); if (accept(parser, YP_TOKEN_PARENTHESIS_RIGHT)) { - arguments.closing_loc = ((yp_location_t) { .start = parser->previous.start, .end = parser->previous.end }); + arguments.closing_loc = YP_LOCATION_TOKEN_VALUE(&parser->previous); } else { receiver = parse_expression(parser, YP_BINDING_POWER_COMPOSITION, "Expected expression after `not`."); yp_flip_flop(receiver); @@ -12050,7 +12032,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { if (!parser->recovering) { accept(parser, YP_TOKEN_NEWLINE); expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, "Expected ')' after 'not' expression."); - arguments.closing_loc = ((yp_location_t) { .start = parser->previous.start, .end = parser->previous.end }); + arguments.closing_loc = YP_LOCATION_TOKEN_VALUE(&parser->previous); } } } else { @@ -13589,7 +13571,7 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t parser_lex(parser); yp_arguments_t arguments = YP_EMPTY_ARGUMENTS; - arguments.opening_loc = ((yp_location_t) { .start = parser->previous.start, .end = parser->previous.end }); + arguments.opening_loc = YP_LOCATION_TOKEN_VALUE(&parser->previous); if (!accept(parser, YP_TOKEN_BRACKET_RIGHT)) { yp_accepts_block_stack_push(parser, true); @@ -13601,7 +13583,7 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t expect(parser, YP_TOKEN_BRACKET_RIGHT, "Expected ']' to close the bracket expression."); } - arguments.closing_loc = ((yp_location_t) { .start = parser->previous.start, .end = parser->previous.end }); + arguments.closing_loc = YP_LOCATION_TOKEN_VALUE(&parser->previous); // If we have a comma after the closing bracket then this is a multiple // assignment and we should parse the targets. @@ -13964,6 +13946,10 @@ yp_parse_serialize(const uint8_t *source, size_t size, yp_buffer_t *buffer, cons yp_parser_free(&parser); } +#undef YP_LOCATION_NULL_VALUE +#undef YP_LOCATION_TOKEN_VALUE +#undef YP_LOCATION_NODE_VALUE +#undef YP_LOCATION_NODE_BASE_VALUE #undef YP_CASE_KEYWORD #undef YP_CASE_OPERATOR #undef YP_CASE_WRITABLE From 630e49010cd91e97ce49d315b00d4ece193ebe82 Mon Sep 17 00:00:00 2001 From: Nathan Froyd Date: Thu, 7 Sep 2023 08:45:26 -0400 Subject: [PATCH 19/46] [ruby/yarp] remove now-redundant `YP_TOKEN_NOT_PROVIDED_VALUE` https://github.com/ruby/yarp/commit/8f9a3c2345 --- yarp/yarp.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/yarp/yarp.c b/yarp/yarp.c index 0ca5253a05551c..cb2bf18597ce67 100644 --- a/yarp/yarp.c +++ b/yarp/yarp.c @@ -516,7 +516,6 @@ not_provided(yp_parser_t *parser) { #define YP_LOCATION_NODE_BASE_VALUE(node) ((yp_location_t) { .start = (node)->base.location.start, .end = (node)->base.location.end }) #define YP_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE ((yp_location_t) { .start = NULL, .end = NULL }) #define YP_OPTIONAL_LOCATION_TOKEN_VALUE(token) ((token)->type == YP_TOKEN_NOT_PROVIDED ? YP_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE : YP_LOCATION_TOKEN_VALUE(token)) -#define YP_TOKEN_NOT_PROVIDED_VALUE(parser) ((yp_token_t) { .type = YP_TOKEN_NOT_PROVIDED, .start = (parser)->start, .end = (parser)->start }) // This is a special out parameter to the parse_arguments_list function that // includes opening and closing parentheses in addition to the arguments since @@ -4560,7 +4559,6 @@ yp_yield_node_create(yp_parser_t *parser, const yp_token_t *keyword, const yp_lo #undef YP_EMPTY_STRING -#undef YP_TOKEN_NOT_PROVIDED_VALUE #undef YP_ALLOC_NODE /******************************************************************************/ From 7adc38b8957d3d36c71450f44ee5adfd8b2bfff9 Mon Sep 17 00:00:00 2001 From: Jemma Issroff Date: Thu, 7 Sep 2023 10:59:51 -0400 Subject: [PATCH 20/46] [YARP] Miscellaneous small bug fixes (#8387) --- test/yarp/compiler_test.rb | 4 ++ yarp/yarp_compiler.c | 84 ++++++++++++++++++++++++++------------ 2 files changed, 63 insertions(+), 25 deletions(-) diff --git a/test/yarp/compiler_test.rb b/test/yarp/compiler_test.rb index d1cd7e33055476..4f81138037a675 100644 --- a/test/yarp/compiler_test.rb +++ b/test/yarp/compiler_test.rb @@ -2,6 +2,10 @@ module YARP class CompilerTest < Test::Unit::TestCase + def test_empty_program + assert_nil compile("") + end + ############################################################################ # Literals # ############################################################################ diff --git a/yarp/yarp_compiler.c b/yarp/yarp_compiler.c index 8b9190cad83ada..4be8f2fa2c73da 100644 --- a/yarp/yarp_compiler.c +++ b/yarp/yarp_compiler.c @@ -100,7 +100,8 @@ yp_static_literal_value(yp_node_t *node) return Qfalse; // TODO: Implement this method for the other literal nodes described above default: - rb_bug("This node type doesn't have a literal value"); + rb_raise(rb_eArgError, "Don't have a literal value for this type"); + return Qfalse; } } @@ -257,6 +258,9 @@ yp_compile_if(rb_iseq_t *iseq, const int line, yp_statements_node_t *node_body, ADD_LABEL(ret, end_label); } + if (popped) { + ADD_INSN(ret, &line_node, pop); + } return; } @@ -524,6 +528,9 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, if (begin_node->statements) { yp_compile_node(iseq, (yp_node_t *)begin_node->statements, ret, src, popped, compile_context); } + else { + ADD_INSN(ret, &dummy_line_node, putnil); + } return; } case YP_NODE_BREAK_NODE: { @@ -914,8 +921,16 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, case YP_NODE_EMBEDDED_STATEMENTS_NODE: { yp_embedded_statements_node_t *embedded_statements_node = (yp_embedded_statements_node_t *)node; - if (embedded_statements_node->statements) + if (embedded_statements_node->statements) { yp_compile_node(iseq, (yp_node_t *) (embedded_statements_node->statements), ret, src, popped, compile_context); + } + else { + ADD_INSN(ret, &dummy_line_node, putnil); + } + + if (popped) { + ADD_INSN(ret, &dummy_line_node, pop); + } // TODO: Concatenate the strings that exist here return; } @@ -1256,27 +1271,33 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, } case YP_NODE_INTERPOLATED_STRING_NODE: { yp_interpolated_string_node_t *interp_string_node= (yp_interpolated_string_node_t *) node; + size_t parts_size = interp_string_node->parts.size; + + if (parts_size > 0) { + for (size_t index = 0; index < parts_size; index++) { + yp_node_t *part = interp_string_node->parts.nodes[index]; + + switch (part->type) { + case YP_NODE_STRING_NODE: { + yp_string_node_t *string_node = (yp_string_node_t *) part; + ADD_INSN1(ret, &dummy_line_node, putobject,parse_string(&string_node->unescaped)); + break; + } + default: + yp_compile_node(iseq, part, ret, src, popped, compile_context); + ADD_INSN(ret, &dummy_line_node, dup); + ADD_INSN1(ret, &dummy_line_node, objtostring, new_callinfo(iseq, idTo_s, 0, VM_CALL_FCALL | VM_CALL_ARGS_SIMPLE , NULL, FALSE)); + ADD_INSN(ret, &dummy_line_node, anytostring); + break; + } + } - for (size_t index = 0; index < interp_string_node->parts.size; index++) { - yp_node_t *part = interp_string_node->parts.nodes[index]; - - switch (part->type) { - case YP_NODE_STRING_NODE: { - yp_string_node_t *string_node = (yp_string_node_t *) part; - ADD_INSN1(ret, &dummy_line_node, putobject,parse_string(&string_node->unescaped)); - break; - } - default: - yp_compile_node(iseq, part, ret, src, popped, compile_context); - ADD_INSN(ret, &dummy_line_node, dup); - ADD_INSN1(ret, &dummy_line_node, objtostring, new_callinfo(iseq, idTo_s, 0, VM_CALL_FCALL | VM_CALL_ARGS_SIMPLE , NULL, FALSE)); - ADD_INSN(ret, &dummy_line_node, anytostring); - break; + if (parts_size > 1) { + ADD_INSN1(ret, &dummy_line_node, concatstrings, INT2FIX((int)(interp_string_node->parts.size))); } } - - if (interp_string_node->parts.size > 1) { - ADD_INSN1(ret, &dummy_line_node, concatstrings, INT2FIX((int)(interp_string_node->parts.size))); + else { + ADD_INSN(ret, &dummy_line_node, putnil); } return; } @@ -1570,6 +1591,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, yp_scope_node_init((yp_node_t *)node, &scope_node); if (program_node->statements->body.size == 0) { ADD_INSN(ret, &dummy_line_node, putnil); + ADD_INSN(ret, &dummy_line_node, leave); } else { yp_scope_node_t *res_node = &scope_node; yp_compile_node(iseq, (yp_node_t *) res_node, ret, src, popped, compile_context); @@ -1723,6 +1745,9 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, if (scope_node->body) { yp_compile_node(iseq, (yp_node_t *)(scope_node->body), ret, src, popped, &scope_compile_context); } + else { + ADD_INSN(ret, &dummy_line_node, putnil); + } ADD_LABEL(ret, end); ADD_TRACE(ret, RUBY_EVENT_B_RETURN); @@ -1748,7 +1773,9 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, return; } case YP_NODE_SELF_NODE: - ADD_INSN(ret, &dummy_line_node, putself); + if (!popped) { + ADD_INSN(ret, &dummy_line_node, putself); + } return; case YP_NODE_SINGLETON_CLASS_NODE: { yp_singleton_class_node_t *singleton_class_node = (yp_singleton_class_node_t *)node; @@ -1824,7 +1851,12 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, for (size_t index = 0; index < node_list.size - 1; index++) { yp_compile_node(iseq, node_list.nodes[index], ret, src, true, compile_context); } - yp_compile_node(iseq, node_list.nodes[node_list.size - 1], ret, src, false, compile_context); + if (node_list.size > 0) { + yp_compile_node(iseq, node_list.nodes[node_list.size - 1], ret, src, popped, compile_context); + } + else { + ADD_INSN(ret, &dummy_line_node, putnil); + } return; } case YP_NODE_STRING_CONCAT_NODE: { @@ -1842,7 +1874,9 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, } case YP_NODE_SYMBOL_NODE: { yp_symbol_node_t *symbol_node = (yp_symbol_node_t *) node; - ADD_INSN1(ret, &dummy_line_node, putobject, ID2SYM(parse_string_symbol(&symbol_node->unescaped))); + if (!popped) { + ADD_INSN1(ret, &dummy_line_node, putobject, ID2SYM(parse_string_symbol(&symbol_node->unescaped))); + } return; } case YP_NODE_TRUE_NODE: @@ -1854,8 +1888,8 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, yp_undef_node_t *undef_node = (yp_undef_node_t *) node; for (size_t index = 0; index < undef_node->names.size; index++) { - ADD_INSN1(ret, &dummy_line_node, putspecialobject, VM_SPECIAL_OBJECT_VMCORE); - ADD_INSN1(ret, &dummy_line_node, putspecialobject, VM_SPECIAL_OBJECT_CBASE); + ADD_INSN1(ret, &dummy_line_node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE)); + ADD_INSN1(ret, &dummy_line_node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_CBASE)); yp_compile_node(iseq, undef_node->names.nodes[index], ret, src, popped, compile_context); From 2d37b44603f2031f0e95073ab77b418142c9eddd Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Wed, 6 Sep 2023 09:47:07 +0200 Subject: [PATCH 21/46] Document that thread event hooks are called without the GVL Except for the `RESUMED` event. --- include/ruby/thread.h | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/include/ruby/thread.h b/include/ruby/thread.h index 0b5b1ca0f3088a..3753a4c06abee2 100644 --- a/include/ruby/thread.h +++ b/include/ruby/thread.h @@ -190,11 +190,41 @@ void *rb_nogvl(void *(*func)(void *), void *data1, */ #define RUBY_CALL_WO_GVL_FLAG_SKIP_CHECK_INTS_ -#define RUBY_INTERNAL_THREAD_EVENT_STARTED 1 << 0 /** thread started */ +/** + * Triggered when a new thread is started. + * + * @note The callback will be called *without* the GVL held. + */ +#define RUBY_INTERNAL_THREAD_EVENT_STARTED 1 << 0 + +/** +* Triggered when a thread attempt to acquire the GVL. +* +* @note The callback will be called *without* the GVL held. +*/ #define RUBY_INTERNAL_THREAD_EVENT_READY 1 << 1 /** acquiring GVL */ + +/** + * Triggered when a thread successfuly acquired the GVL. + * + * @note The callback will be called *with* the GVL held. + */ #define RUBY_INTERNAL_THREAD_EVENT_RESUMED 1 << 2 /** acquired GVL */ + +/** + * Triggered when a thread released the GVL. + * + * @note The callback will be called *without* the GVL held. + */ #define RUBY_INTERNAL_THREAD_EVENT_SUSPENDED 1 << 3 /** released GVL */ + +/** + * Triggered when a thread exits. + * + * @note The callback will be called *without* the GVL held. + */ #define RUBY_INTERNAL_THREAD_EVENT_EXITED 1 << 4 /** thread terminated */ + #define RUBY_INTERNAL_THREAD_EVENT_MASK 0xff /** All Thread events */ typedef void rb_internal_thread_event_data_t; // for future extension. @@ -212,6 +242,8 @@ typedef struct rb_internal_thread_event_hook rb_internal_thread_event_hook_t; * @param[in] data Passed as-is to `func`. * @return An opaque pointer to the hook, to unregister it later. * @note This functionality is a noop on Windows. + * @note The callback will be called without the GVL held, except for the + RESUMED event. * @warning This function MUST not be called from a thread event callback. */ rb_internal_thread_event_hook_t *rb_internal_thread_add_event_hook( From 4efcaf956e27df365a1cf9e0cbb8d9a68eeb6995 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Sun, 3 Sep 2023 21:27:43 -0400 Subject: [PATCH 22/46] [ruby/yarp] Extract error messages into diagnostic.c and use canonical message IDs The parser now passes around `yp_diagnostic_id_t` for diagnostic messages instead of character strings, and we rely on the function `diagnostic_message()` to resolve that to a string. In addition, many messages were edited so that the parser expresses coordinate ideas in similar form [1] using consistent voice and typographic conventions. Closes https://github.com/ruby/yarp/pull/1379, and makes progress on #941. [1] Strunk & White rule 19 https://github.com/ruby/yarp/commit/0b6dd85bf1 --- test/yarp/errors_test.rb | 216 +++++++------- yarp/diagnostic.c | 256 ++++++++++++++++- yarp/diagnostic.h | 199 ++++++++++++- yarp/unescape.c | 40 +-- yarp/yarp.c | 608 ++++++++++++++++++++------------------- 5 files changed, 885 insertions(+), 434 deletions(-) diff --git a/test/yarp/errors_test.rb b/test/yarp/errors_test.rb index 608af07795f7cc..61955d612f6969 100644 --- a/test/yarp/errors_test.rb +++ b/test/yarp/errors_test.rb @@ -8,8 +8,8 @@ class ErrorsTest < TestCase def test_constant_path_with_invalid_token_after assert_error_messages "A::$b", [ - "Expected identifier or constant after '::'", - "Expected a newline or semicolon after statement." + "Expected a constant after the `::` operator", + "Expected a newline or semicolon after the statement" ] end @@ -26,7 +26,7 @@ def test_module_name_recoverable ) assert_errors expected, "module Parent module end", [ - ["Expected to find a module name after `module`.", 20..20] + ["Expected a constant name after `module`", 20..20] ] end @@ -42,7 +42,7 @@ def test_for_loops_index_missing ) assert_errors expected, "for in 1..10\ni\nend", [ - ["Expected index after for.", 0..0] + ["Expected an index after `for`", 0..0] ] end @@ -58,9 +58,9 @@ def test_for_loops_only_end ) assert_errors expected, "for end", [ - ["Expected index after for.", 0..0], - ["Expected keyword in.", 3..3], - ["Expected collection.", 3..3] + ["Expected an index after `for`", 0..0], + ["Expected an `in` after the index in a `for` statement", 3..3], + ["Expected a collection after the `in` in a `for` statement", 3..3] ] end @@ -73,7 +73,7 @@ def test_pre_execution_missing_brace ) assert_errors expected, "BEGIN 1 }", [ - ["Expected '{' after 'BEGIN'.", 5..5] + ["Expected a `{` after `BEGIN`", 5..5] ] end @@ -98,37 +98,37 @@ def test_pre_execution_context ) assert_errors expected, "BEGIN { 1 + }", [ - ["Expected a value after the operator.", 11..11] + ["Expected an expression after the operator", 11..11] ] end def test_unterminated_embdoc assert_errors expression("1"), "1\n=begin\n", [ - ["Unterminated embdoc", 2..9] + ["Could not find a terminator for the embedded document", 2..9] ] end def test_unterminated_i_list assert_errors expression("%i["), "%i[", [ - ["Expected a closing delimiter for a `%i` list.", 3..3] + ["Expected a closing delimiter for the `%i` list", 3..3] ] end def test_unterminated_w_list assert_errors expression("%w["), "%w[", [ - ["Expected a closing delimiter for a `%w` list.", 3..3] + ["Expected a closing delimiter for the `%w` list", 3..3] ] end def test_unterminated_W_list assert_errors expression("%W["), "%W[", [ - ["Expected a closing delimiter for a `%W` list.", 3..3] + ["Expected a closing delimiter for the `%W` list", 3..3] ] end def test_unterminated_regular_expression assert_errors expression("/hello"), "/hello", [ - ["Expected a closing delimiter for a regular expression.", 1..1] + ["Expected a closing delimiter for the regular expression", 1..1] ] end @@ -136,178 +136,178 @@ def test_unterminated_regular_expression_with_heredoc source = "<<-END + /b\nEND\n" assert_errors expression(source), source, [ - ["Expected a closing delimiter for a regular expression.", 10..10] + ["Expected a closing delimiter for the regular expression", 10..10] ] end def test_unterminated_xstring assert_errors expression("`hello"), "`hello", [ - ["Expected a closing delimiter for an xstring.", 1..1] + ["Expected a closing delimiter for the `%x` or backtick string", 1..1] ] end def test_unterminated_string assert_errors expression('"hello'), '"hello', [ - ["Expected a closing delimiter for an interpolated string.", 1..1] + ["Expected a closing delimiter for the interpolated string", 1..1] ] end def test_unterminated_s_symbol assert_errors expression("%s[abc"), "%s[abc", [ - ["Expected a closing delimiter for a dynamic symbol.", 3..3] + ["Expected a closing delimiter for the dynamic symbol", 3..3] ] end def test_unterminated_parenthesized_expression assert_errors expression('(1 + 2'), '(1 + 2', [ - ["Expected to be able to parse an expression.", 6..6], - ["Expected a closing parenthesis.", 6..6] + ["Cannot parse the expression", 6..6], + ["Expected a matching `)`", 6..6] ] end def test_unterminated_argument_expression assert_errors expression('a %'), 'a %', [ - ["Unexpected end of input", 2..3], - ["Expected a value after the operator.", 3..3], + ["Invalid `%` token", 2..3], + ["Expected an expression after the operator", 3..3], ] end def test_cr_without_lf_in_percent_expression assert_errors expression("%\r"), "%\r", [ - ["Invalid %% token", 0..2], + ["Invalid `%` token", 0..2], ] end def test_1_2_3 assert_errors expression("(1, 2, 3)"), "(1, 2, 3)", [ - ["Expected to be able to parse an expression.", 2..2], - ["Expected a closing parenthesis.", 2..2], - ["Expected a newline or semicolon after statement.", 2..2], - ["Expected to be able to parse an expression.", 2..2], - ["Expected a newline or semicolon after statement.", 5..5], - ["Expected to be able to parse an expression.", 5..5], - ["Expected a newline or semicolon after statement.", 8..8], - ["Expected to be able to parse an expression.", 8..8], + ["Cannot parse the expression", 2..2], + ["Expected a matching `)`", 2..2], + ["Expected a newline or semicolon after the statement", 2..2], + ["Cannot parse the expression", 2..2], + ["Expected a newline or semicolon after the statement", 5..5], + ["Cannot parse the expression", 5..5], + ["Expected a newline or semicolon after the statement", 8..8], + ["Cannot parse the expression", 8..8], ] end def test_return_1_2_3 assert_error_messages "return(1, 2, 3)", [ - "Expected to be able to parse an expression.", - "Expected a closing parenthesis.", - "Expected a newline or semicolon after statement.", - "Expected to be able to parse an expression." + "Cannot parse the expression", + "Expected a matching `)`", + "Expected a newline or semicolon after the statement", + "Cannot parse the expression", ] end def test_return_1 assert_errors expression("return 1,;"), "return 1,;", [ - ["Expected to be able to parse an argument.", 9..9] + ["Expected an argument", 9..9] ] end def test_next_1_2_3 assert_errors expression("next(1, 2, 3)"), "next(1, 2, 3)", [ - ["Expected to be able to parse an expression.", 6..6], - ["Expected a closing parenthesis.", 6..6], - ["Expected a newline or semicolon after statement.", 12..12], - ["Expected to be able to parse an expression.", 12..12] + ["Cannot parse the expression", 6..6], + ["Expected a matching `)`", 6..6], + ["Expected a newline or semicolon after the statement", 12..12], + ["Cannot parse the expression", 12..12], ] end def test_next_1 assert_errors expression("next 1,;"), "next 1,;", [ - ["Expected to be able to parse an argument.", 7..7] + ["Expected an argument", 7..7] ] end def test_break_1_2_3 assert_errors expression("break(1, 2, 3)"), "break(1, 2, 3)", [ - ["Expected to be able to parse an expression.", 7..7], - ["Expected a closing parenthesis.", 7..7], - ["Expected a newline or semicolon after statement.", 13..13], - ["Expected to be able to parse an expression.", 13..13], + ["Cannot parse the expression", 7..7], + ["Expected a matching `)`", 7..7], + ["Expected a newline or semicolon after the statement", 13..13], + ["Cannot parse the expression", 13..13], ] end def test_break_1 assert_errors expression("break 1,;"), "break 1,;", [ - ["Expected to be able to parse an argument.", 8..8] + ["Expected an argument", 8..8] ] end def test_argument_forwarding_when_parent_is_not_forwarding assert_errors expression('def a(x, y, z); b(...); end'), 'def a(x, y, z); b(...); end', [ - ["unexpected ... when parent method is not forwarding.", 18..21] + ["Unexpected `...` when the parent method is not forwarding", 18..21] ] end def test_argument_forwarding_only_effects_its_own_internals assert_errors expression('def a(...); b(...); end; def c(x, y, z); b(...); end'), 'def a(...); b(...); end; def c(x, y, z); b(...); end', [ - ["unexpected ... when parent method is not forwarding.", 43..46] + ["Unexpected `...` when the parent method is not forwarding", 43..46] ] end def test_top_level_constant_with_downcased_identifier assert_error_messages "::foo", [ - "Expected a constant after ::.", - "Expected a newline or semicolon after statement." + "Expected a constant after the `::` operator", + "Expected a newline or semicolon after the statement" ] end def test_top_level_constant_starting_with_downcased_identifier assert_error_messages "::foo::A", [ - "Expected a constant after ::.", - "Expected a newline or semicolon after statement." + "Expected a constant after the `::` operator", + "Expected a newline or semicolon after the statement" ] end def test_aliasing_global_variable_with_non_global_variable assert_errors expression("alias $a b"), "alias $a b", [ - ["Expected a global variable.", 9..10] + ["Invalid argument being passed to `alias`; expected a bare word, symbol, constant, or global variable", 9..10] ] end def test_aliasing_non_global_variable_with_global_variable assert_errors expression("alias a $b"), "alias a $b", [ - ["Expected a bare word or symbol argument.", 8..10] + ["Invalid argument being passed to `alias`; expected a bare word, symbol, constant, or global variable", 8..10] ] end def test_aliasing_global_variable_with_global_number_variable assert_errors expression("alias $a $1"), "alias $a $1", [ - ["Can't make alias for number variables.", 9..11] + ["Invalid argument being passed to `alias`; expected a bare word, symbol, constant, or global variable", 9..11] ] end def test_def_with_expression_receiver_and_no_identifier assert_errors expression("def (a); end"), "def (a); end", [ - ["Expected '.' or '::' after receiver", 7..7] + ["Expected a `.` or `::` after the receiver in a method definition", 7..7] ] end def test_def_with_multiple_statements_receiver assert_errors expression("def (\na\nb\n).c; end"), "def (\na\nb\n).c; end", [ - ["Expected closing ')' for receiver.", 7..7], - ["Expected '.' or '::' after receiver", 7..7], - ["Expected to be able to parse an expression.", 10..10], - ["Expected to be able to parse an expression.", 11..11] + ["Expected a matching `)`", 7..7], + ["Expected a `.` or `::` after the receiver in a method definition", 7..7], + ["Cannot parse the expression", 10..10], + ["Cannot parse the expression", 11..11] ] end def test_def_with_empty_expression_receiver assert_errors expression("def ().a; end"), "def ().a; end", [ - ["Expected to be able to parse receiver.", 5..5] + ["Expected a receiver for the method definition", 5..5] ] end def test_block_beginning_with_brace_and_ending_with_end assert_error_messages "x.each { x end", [ - "Expected a newline or semicolon after statement.", - "Expected to be able to parse an expression.", - "Expected to be able to parse an expression.", - "Expected block beginning with '{' to end with '}'." + "Expected a newline or semicolon after the statement", + "Cannot parse the expression", + "Cannot parse the expression", + "Expected a block beginning with `{` to end with `}`" ] end @@ -328,7 +328,7 @@ def test_double_splat_followed_by_splat_argument ) assert_errors expected, "a(**kwargs, *args)", [ - ["Unexpected splat argument after double splat.", 12..17] + ["Unexpected `*` splat argument after a `**` keyword splat argument", 12..17] ] end @@ -349,15 +349,15 @@ def test_arguments_after_block ) assert_errors expected, "a(&block, foo)", [ - ["Unexpected argument after block argument.", 10..13] + ["Unexpected argument after a block argument", 10..13] ] end def test_arguments_binding_power_for_and assert_error_messages "foo(*bar and baz)", [ - "Expected a ')' to close the argument list.", - "Expected a newline or semicolon after statement.", - "Expected to be able to parse an expression." + "Expected a `)` to close the arguments", + "Expected a newline or semicolon after the statement", + "Cannot parse the expression" ] end @@ -384,7 +384,7 @@ def test_splat_argument_after_keyword_argument ) assert_errors expected, "a(foo: bar, *args)", [ - ["Unexpected splat argument after double splat.", 12..17] + ["Unexpected `*` splat argument after a `**` keyword splat argument", 12..17] ] end @@ -405,7 +405,7 @@ def test_module_definition_in_method_body ) assert_errors expected, "def foo;module A;end;end", [ - ["Module definition in method body", 8..14] + ["Unexpected module definition in a method body", 8..14] ] end @@ -443,7 +443,7 @@ def test_module_definition_in_method_body_within_block Location() ) - assert_errors expected, <<~RUBY, [["Module definition in method body", 21..27]] + assert_errors expected, <<~RUBY, [["Unexpected module definition in a method body", 21..27]] def foo bar do module Foo;end @@ -480,7 +480,7 @@ def test_class_definition_in_method_body ) assert_errors expected, "def foo;class A;end;end", [ - ["Class definition in method body", 8..13] + ["Unexpected class definition in a method body", 8..13] ] end @@ -506,10 +506,10 @@ def test_bad_arguments ) assert_errors expected, "def foo(A, @a, $A, @@a);end", [ - ["Formal argument cannot be a constant", 8..9], - ["Formal argument cannot be an instance variable", 11..13], - ["Formal argument cannot be a global variable", 15..17], - ["Formal argument cannot be a class variable", 19..22], + ["Invalid formal argument; formal argument cannot be a constant", 8..9], + ["Invalid formal argument; formal argument cannot be an instance variable", 11..13], + ["Invalid formal argument; formal argument cannot be a global variable", 15..17], + ["Invalid formal argument; formal argument cannot be a class variable", 19..22], ] end @@ -540,15 +540,15 @@ def test_cannot_assign_to_a_reserved_numbered_parameter end RUBY assert_errors expected, source, [ - ["reserved for numbered parameter", 8..10], - ["reserved for numbered parameter", 14..16], - ["reserved for numbered parameter", 20..22], - ["reserved for numbered parameter", 26..28], - ["reserved for numbered parameter", 32..34], - ["reserved for numbered parameter", 40..42], - ["reserved for numbered parameter", 46..48], - ["reserved for numbered parameter", 52..54], - ["reserved for numbered parameter", 58..60], + ["Token reserved for a numbered parameter", 8..10], + ["Token reserved for a numbered parameter", 14..16], + ["Token reserved for a numbered parameter", 20..22], + ["Token reserved for a numbered parameter", 26..28], + ["Token reserved for a numbered parameter", 32..34], + ["Token reserved for a numbered parameter", 40..42], + ["Token reserved for a numbered parameter", 46..48], + ["Token reserved for a numbered parameter", 52..54], + ["Token reserved for a numbered parameter", 58..60], ] end @@ -577,7 +577,7 @@ def test_do_not_allow_trailing_commas_in_method_parameters ) assert_errors expected, "def foo(a,b,c,);end", [ - ["Unexpected ','.", 13..14] + ["Unexpected `,` in parameters", 13..14] ] end @@ -596,7 +596,7 @@ def test_do_not_allow_trailing_commas_in_lambda_parameters nil ) assert_errors expected, "-> (a, b, ) {}", [ - ["Unexpected ','.", 8..9] + ["Unexpected `,` in parameters", 8..9] ] end @@ -604,13 +604,13 @@ def test_do_not_allow_multiple_codepoints_in_a_single_character_literal expected = StringNode(Location(), Location(), nil, "\u0001\u0002") assert_errors expected, '?\u{0001 0002}', [ - ["Multiple codepoints at single character literal", 9..12] + ["Invalid Unicode escape sequence; multiple codepoints are not allowed in a character literal", 9..12] ] end def test_invalid_hex_escape assert_errors expression('"\\xx"'), '"\\xx"', [ - ["Invalid hex escape.", 1..3], + ["Invalid hexadecimal escape sequence", 1..3], ] end @@ -618,7 +618,7 @@ def test_do_not_allow_more_than_6_hexadecimal_digits_in_u_Unicode_character_nota expected = StringNode(Location(), Location(), Location(), "\u0001") assert_errors expected, '"\u{0000001}"', [ - ["invalid Unicode escape.", 4..11], + ["Invalid Unicode escape sequence; maximum length is 6 digits", 4..11], ] end @@ -626,13 +626,13 @@ def test_do_not_allow_characters_other_than_0_9_a_f_and_A_F_in_u_Unicode_charact expected = StringNode(Location(), Location(), Location(), "\u0000z}") assert_errors expected, '"\u{000z}"', [ - ["unterminated Unicode escape", 7..7], + ["Invalid Unicode escape sequence", 7..7], ] end def test_unterminated_unicode_brackets_should_be_a_syntax_error assert_errors expression('?\\u{3'), '?\\u{3', [ - ["invalid Unicode escape.", 1..5], + ["Invalid Unicode escape sequence; needs closing `}`", 1..5], ] end @@ -923,7 +923,7 @@ def test_case_without_when_clauses_errors_on_else_clause ) assert_errors expected, "case :a\nelse\nend", [ - ["Unexpected else without no when clauses in case statement.", 8..12] + ["Unexpected `else` in `case` statement; a `when` clause must precede `else`", 8..12] ] end @@ -944,7 +944,7 @@ def test_setter_method_cannot_be_defined_in_an_endless_method_definition ) assert_errors expected, "def a=() = 42", [ - ["Setter method cannot be defined in an endless method definition", 4..6] + ["Invalid method name; a setter method cannot be defined in an endless method definition", 4..6] ] end @@ -959,7 +959,7 @@ def test_do_not_allow_forward_arguments_in_lambda_literals ) assert_errors expected, "->(...) {}", [ - ["Unexpected ...", 3..6] + ["Unexpected `...` when the parent method is not forwarding", 3..6] ] end @@ -983,7 +983,7 @@ def test_do_not_allow_forward_arguments_in_blocks ) assert_errors expected, "a {|...|}", [ - ["Unexpected ...", 4..7] + ["Unexpected `...` when the parent method is not forwarding", 4..7] ] end @@ -1000,7 +1000,7 @@ def test_dont_allow_return_inside_class_body ) assert_errors expected, "class A; return; end", [ - ["Invalid return in class/module body", 15..16] + ["Invalid `return` in a class or module body", 15..16] ] end @@ -1015,7 +1015,7 @@ def test_dont_allow_return_inside_module_body ) assert_errors expected, "module A; return; end", [ - ["Invalid return in class/module body", 16..17] + ["Invalid `return` in a class or module body", 16..17] ] end @@ -1033,8 +1033,8 @@ def test_dont_allow_setting_to_back_and_nth_reference ) assert_errors expected, "begin\n$+ = nil\n$1466 = nil\nend", [ - ["Can't set variable", 6..8], - ["Can't set variable", 15..20] + ["Immutable variable as a write target", 6..8], + ["Immutable variable as a write target", 15..20] ] end @@ -1058,7 +1058,7 @@ def test_duplicated_parameter_names ) assert_errors expected, "def foo(a,b,a);end", [ - ["Duplicated parameter name.", 12..13] + ["Repeated parameter name", 12..13] ] end @@ -1078,7 +1078,7 @@ def test_duplicated_parameter_names ) assert_errors expected, "def foo(a,b,*a);end", [ - ["Duplicated parameter name.", 13..14] + ["Repeated parameter name", 13..14] ] expected = DefNode( @@ -1097,7 +1097,7 @@ def test_duplicated_parameter_names ) assert_errors expected, "def foo(a,b,**a);end", [ - ["Duplicated parameter name.", 14..15] + ["Repeated parameter name", 14..15] ] expected = DefNode( @@ -1116,7 +1116,7 @@ def test_duplicated_parameter_names ) assert_errors expected, "def foo(a,b,&a);end", [ - ["Duplicated parameter name.", 13..14] + ["Repeated parameter name", 13..14] ] expected = DefNode( @@ -1134,12 +1134,12 @@ def test_duplicated_parameter_names Location() ) - assert_errors expected, "def foo(a = 1,b,*c);end", [["Unexpected parameter *", 16..17]] + assert_errors expected, "def foo(a = 1,b,*c);end", [["Unexpected parameter `*`", 16..17]] end def test_unterminated_global_variable assert_errors expression("$"), "$", [ - ["Invalid global variable.", 0..1] + ["Invalid global variable", 0..1] ] end diff --git a/yarp/diagnostic.c b/yarp/diagnostic.c index b216d96a330974..e92a1ee49109fd 100644 --- a/yarp/diagnostic.c +++ b/yarp/diagnostic.c @@ -1,12 +1,264 @@ #include "yarp/diagnostic.h" +/* + ## Message composition + + When composing an error message, use sentence fragments. + + Try describing the property of the code that caused the error, rather than the rule that is being + violated. It may help to use a fragment that completes a sentence beginning, "The parser + encountered (a) ...". If appropriate, add a description of the rule violation (or other helpful + context) after a semicolon. + + For example:, instead of "Control escape sequence cannot be doubled", prefer: + + > "Invalid control escape sequence; control cannot be repeated" + + In some cases, where the failure is more general or syntax expectations are violated, it may make + more sense to use a fragment that completes a sentence beginning, "The parser ...". + + For example: + + > "Expected an expression after `(`" + > "Cannot parse the expression" + + + ## Message style guide + + - Use articles like "a", "an", and "the" when appropriate. + - e.g., prefer "Cannot parse the expression" to "Cannot parse expression". + - Use the common name for tokens and nodes. + - e.g., prefer "keyword splat" to "assoc splat" + - e.g., prefer "embedded document" to "embdoc" + - Capitalize the initial word of the message. + - Use back ticks around token literals + - e.g., "Expected a `=>` between the hash key and value" + - Do not use `.` or other punctuation at the end of the message. + - Do not use contractions like "can't". Prefer "cannot" to "can not". + - For tokens that can have multiple meanings, reference the token and its meaning. + - e.g., "`*` splat argument" is clearer and more complete than "splat argument" or "`*` argument" + + + ## Error names (YP_ERR_*) + + - When appropriate, prefer node name to token name. + - e.g., prefer "SPLAT" to "STAR" in the context of argument parsing. + - Prefer token name to common name. + - e.g., prefer "STAR" to "ASTERISK". + - Try to order the words in the name from more general to more specific, + - e.g., "INVALID_NUMBER_DECIMAL" is better than "DECIMAL_INVALID_NUMBER". + - When in doubt, look for similar patterns and name them so that they are grouped when lexically + sorted. See YP_ERR_ARGUMENT_NO_FORWARDING_* for an example. +*/ + +static const char* const diagnostic_messages[YP_DIAGNOSTIC_ID_LEN] = { + [YP_ERR_ALIAS_ARGUMENT] = "Invalid argument being passed to `alias`; expected a bare word, symbol, constant, or global variable", + [YP_ERR_AMPAMPEQ_MULTI_ASSIGN] = "Unexpected `&&=` in a multiple assignment", + [YP_ERR_ARGUMENT_AFTER_BLOCK] = "Unexpected argument after a block argument", + [YP_ERR_ARGUMENT_BARE_HASH] = "Unexpected bare hash argument", + [YP_ERR_ARGUMENT_BLOCK_MULTI] = "Multiple block arguments; only one block is allowed", + [YP_ERR_ARGUMENT_FORMAL_CLASS] = "Invalid formal argument; formal argument cannot be a class variable", + [YP_ERR_ARGUMENT_FORMAL_CONSTANT] = "Invalid formal argument; formal argument cannot be a constant", + [YP_ERR_ARGUMENT_FORMAL_GLOBAL] = "Invalid formal argument; formal argument cannot be a global variable", + [YP_ERR_ARGUMENT_FORMAL_IVAR] = "Invalid formal argument; formal argument cannot be an instance variable", + [YP_ERR_ARGUMENT_NO_FORWARDING_AMP] = "Unexpected `&` when the parent method is not forwarding", + [YP_ERR_ARGUMENT_NO_FORWARDING_ELLIPSES] = "Unexpected `...` when the parent method is not forwarding", + [YP_ERR_ARGUMENT_NO_FORWARDING_STAR] = "Unexpected `*` when the parent method is not forwarding", + [YP_ERR_ARGUMENT_SPLAT_AFTER_ASSOC_SPLAT] = "Unexpected `*` splat argument after a `**` keyword splat argument", + [YP_ERR_ARGUMENT_SPLAT_AFTER_SPLAT] = "Unexpected `*` splat argument after a `*` splat argument", + [YP_ERR_ARGUMENT_TERM_PAREN] = "Expected a `)` to close the arguments", + [YP_ERR_ARRAY_ELEMENT] = "Expected an element for the array", + [YP_ERR_ARRAY_EXPRESSION] = "Expected an expression for the array element", + [YP_ERR_ARRAY_EXPRESSION_AFTER_STAR] = "Expected an expression after `*` in the array", + [YP_ERR_ARRAY_SEPARATOR] = "Expected a `,` separator for the array elements", + [YP_ERR_ARRAY_TERM] = "Expected a `]` to close the array", + [YP_ERR_BEGIN_LONELY_ELSE] = "Unexpected `else` in `begin` block; a `rescue` clause must precede `else`", + [YP_ERR_BEGIN_TERM] = "Expected an `end` to close the `begin` statement", + [YP_ERR_BEGIN_UPCASE_BRACE] = "Expected a `{` after `BEGIN`", + [YP_ERR_BEGIN_UPCASE_TERM] = "Expected a `}` to close the `BEGIN` statement", + [YP_ERR_BLOCK_PARAM_LOCAL_VARIABLE] = "Expected a local variable name in the block parameters", + [YP_ERR_BLOCK_PARAM_PIPE_TERM] = "Expected the block parameters to end with `|`", + [YP_ERR_BLOCK_TERM_BRACE] = "Expected a block beginning with `{` to end with `}`", + [YP_ERR_BLOCK_TERM_END] = "Expected a block beginning with `do` to end with `end`", + [YP_ERR_CANNOT_PARSE_EXPRESSION] = "Cannot parse the expression", + [YP_ERR_CANNOT_PARSE_STRING_PART] = "Cannot parse the string part", + [YP_ERR_CASE_EXPRESSION_AFTER_CASE] = "Expected an expression after `case`", + [YP_ERR_CASE_EXPRESSION_AFTER_WHEN] = "Expected an expression after `when`", + [YP_ERR_CASE_LONELY_ELSE] = "Unexpected `else` in `case` statement; a `when` clause must precede `else`", + [YP_ERR_CASE_TERM] = "Expected an `end` to close the `case` statement", + [YP_ERR_CLASS_IN_METHOD] = "Unexpected class definition in a method body", + [YP_ERR_CLASS_NAME] = "Expected a constant name after `class`", + [YP_ERR_CLASS_SUPERCLASS] = "Expected a superclass after `<`", + [YP_ERR_CLASS_TERM] = "Expected an `end` to close the `class` statement", + [YP_ERR_CONDITIONAL_ELSIF_PREDICATE] = "Expected a predicate expression for the `elsif` statement", + [YP_ERR_CONDITIONAL_IF_PREDICATE] = "Expected a predicate expression for the `if` statement", + [YP_ERR_CONDITIONAL_TERM] = "Expected an `end` to close the conditional clause", + [YP_ERR_CONDITIONAL_TERM_ELSE] = "Expected an `end` to close the `else` clause", + [YP_ERR_CONDITIONAL_UNLESS_PREDICATE] = "Expected a predicate expression for the `unless` statement", + [YP_ERR_CONDITIONAL_UNTIL_PREDICATE] = "Expected a predicate expression for the `until` statement", + [YP_ERR_CONDITIONAL_WHILE_PREDICATE] = "Expected a predicate expression for the `while` statement", + [YP_ERR_CONSTANT_PATH_COLON_COLON_CONSTANT] = "Expected a constant after the `::` operator", + [YP_ERR_DEF_ENDLESS] = "Could not parse the endless method body", + [YP_ERR_DEF_ENDLESS_SETTER] = "Invalid method name; a setter method cannot be defined in an endless method definition", + [YP_ERR_DEF_NAME] = "Expected a method name", + [YP_ERR_DEF_NAME_AFTER_RECEIVER] = "Expected a method name after the receiver", + [YP_ERR_DEF_PARAMS_TERM] = "Expected a delimiter to close the parameters", + [YP_ERR_DEF_PARAMS_TERM_PAREN] = "Expected a `)` to close the parameters", + [YP_ERR_DEF_RECEIVER] = "Expected a receiver for the method definition", + [YP_ERR_DEF_RECEIVER_TERM] = "Expected a `.` or `::` after the receiver in a method definition", + [YP_ERR_DEF_TERM] = "Expected an `end` to close the `def` statement", + [YP_ERR_DEFINED_EXPRESSION] = "Expected an expression after `defined?`", + [YP_ERR_EMBDOC_TERM] = "Could not find a terminator for the embedded document", + [YP_ERR_EMBEXPR_END] = "Expected a `}` to close the embedded expression", + [YP_ERR_EMBVAR_INVALID] = "Invalid embedded variable", + [YP_ERR_END_UPCASE_BRACE] = "Expected a `{` after `END`", + [YP_ERR_END_UPCASE_TERM] = "Expected a `}` to close the `END` statement", + [YP_ERR_ESCAPE_INVALID_CONTROL] = "Invalid control escape sequence", + [YP_ERR_ESCAPE_INVALID_CONTROL_REPEAT] = "Invalid control escape sequence; control cannot be repeated", + [YP_ERR_ESCAPE_INVALID_HEXADECIMAL] = "Invalid hexadecimal escape sequence", + [YP_ERR_ESCAPE_INVALID_META] = "Invalid meta escape sequence", + [YP_ERR_ESCAPE_INVALID_META_REPEAT] = "Invalid meta escape sequence; meta cannot be repeated", + [YP_ERR_ESCAPE_INVALID_UNICODE] = "Invalid Unicode escape sequence", + [YP_ERR_ESCAPE_INVALID_UNICODE_CM_FLAGS] = "Invalid Unicode escape sequence; Unicode cannot be combined with control or meta flags", + [YP_ERR_ESCAPE_INVALID_UNICODE_LITERAL] = "Invalid Unicode escape sequence; multiple codepoints are not allowed in a character literal", + [YP_ERR_ESCAPE_INVALID_UNICODE_LONG] = "Invalid Unicode escape sequence; maximum length is 6 digits", + [YP_ERR_ESCAPE_INVALID_UNICODE_TERM] = "Invalid Unicode escape sequence; needs closing `}`", + [YP_ERR_EXPECT_ARGUMENT] = "Expected an argument", + [YP_ERR_EXPECT_EOL_AFTER_STATEMENT] = "Expected a newline or semicolon after the statement", + [YP_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ] = "Expected an expression after `&&=`", + [YP_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ] = "Expected an expression after `||=`", + [YP_ERR_EXPECT_EXPRESSION_AFTER_COMMA] = "Expected an expression after `,`", + [YP_ERR_EXPECT_EXPRESSION_AFTER_EQUAL] = "Expected an expression after `=`", + [YP_ERR_EXPECT_EXPRESSION_AFTER_LESS_LESS] = "Expected an expression after `<<`", + [YP_ERR_EXPECT_EXPRESSION_AFTER_LPAREN] = "Expected an expression after `(`", + [YP_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR] = "Expected an expression after the operator", + [YP_ERR_EXPECT_EXPRESSION_AFTER_SPLAT] = "Expected an expression after `*` splat in an argument", + [YP_ERR_EXPECT_EXPRESSION_AFTER_SPLAT_HASH] = "Expected an expression after `**` in a hash", + [YP_ERR_EXPECT_EXPRESSION_AFTER_STAR] = "Expected an expression after `*`", + [YP_ERR_EXPECT_IDENT_REQ_PARAMETER] = "Expected an identifier for the required parameter", + [YP_ERR_EXPECT_LPAREN_REQ_PARAMETER] = "Expected a `(` to start a required parameter", + [YP_ERR_EXPECT_RBRACKET] = "Expected a matching `]`", + [YP_ERR_EXPECT_RPAREN] = "Expected a matching `)`", + [YP_ERR_EXPECT_RPAREN_AFTER_MULTI] = "Expected a `)` after multiple assignment", + [YP_ERR_EXPECT_RPAREN_REQ_PARAMETER] = "Expected a `)` to end a required parameter", + [YP_ERR_EXPECT_STRING_CONTENT] = "Expected string content after opening string delimiter", + [YP_ERR_EXPECT_WHEN_DELIMITER] = "Expected a delimiter after the predicates of a `when` clause", + [YP_ERR_EXPRESSION_BARE_HASH] = "Unexpected bare hash in expression", + [YP_ERR_FOR_COLLECTION] = "Expected a collection after the `in` in a `for` statement", + [YP_ERR_FOR_INDEX] = "Expected an index after `for`", + [YP_ERR_FOR_IN] = "Expected an `in` after the index in a `for` statement", + [YP_ERR_FOR_TERM] = "Expected an `end` to close the `for` loop", + [YP_ERR_HASH_EXPRESSION_AFTER_LABEL] = "Expected an expression after the label in a hash", + [YP_ERR_HASH_KEY] = "Expected a key in the hash literal", + [YP_ERR_HASH_ROCKET] = "Expected a `=>` between the hash key and value", + [YP_ERR_HASH_TERM] = "Expected a `}` to close the hash literal", + [YP_ERR_HASH_VALUE] = "Expected a value in the hash literal", + [YP_ERR_HEREDOC_TERM] = "Could not find a terminator for the heredoc", + [YP_ERR_INCOMPLETE_QUESTION_MARK] = "Incomplete expression at `?`", + [YP_ERR_INCOMPLETE_VARIABLE_CLASS] = "Incomplete class variable", + [YP_ERR_INCOMPLETE_VARIABLE_INSTANCE] = "Incomplete instance variable", + [YP_ERR_INVALID_ENCODING_MAGIC_COMMENT] = "Unknown or invalid encoding in the magic comment", + [YP_ERR_INVALID_FLOAT_EXPONENT] = "Invalid exponent", + [YP_ERR_INVALID_NUMBER_BINARY] = "Invalid binary number", + [YP_ERR_INVALID_NUMBER_DECIMAL] = "Invalid decimal number", + [YP_ERR_INVALID_NUMBER_HEXADECIMAL] = "Invalid hexadecimal number", + [YP_ERR_INVALID_NUMBER_OCTAL] = "Invalid octal number", + [YP_ERR_INVALID_PERCENT] = "Invalid `%` token", // TODO WHAT? + [YP_ERR_INVALID_TOKEN] = "Invalid token", // TODO WHAT? + [YP_ERR_INVALID_VARIABLE_GLOBAL] = "Invalid global variable", + [YP_ERR_LAMBDA_OPEN] = "Expected a `do` keyword or a `{` to open the lambda block", + [YP_ERR_LAMBDA_TERM_BRACE] = "Expected a lambda block beginning with `{` to end with `}`", + [YP_ERR_LAMBDA_TERM_END] = "Expected a lambda block beginning with `do` to end with `end`", + [YP_ERR_LIST_I_LOWER_ELEMENT] = "Expected a symbol in a `%i` list", + [YP_ERR_LIST_I_LOWER_TERM] = "Expected a closing delimiter for the `%i` list", + [YP_ERR_LIST_I_UPPER_ELEMENT] = "Expected a symbol in a `%I` list", + [YP_ERR_LIST_I_UPPER_TERM] = "Expected a closing delimiter for the `%I` list", + [YP_ERR_LIST_W_LOWER_ELEMENT] = "Expected a string in a `%w` list", + [YP_ERR_LIST_W_LOWER_TERM] = "Expected a closing delimiter for the `%w` list", + [YP_ERR_LIST_W_UPPER_ELEMENT] = "Expected a string in a `%W` list", + [YP_ERR_LIST_W_UPPER_TERM] = "Expected a closing delimiter for the `%W` list", + [YP_ERR_MALLOC_FAILED] = "Failed to allocate memory", + [YP_ERR_MODULE_IN_METHOD] = "Unexpected module definition in a method body", + [YP_ERR_MODULE_NAME] = "Expected a constant name after `module`", + [YP_ERR_MODULE_TERM] = "Expected an `end` to close the `module` statement", + [YP_ERR_MULTI_ASSIGN_MULTI_SPLATS] = "Multiple splats in multiple assignment", + [YP_ERR_NOT_EXPRESSION] = "Expected an expression after `not`", + [YP_ERR_NUMBER_LITERAL_UNDERSCORE] = "Number literal ending with a `_`", + [YP_ERR_OPERATOR_MULTI_ASSIGN] = "Unexpected operator for a multiple assignment", + [YP_ERR_PARAMETER_ASSOC_SPLAT_MULTI] = "Unexpected multiple `**` splat parameters", + [YP_ERR_PARAMETER_BLOCK_MULTI] = "Multiple block parameters; only one block is allowed", + [YP_ERR_PARAMETER_NAME_REPEAT] = "Repeated parameter name", + [YP_ERR_PARAMETER_NO_DEFAULT] = "Expected a default value for the parameter", + [YP_ERR_PARAMETER_NO_DEFAULT_KW] = "Expected a default value for the keyword parameter", + [YP_ERR_PARAMETER_NUMBERED_RESERVED] = "Token reserved for a numbered parameter", + [YP_ERR_PARAMETER_ORDER] = "Unexpected parameter order", + [YP_ERR_PARAMETER_SPLAT_MULTI] = "Unexpected multiple `*` splat parameters", + [YP_ERR_PARAMETER_STAR] = "Unexpected parameter `*`", + [YP_ERR_PARAMETER_WILD_LOOSE_COMMA] = "Unexpected `,` in parameters", + [YP_ERR_PATTERN_EXPRESSION_AFTER_BRACKET] = "Expected a pattern expression after the `[` operator", + [YP_ERR_PATTERN_EXPRESSION_AFTER_COMMA] = "Expected a pattern expression after `,`", + [YP_ERR_PATTERN_EXPRESSION_AFTER_HROCKET] = "Expected a pattern expression after `=>`", + [YP_ERR_PATTERN_EXPRESSION_AFTER_IN] = "Expected a pattern expression after the `in` keyword", + [YP_ERR_PATTERN_EXPRESSION_AFTER_KEY] = "Expected a pattern expression after the key", + [YP_ERR_PATTERN_EXPRESSION_AFTER_PAREN] = "Expected a pattern expression after the `(` operator", + [YP_ERR_PATTERN_EXPRESSION_AFTER_PIN] = "Expected a pattern expression after the `^` pin operator", + [YP_ERR_PATTERN_EXPRESSION_AFTER_PIPE] = "Expected a pattern expression after the `|` operator", + [YP_ERR_PATTERN_EXPRESSION_AFTER_RANGE] = "Expected a pattern expression after the range operator", + [YP_ERR_PATTERN_HASH_KEY] = "Expected a key in the hash pattern", + [YP_ERR_PATTERN_HASH_KEY_LABEL] = "Expected a label as the key in the hash pattern", // TODO // THIS // AND // ABOVE // IS WEIRD + [YP_ERR_PATTERN_IDENT_AFTER_HROCKET] = "Expected an identifier after the `=>` operator", + [YP_ERR_PATTERN_LABEL_AFTER_COMMA] = "Expected a label after the `,` in the hash pattern", + [YP_ERR_PATTERN_REST] = "Unexpected rest pattern", + [YP_ERR_PATTERN_TERM_BRACE] = "Expected a `}` to close the pattern expression", + [YP_ERR_PATTERN_TERM_BRACKET] = "Expected a `]` to close the pattern expression", + [YP_ERR_PATTERN_TERM_PAREN] = "Expected a `)` to close the pattern expression", + [YP_ERR_PIPEPIPEEQ_MULTI_ASSIGN] = "Unexpected `||=` in a multiple assignment", + [YP_ERR_REGEXP_TERM] = "Expected a closing delimiter for the regular expression", + [YP_ERR_RESCUE_EXPRESSION] = "Expected a rescued expression", + [YP_ERR_RESCUE_MODIFIER_VALUE] = "Expected a value after the `rescue` modifier", + [YP_ERR_RESCUE_TERM] = "Expected a closing delimiter for the `rescue` clause", + [YP_ERR_RESCUE_VARIABLE] = "Expected an exception variable after `=>` in a rescue statement", + [YP_ERR_RETURN_INVALID] = "Invalid `return` in a class or module body", + [YP_ERR_STRING_CONCATENATION] = "Expected a string for concatenation", + [YP_ERR_STRING_INTERPOLATED_TERM] = "Expected a closing delimiter for the interpolated string", + [YP_ERR_STRING_LITERAL_TERM] = "Expected a closing delimiter for the string literal", + [YP_ERR_SYMBOL_INVALID] = "Invalid symbol", // TODO expected symbol? yarp.c ~9719 + [YP_ERR_SYMBOL_TERM_DYNAMIC] = "Expected a closing delimiter for the dynamic symbol", + [YP_ERR_SYMBOL_TERM_INTERPOLATED] = "Expected a closing delimiter for the interpolated symbol", + [YP_ERR_TERNARY_COLON] = "Expected a `:` after the true expression of a ternary operator", + [YP_ERR_TERNARY_EXPRESSION_FALSE] = "Expected an expression after `:` in the ternary operator", + [YP_ERR_TERNARY_EXPRESSION_TRUE] = "Expected an expression after `?` in the ternary operator", + [YP_ERR_UNDEF_ARGUMENT] = "Invalid argument being passed to `undef`; expected a bare word, constant, or symbol argument", + [YP_ERR_UNARY_RECEIVER_BANG] = "Expected a receiver for unary `!`", + [YP_ERR_UNARY_RECEIVER_MINUS] = "Expected a receiver for unary `-`", + [YP_ERR_UNARY_RECEIVER_PLUS] = "Expected a receiver for unary `+`", + [YP_ERR_UNARY_RECEIVER_TILDE] = "Expected a receiver for unary `~`", + [YP_ERR_UNTIL_TERM] = "Expected an `end` to close the `until` statement", + [YP_ERR_WHILE_TERM] = "Expected an `end` to close the `while` statement", + [YP_ERR_WRITE_TARGET_READONLY] = "Immutable variable as a write target", + [YP_ERR_WRITE_TARGET_UNEXPECTED] = "Unexpected write target", + [YP_ERR_XSTRING_TERM] = "Expected a closing delimiter for the `%x` or backtick string", + [YP_WARN_AMBIGUOUS_FIRST_ARGUMENT_MINUS] = "Ambiguous first argument; put parentheses or a space even after `-` operator", + [YP_WARN_AMBIGUOUS_FIRST_ARGUMENT_PLUS] = "Ambiguous first argument; put parentheses or a space even after `+` operator", + [YP_WARN_AMBIGUOUS_PREFIX_STAR] = "Ambiguous `*` has been interpreted as an argument prefix", + [YP_WARN_AMBIGUOUS_SLASH] = "Ambiguous `/`; wrap regexp in parentheses or add a space after `/` operator", +}; + +static const char* +yp_diagnostic_message(yp_diagnostic_id_t diag_id) { + assert(diag_id < YP_DIAGNOSTIC_ID_LEN); + const char *message = diagnostic_messages[diag_id]; + assert(message); + return message; +} + // Append an error to the given list of diagnostic. bool -yp_diagnostic_list_append(yp_list_t *list, const uint8_t *start, const uint8_t *end, const char *message) { +yp_diagnostic_list_append(yp_list_t *list, const uint8_t *start, const uint8_t *end, yp_diagnostic_id_t diag_id) { yp_diagnostic_t *diagnostic = (yp_diagnostic_t *) malloc(sizeof(yp_diagnostic_t)); if (diagnostic == NULL) return false; - *diagnostic = (yp_diagnostic_t) { .start = start, .end = end, .message = message }; + *diagnostic = (yp_diagnostic_t) { .start = start, .end = end, .message = yp_diagnostic_message(diag_id) }; yp_list_append(list, (yp_list_node_t *) diagnostic); return true; } diff --git a/yarp/diagnostic.h b/yarp/diagnostic.h index 58228d8493ad31..fd17945e0d9e24 100644 --- a/yarp/diagnostic.h +++ b/yarp/diagnostic.h @@ -6,6 +6,7 @@ #include #include +#include // This struct represents a diagnostic found during parsing. typedef struct { @@ -15,8 +16,204 @@ typedef struct { const char *message; } yp_diagnostic_t; +typedef enum { + YP_ERR_ALIAS_ARGUMENT, + YP_ERR_AMPAMPEQ_MULTI_ASSIGN, + YP_ERR_ARGUMENT_AFTER_BLOCK, + YP_ERR_ARGUMENT_BARE_HASH, + YP_ERR_ARGUMENT_BLOCK_MULTI, + YP_ERR_ARGUMENT_FORMAL_CLASS, + YP_ERR_ARGUMENT_FORMAL_CONSTANT, + YP_ERR_ARGUMENT_FORMAL_GLOBAL, + YP_ERR_ARGUMENT_FORMAL_IVAR, + YP_ERR_ARGUMENT_NO_FORWARDING_AMP, + YP_ERR_ARGUMENT_NO_FORWARDING_ELLIPSES, + YP_ERR_ARGUMENT_NO_FORWARDING_STAR, + YP_ERR_ARGUMENT_SPLAT_AFTER_ASSOC_SPLAT, + YP_ERR_ARGUMENT_SPLAT_AFTER_SPLAT, + YP_ERR_ARGUMENT_TERM_PAREN, + YP_ERR_ARRAY_ELEMENT, + YP_ERR_ARRAY_EXPRESSION, + YP_ERR_ARRAY_EXPRESSION_AFTER_STAR, + YP_ERR_ARRAY_SEPARATOR, + YP_ERR_ARRAY_TERM, + YP_ERR_BEGIN_LONELY_ELSE, + YP_ERR_BEGIN_TERM, + YP_ERR_BEGIN_UPCASE_BRACE, + YP_ERR_BEGIN_UPCASE_TERM, + YP_ERR_BLOCK_PARAM_LOCAL_VARIABLE, + YP_ERR_BLOCK_PARAM_PIPE_TERM, + YP_ERR_BLOCK_TERM_BRACE, + YP_ERR_BLOCK_TERM_END, + YP_ERR_CANNOT_PARSE_EXPRESSION, + YP_ERR_CANNOT_PARSE_STRING_PART, + YP_ERR_CASE_EXPRESSION_AFTER_CASE, + YP_ERR_CASE_EXPRESSION_AFTER_WHEN, + YP_ERR_CASE_LONELY_ELSE, + YP_ERR_CASE_TERM, + YP_ERR_CLASS_IN_METHOD, + YP_ERR_CLASS_NAME, + YP_ERR_CLASS_SUPERCLASS, + YP_ERR_CLASS_TERM, + YP_ERR_CONDITIONAL_ELSIF_PREDICATE, + YP_ERR_CONDITIONAL_IF_PREDICATE, + YP_ERR_CONDITIONAL_TERM, + YP_ERR_CONDITIONAL_TERM_ELSE, + YP_ERR_CONDITIONAL_UNLESS_PREDICATE, + YP_ERR_CONDITIONAL_UNTIL_PREDICATE, + YP_ERR_CONDITIONAL_WHILE_PREDICATE, + YP_ERR_CONSTANT_PATH_COLON_COLON_CONSTANT, + YP_ERR_DEF_ENDLESS, + YP_ERR_DEF_ENDLESS_SETTER, + YP_ERR_DEF_NAME, + YP_ERR_DEF_NAME_AFTER_RECEIVER, + YP_ERR_DEF_PARAMS_TERM, + YP_ERR_DEF_PARAMS_TERM_PAREN, + YP_ERR_DEF_RECEIVER, + YP_ERR_DEF_RECEIVER_TERM, + YP_ERR_DEF_TERM, + YP_ERR_DEFINED_EXPRESSION, + YP_ERR_EMBDOC_TERM, + YP_ERR_EMBEXPR_END, + YP_ERR_EMBVAR_INVALID, + YP_ERR_END_UPCASE_BRACE, + YP_ERR_END_UPCASE_TERM, + YP_ERR_ESCAPE_INVALID_CONTROL, + YP_ERR_ESCAPE_INVALID_CONTROL_REPEAT, + YP_ERR_ESCAPE_INVALID_HEXADECIMAL, + YP_ERR_ESCAPE_INVALID_META, + YP_ERR_ESCAPE_INVALID_META_REPEAT, + YP_ERR_ESCAPE_INVALID_UNICODE, + YP_ERR_ESCAPE_INVALID_UNICODE_CM_FLAGS, + YP_ERR_ESCAPE_INVALID_UNICODE_LITERAL, + YP_ERR_ESCAPE_INVALID_UNICODE_LONG, + YP_ERR_ESCAPE_INVALID_UNICODE_TERM, + YP_ERR_EXPECT_ARGUMENT, + YP_ERR_EXPECT_EOL_AFTER_STATEMENT, + YP_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ, + YP_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ, + YP_ERR_EXPECT_EXPRESSION_AFTER_COMMA, + YP_ERR_EXPECT_EXPRESSION_AFTER_EQUAL, + YP_ERR_EXPECT_EXPRESSION_AFTER_LESS_LESS, + YP_ERR_EXPECT_EXPRESSION_AFTER_LPAREN, + YP_ERR_EXPECT_EXPRESSION_AFTER_QUESTION, + YP_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR, + YP_ERR_EXPECT_EXPRESSION_AFTER_SPLAT, + YP_ERR_EXPECT_EXPRESSION_AFTER_SPLAT_HASH, + YP_ERR_EXPECT_EXPRESSION_AFTER_STAR, + YP_ERR_EXPECT_IDENT_REQ_PARAMETER, + YP_ERR_EXPECT_LPAREN_REQ_PARAMETER, + YP_ERR_EXPECT_RBRACKET, + YP_ERR_EXPECT_RPAREN, + YP_ERR_EXPECT_RPAREN_AFTER_MULTI, + YP_ERR_EXPECT_RPAREN_REQ_PARAMETER, + YP_ERR_EXPECT_STRING_CONTENT, + YP_ERR_EXPECT_WHEN_DELIMITER, + YP_ERR_EXPRESSION_BARE_HASH, + YP_ERR_FOR_COLLECTION, + YP_ERR_FOR_IN, + YP_ERR_FOR_INDEX, + YP_ERR_FOR_TERM, + YP_ERR_HASH_EXPRESSION_AFTER_LABEL, + YP_ERR_HASH_KEY, + YP_ERR_HASH_ROCKET, + YP_ERR_HASH_TERM, + YP_ERR_HASH_VALUE, + YP_ERR_HEREDOC_TERM, + YP_ERR_INCOMPLETE_QUESTION_MARK, + YP_ERR_INCOMPLETE_VARIABLE_CLASS, + YP_ERR_INCOMPLETE_VARIABLE_INSTANCE, + YP_ERR_INVALID_ENCODING_MAGIC_COMMENT, + YP_ERR_INVALID_FLOAT_EXPONENT, + YP_ERR_INVALID_NUMBER_BINARY, + YP_ERR_INVALID_NUMBER_DECIMAL, + YP_ERR_INVALID_NUMBER_HEXADECIMAL, + YP_ERR_INVALID_NUMBER_OCTAL, + YP_ERR_INVALID_PERCENT, + YP_ERR_INVALID_TOKEN, + YP_ERR_INVALID_VARIABLE_GLOBAL, + YP_ERR_LAMBDA_OPEN, + YP_ERR_LAMBDA_TERM_BRACE, + YP_ERR_LAMBDA_TERM_END, + YP_ERR_LIST_I_LOWER_ELEMENT, + YP_ERR_LIST_I_LOWER_TERM, + YP_ERR_LIST_I_UPPER_ELEMENT, + YP_ERR_LIST_I_UPPER_TERM, + YP_ERR_LIST_W_LOWER_ELEMENT, + YP_ERR_LIST_W_LOWER_TERM, + YP_ERR_LIST_W_UPPER_ELEMENT, + YP_ERR_LIST_W_UPPER_TERM, + YP_ERR_MALLOC_FAILED, + YP_ERR_MODULE_IN_METHOD, + YP_ERR_MODULE_NAME, + YP_ERR_MODULE_TERM, + YP_ERR_MULTI_ASSIGN_MULTI_SPLATS, + YP_ERR_NOT_EXPRESSION, + YP_ERR_NUMBER_LITERAL_UNDERSCORE, + YP_ERR_OPERATOR_MULTI_ASSIGN, + YP_ERR_PARAMETER_ASSOC_SPLAT_MULTI, + YP_ERR_PARAMETER_BLOCK_MULTI, + YP_ERR_PARAMETER_NAME_REPEAT, + YP_ERR_PARAMETER_NO_DEFAULT, + YP_ERR_PARAMETER_NO_DEFAULT_KW, + YP_ERR_PARAMETER_NUMBERED_RESERVED, + YP_ERR_PARAMETER_ORDER, + YP_ERR_PARAMETER_SPLAT_MULTI, + YP_ERR_PARAMETER_STAR, + YP_ERR_PARAMETER_WILD_LOOSE_COMMA, + YP_ERR_PATTERN_EXPRESSION_AFTER_BRACKET, + YP_ERR_PATTERN_EXPRESSION_AFTER_HROCKET, + YP_ERR_PATTERN_EXPRESSION_AFTER_COMMA, + YP_ERR_PATTERN_EXPRESSION_AFTER_IN, + YP_ERR_PATTERN_EXPRESSION_AFTER_KEY, + YP_ERR_PATTERN_EXPRESSION_AFTER_PAREN, + YP_ERR_PATTERN_EXPRESSION_AFTER_PIN, + YP_ERR_PATTERN_EXPRESSION_AFTER_PIPE, + YP_ERR_PATTERN_EXPRESSION_AFTER_RANGE, + YP_ERR_PATTERN_HASH_KEY, + YP_ERR_PATTERN_HASH_KEY_LABEL, + YP_ERR_PATTERN_IDENT_AFTER_HROCKET, + YP_ERR_PATTERN_LABEL_AFTER_COMMA, + YP_ERR_PATTERN_REST, + YP_ERR_PATTERN_TERM_BRACE, + YP_ERR_PATTERN_TERM_BRACKET, + YP_ERR_PATTERN_TERM_PAREN, + YP_ERR_PIPEPIPEEQ_MULTI_ASSIGN, + YP_ERR_REGEXP_TERM, + YP_ERR_RESCUE_EXPRESSION, + YP_ERR_RESCUE_MODIFIER_VALUE, + YP_ERR_RESCUE_TERM, + YP_ERR_RESCUE_VARIABLE, + YP_ERR_RETURN_INVALID, + YP_ERR_STRING_CONCATENATION, + YP_ERR_STRING_INTERPOLATED_TERM, + YP_ERR_STRING_LITERAL_TERM, + YP_ERR_SYMBOL_INVALID, + YP_ERR_SYMBOL_TERM_DYNAMIC, + YP_ERR_SYMBOL_TERM_INTERPOLATED, + YP_ERR_TERNARY_COLON, + YP_ERR_TERNARY_EXPRESSION_FALSE, + YP_ERR_TERNARY_EXPRESSION_TRUE, + YP_ERR_UNDEF_ARGUMENT, + YP_ERR_UNARY_RECEIVER_BANG, + YP_ERR_UNARY_RECEIVER_MINUS, + YP_ERR_UNARY_RECEIVER_PLUS, + YP_ERR_UNARY_RECEIVER_TILDE, + YP_ERR_UNTIL_TERM, + YP_ERR_WHILE_TERM, + YP_ERR_WRITE_TARGET_READONLY, + YP_ERR_WRITE_TARGET_UNEXPECTED, + YP_ERR_XSTRING_TERM, + YP_WARN_AMBIGUOUS_FIRST_ARGUMENT_MINUS, + YP_WARN_AMBIGUOUS_FIRST_ARGUMENT_PLUS, + YP_WARN_AMBIGUOUS_PREFIX_STAR, + YP_WARN_AMBIGUOUS_SLASH, + /* This must be the last member. */ + YP_DIAGNOSTIC_ID_LEN, +} yp_diagnostic_id_t; + // Append a diagnostic to the given list of diagnostics. -bool yp_diagnostic_list_append(yp_list_t *list, const uint8_t *start, const uint8_t *end, const char *message); +bool yp_diagnostic_list_append(yp_list_t *list, const uint8_t *start, const uint8_t *end, yp_diagnostic_id_t diag_id); // Deallocate the internal state of the given diagnostic list. void yp_diagnostic_list_free(yp_list_t *list); diff --git a/yarp/unescape.c b/yarp/unescape.c index 830c5996ae380d..9da52eaea9c6e9 100644 --- a/yarp/unescape.c +++ b/yarp/unescape.c @@ -94,7 +94,7 @@ static inline size_t unescape_hexadecimal(const uint8_t *backslash, uint8_t *value, const uint8_t *end, yp_list_t *error_list) { *value = 0; if (backslash + 2 >= end || !yp_char_is_hexadecimal_digit(backslash[2])) { - if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 2, "Invalid hex escape."); + if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 2, YP_ERR_ESCAPE_INVALID_HEXADECIMAL); return 2; } *value = unescape_hexadecimal_digit(backslash[2]); @@ -157,7 +157,7 @@ unescape_unicode_write(uint8_t *dest, uint32_t value, const uint8_t *start, cons // If we get here, then the value is too big. This is an error, but we don't // want to just crash, so instead we'll add an error to the error list and put // in a replacement character instead. - if (error_list) yp_diagnostic_list_append(error_list, start, end, "Invalid Unicode escape sequence."); + if (error_list) yp_diagnostic_list_append(error_list, start, end, YP_ERR_ESCAPE_INVALID_UNICODE); dest[0] = 0xEF; dest[1] = 0xBF; dest[2] = 0xBD; @@ -235,7 +235,7 @@ unescape( // \unnnn Unicode character, where nnnn is exactly 4 hexadecimal digits ([0-9a-fA-F]) case 'u': { if ((flags & YP_UNESCAPE_FLAG_CONTROL) | (flags & YP_UNESCAPE_FLAG_META)) { - if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 2, "Unicode escape sequence cannot be used with control or meta flags."); + if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 2, YP_ERR_ESCAPE_INVALID_UNICODE_CM_FLAGS); return backslash + 2; } @@ -252,11 +252,11 @@ unescape( // \u{nnnn} character literal allows only 1-6 hexadecimal digits if (hexadecimal_length > 6) { - if (error_list) yp_diagnostic_list_append(error_list, unicode_cursor, unicode_cursor + hexadecimal_length, "invalid Unicode escape."); + if (error_list) yp_diagnostic_list_append(error_list, unicode_cursor, unicode_cursor + hexadecimal_length, YP_ERR_ESCAPE_INVALID_UNICODE_LONG); } // there are not hexadecimal characters else if (hexadecimal_length == 0) { - if (error_list) yp_diagnostic_list_append(error_list, unicode_cursor, unicode_cursor + hexadecimal_length, "unterminated Unicode escape"); + if (error_list) yp_diagnostic_list_append(error_list, unicode_cursor, unicode_cursor + hexadecimal_length, YP_ERR_ESCAPE_INVALID_UNICODE); return unicode_cursor; } @@ -277,13 +277,13 @@ unescape( // ?\u{nnnn} character literal should contain only one codepoint and cannot be like ?\u{nnnn mmmm} if (flags & YP_UNESCAPE_FLAG_EXPECT_SINGLE && codepoints_count > 1) { - if (error_list) yp_diagnostic_list_append(error_list, extra_codepoints_start, unicode_cursor - 1, "Multiple codepoints at single character literal"); + if (error_list) yp_diagnostic_list_append(error_list, extra_codepoints_start, unicode_cursor - 1, YP_ERR_ESCAPE_INVALID_UNICODE_LITERAL); } if (unicode_cursor < end && *unicode_cursor == '}') { unicode_cursor++; } else { - if (error_list) yp_diagnostic_list_append(error_list, backslash, unicode_cursor, "invalid Unicode escape."); + if (error_list) yp_diagnostic_list_append(error_list, backslash, unicode_cursor, YP_ERR_ESCAPE_INVALID_UNICODE_TERM); } return unicode_cursor; @@ -298,7 +298,7 @@ unescape( return backslash + 6; } - if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 2, "Invalid Unicode escape sequence"); + if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 2, YP_ERR_ESCAPE_INVALID_UNICODE); return backslash + 2; } // \c\M-x meta control character, where x is an ASCII printable character @@ -306,12 +306,12 @@ unescape( // \cx control character, where x is an ASCII printable character case 'c': if (backslash + 2 >= end) { - if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 1, "Invalid control escape sequence"); + if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 1, YP_ERR_ESCAPE_INVALID_CONTROL); return end; } if (flags & YP_UNESCAPE_FLAG_CONTROL) { - if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 1, "Control escape sequence cannot be doubled."); + if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 1, YP_ERR_ESCAPE_INVALID_CONTROL_REPEAT); return backslash + 2; } @@ -325,7 +325,7 @@ unescape( return backslash + 3; default: { if (!char_is_ascii_printable(backslash[2])) { - if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 1, "Invalid control escape sequence"); + if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 1, YP_ERR_ESCAPE_INVALID_CONTROL); return backslash + 2; } @@ -339,17 +339,17 @@ unescape( // \C-? delete, ASCII 7Fh (DEL) case 'C': if (backslash + 3 >= end) { - if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 1, "Invalid control escape sequence"); + if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 1, YP_ERR_ESCAPE_INVALID_CONTROL); return end; } if (flags & YP_UNESCAPE_FLAG_CONTROL) { - if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 1, "Control escape sequence cannot be doubled."); + if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 1, YP_ERR_ESCAPE_INVALID_CONTROL_REPEAT); return backslash + 2; } if (backslash[2] != '-') { - if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 1, "Invalid control escape sequence"); + if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 1, YP_ERR_ESCAPE_INVALID_CONTROL); return backslash + 2; } @@ -363,7 +363,7 @@ unescape( return backslash + 4; default: if (!char_is_ascii_printable(backslash[3])) { - if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 2, "Invalid control escape sequence"); + if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 2, YP_ERR_ESCAPE_INVALID_CONTROL); return backslash + 2; } @@ -377,17 +377,17 @@ unescape( // \M-x meta character, where x is an ASCII printable character case 'M': { if (backslash + 3 >= end) { - if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 1, "Invalid control escape sequence"); + if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 1, YP_ERR_ESCAPE_INVALID_META); return end; } if (flags & YP_UNESCAPE_FLAG_META) { - if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 2, "Meta escape sequence cannot be doubled."); + if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 2, YP_ERR_ESCAPE_INVALID_META_REPEAT); return backslash + 2; } if (backslash[2] != '-') { - if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 2, "Invalid meta escape sequence"); + if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 2, YP_ERR_ESCAPE_INVALID_META); return backslash + 2; } @@ -402,7 +402,7 @@ unescape( return backslash + 4; } - if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 2, "Invalid meta escape sequence"); + if (error_list) yp_diagnostic_list_append(error_list, backslash, backslash + 2, YP_ERR_ESCAPE_INVALID_META); return backslash + 3; } // \n @@ -474,7 +474,7 @@ yp_unescape_manipulate_string_or_char_literal(yp_parser_t *parser, yp_string_t * // within the string. uint8_t *allocated = malloc(string->length); if (allocated == NULL) { - yp_diagnostic_list_append(&parser->error_list, string->source, string->source + string->length, "Failed to allocate memory for unescaping."); + yp_diagnostic_list_append(&parser->error_list, string->source, string->source + string->length, YP_ERR_MALLOC_FAILED); return; } diff --git a/yarp/yarp.c b/yarp/yarp.c index cb2bf18597ce67..07ee4d8a8f163f 100644 --- a/yarp/yarp.c +++ b/yarp/yarp.c @@ -549,7 +549,7 @@ yp_arguments_validate(yp_parser_t *parser, yp_arguments_t *arguments) { &parser->error_list, arguments->block->base.location.start, arguments->block->base.location.end, - "both block arg and actual block given" + YP_ERR_ARGUMENT_BLOCK_MULTI ); } } @@ -643,14 +643,14 @@ parse_decimal_number(yp_parser_t *parser, const uint8_t *start, const uint8_t *e unsigned long value = strtoul(digits, &endptr, 10); if ((digits == endptr) || (*endptr != '\0') || (errno == ERANGE)) { - yp_diagnostic_list_append(&parser->error_list, start, end, "invalid decimal number"); + yp_diagnostic_list_append(&parser->error_list, start, end, YP_ERR_INVALID_NUMBER_DECIMAL); value = UINT32_MAX; } free(digits); if (value > UINT32_MAX) { - yp_diagnostic_list_append(&parser->error_list, start, end, "invalid decimal number"); + yp_diagnostic_list_append(&parser->error_list, start, end, YP_ERR_INVALID_NUMBER_DECIMAL); value = UINT32_MAX; } @@ -4637,7 +4637,7 @@ yp_parser_parameter_name_check(yp_parser_t *parser, yp_token_t *name) { yp_constant_id_t constant_id = yp_parser_constant_id_token(parser, name); if (yp_constant_id_list_includes(&parser->current_scope->locals, constant_id)) { - yp_diagnostic_list_append(&parser->error_list, name->start, name->end, "Duplicated parameter name."); + yp_diagnostic_list_append(&parser->error_list, name->start, name->end, YP_ERR_PARAMETER_NAME_REPEAT); } } @@ -4980,7 +4980,7 @@ parser_lex_encoding_comment(yp_parser_t *parser) { // didn't understand the encoding that the user was trying to use. In this // case we'll keep using the default encoding but add an error to the // parser to indicate an unsuccessful parse. - yp_diagnostic_list_append(&parser->error_list, encoding_start, encoding_end, "Could not understand the encoding specified in the magic comment."); + yp_diagnostic_list_append(&parser->error_list, encoding_start, encoding_end, YP_ERR_INVALID_ENCODING_MAGIC_COMMENT); } /******************************************************************************/ @@ -5140,7 +5140,7 @@ lex_optional_float_suffix(yp_parser_t *parser) { parser->current.end += yp_strspn_decimal_number(parser->current.end, parser->end - parser->current.end); type = YP_TOKEN_FLOAT; } else { - yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, "Missing exponent."); + yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_INVALID_FLOAT_EXPONENT); type = YP_TOKEN_FLOAT; } } @@ -5161,7 +5161,7 @@ lex_numeric_prefix(yp_parser_t *parser) { if (yp_char_is_decimal_digit(peek(parser))) { parser->current.end += yp_strspn_decimal_number(parser->current.end, parser->end - parser->current.end); } else { - yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, "Invalid decimal number."); + yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_INVALID_NUMBER_DECIMAL); } break; @@ -5173,7 +5173,7 @@ lex_numeric_prefix(yp_parser_t *parser) { if (yp_char_is_binary_digit(peek(parser))) { parser->current.end += yp_strspn_binary_number(parser->current.end, parser->end - parser->current.end); } else { - yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, "Invalid binary number."); + yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_INVALID_NUMBER_BINARY); } break; @@ -5185,7 +5185,7 @@ lex_numeric_prefix(yp_parser_t *parser) { if (yp_char_is_octal_digit(peek(parser))) { parser->current.end += yp_strspn_octal_number(parser->current.end, parser->end - parser->current.end); } else { - yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, "Invalid octal number."); + yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_INVALID_NUMBER_OCTAL); } break; @@ -5210,7 +5210,7 @@ lex_numeric_prefix(yp_parser_t *parser) { if (yp_char_is_hexadecimal_digit(peek(parser))) { parser->current.end += yp_strspn_hexadecimal_number(parser->current.end, parser->end - parser->current.end); } else { - yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, "Invalid hexadecimal number."); + yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_INVALID_NUMBER_HEXADECIMAL); } break; @@ -5240,7 +5240,7 @@ lex_numeric_prefix(yp_parser_t *parser) { // If the last character that we consumed was an underscore, then this is // actually an invalid integer value, and we should return an invalid token. if (peek_offset(parser, -1) == '_') { - yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, "Number literal cannot end with a `_`."); + yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_NUMBER_LITERAL_UNDERSCORE); } return type; @@ -5292,7 +5292,7 @@ lex_numeric(yp_parser_t *parser) { static yp_token_type_t lex_global_variable(yp_parser_t *parser) { if (parser->current.end >= parser->end) { - yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, "Invalid global variable."); + yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_INVALID_VARIABLE_GLOBAL); return YP_TOKEN_GLOBAL_VARIABLE; } @@ -5333,7 +5333,7 @@ lex_global_variable(yp_parser_t *parser) { } while (parser->current.end < parser->end && (width = char_is_identifier(parser, parser->current.end)) > 0); // $0 isn't allowed to be followed by anything. - yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, "Invalid global variable."); + yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_INVALID_VARIABLE_GLOBAL); } return YP_TOKEN_GLOBAL_VARIABLE; @@ -5364,7 +5364,7 @@ lex_global_variable(yp_parser_t *parser) { } else { // If we get here, then we have a $ followed by something that isn't // recognized as a global variable. - yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, "Invalid global variable."); + yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_INVALID_VARIABLE_GLOBAL); } return YP_TOKEN_GLOBAL_VARIABLE; @@ -5704,7 +5704,7 @@ lex_question_mark(yp_parser_t *parser) { } if (parser->current.end >= parser->end) { - yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, "Incomplete character syntax."); + yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_INCOMPLETE_QUESTION_MARK); return YP_TOKEN_CHARACTER_LITERAL; } @@ -5755,9 +5755,9 @@ lex_at_variable(yp_parser_t *parser) { parser->current.end += width; } } else if (type == YP_TOKEN_CLASS_VARIABLE) { - yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, "Incomplete class variable."); + yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_INCOMPLETE_VARIABLE_CLASS); } else { - yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, "Incomplete instance variable."); + yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_INCOMPLETE_VARIABLE_INSTANCE); } // If we're lexing an embedded variable, then we need to pop back into the @@ -5856,7 +5856,7 @@ lex_embdoc(yp_parser_t *parser) { parser_lex_callback(parser); } - yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, "Unterminated embdoc"); + yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_EMBDOC_TERM); comment->end = parser->current.end; yp_list_append(&parser->comment_list, (yp_list_node_t *) comment); @@ -6286,7 +6286,7 @@ parser_lex(yp_parser_t *parser) { yp_token_type_t type = YP_TOKEN_STAR; if (lex_state_spcarg_p(parser, space_seen)) { - yp_diagnostic_list_append(&parser->warning_list, parser->current.start, parser->current.end, "`*' interpreted as argument prefix"); + yp_diagnostic_list_append(&parser->warning_list, parser->current.start, parser->current.end, YP_WARN_AMBIGUOUS_PREFIX_STAR); type = YP_TOKEN_USTAR; } else if (lex_state_beg_p(parser)) { type = YP_TOKEN_USTAR; @@ -6430,7 +6430,7 @@ parser_lex(yp_parser_t *parser) { // this is not a valid heredoc declaration. In this case we // will add an error, but we will still return a heredoc // start. - yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, "Unterminated heredoc."); + yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_EMBDOC_TERM); body_start = parser->end; } else { // Otherwise, we want to indicate that the body of the @@ -6627,7 +6627,7 @@ parser_lex(yp_parser_t *parser) { &parser->warning_list, parser->current.start, parser->current.end, - "ambiguous first argument; put parentheses or a space even after `+` operator" + YP_WARN_AMBIGUOUS_FIRST_ARGUMENT_PLUS ); } @@ -6676,7 +6676,7 @@ parser_lex(yp_parser_t *parser) { &parser->warning_list, parser->current.start, parser->current.end, - "ambiguous first argument; put parentheses or a space even after `-` operator" + YP_WARN_AMBIGUOUS_FIRST_ARGUMENT_MINUS ); } @@ -6774,7 +6774,7 @@ parser_lex(yp_parser_t *parser) { } if (lex_state_spcarg_p(parser, space_seen)) { - yp_diagnostic_list_append(&parser->warning_list, parser->current.start, parser->current.end, "ambiguity between regexp and two divisions: wrap regexp in parentheses or add a space after `/' operator"); + yp_diagnostic_list_append(&parser->warning_list, parser->current.start, parser->current.end, YP_WARN_AMBIGUOUS_SLASH); lex_mode_push_regexp(parser, '\0', '/'); LEX(YP_TOKEN_REGEXP_BEGIN); } @@ -6813,7 +6813,7 @@ parser_lex(yp_parser_t *parser) { // going to say it's the percent operator because we don't want to move into the // string lex mode unnecessarily. if ((lex_state_beg_p(parser) || lex_state_arg_p(parser)) && (parser->current.end >= parser->end)) { - yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, "Unexpected end of input"); + yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_INVALID_PERCENT); LEX(YP_TOKEN_PERCENT); } @@ -6938,7 +6938,7 @@ parser_lex(yp_parser_t *parser) { // unparseable. In this case we'll just drop it from the parser // and skip past it and hope that the next token is something // that we can parse. - yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, "Invalid %% token"); + yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_INVALID_PERCENT); goto lex_next_token; } } @@ -6974,7 +6974,7 @@ parser_lex(yp_parser_t *parser) { // token as we've exhausted all of the other options. We'll skip past // it and return the next token. if (!width) { - yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, "Invalid token."); + yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_INVALID_TOKEN); goto lex_next_token; } @@ -7920,17 +7920,17 @@ accept_any(yp_parser_t *parser, size_t count, ...) { // valid) and create an artificial token instead. This allows us to recover from // the fact that the token isn't present and continue parsing. static void -expect(yp_parser_t *parser, yp_token_type_t type, const char *message) { +expect(yp_parser_t *parser, yp_token_type_t type, yp_diagnostic_id_t diag_id) { if (accept(parser, type)) return; - yp_diagnostic_list_append(&parser->error_list, parser->previous.end, parser->previous.end, message); + yp_diagnostic_list_append(&parser->error_list, parser->previous.end, parser->previous.end, diag_id); parser->previous = (yp_token_t) { .type = YP_TOKEN_MISSING, .start = parser->previous.end, .end = parser->previous.end }; } static void -expect_any(yp_parser_t *parser, const char*message, size_t count, ...) { +expect_any(yp_parser_t *parser, yp_diagnostic_id_t diag_id, size_t count, ...) { va_list types; va_start(types, count); @@ -7943,13 +7943,13 @@ expect_any(yp_parser_t *parser, const char*message, size_t count, ...) { va_end(types); - yp_diagnostic_list_append(&parser->error_list, parser->previous.end, parser->previous.end, message); + yp_diagnostic_list_append(&parser->error_list, parser->previous.end, parser->previous.end, diag_id); parser->previous = (yp_token_t) { .type = YP_TOKEN_MISSING, .start = parser->previous.end, .end = parser->previous.end }; } static yp_node_t * -parse_expression(yp_parser_t *parser, yp_binding_power_t binding_power, const char *message); +parse_expression(yp_parser_t *parser, yp_binding_power_t binding_power, yp_diagnostic_id_t diag_id); // This function controls whether or not we will attempt to parse an expression // beginning at the subsequent token. It is used when we are in a context where @@ -8026,14 +8026,14 @@ token_begins_expression_p(yp_token_type_t type) { // Parse an expression with the given binding power that may be optionally // prefixed by the * operator. static yp_node_t * -parse_starred_expression(yp_parser_t *parser, yp_binding_power_t binding_power, const char *message) { +parse_starred_expression(yp_parser_t *parser, yp_binding_power_t binding_power, yp_diagnostic_id_t diag_id) { if (accept(parser, YP_TOKEN_USTAR)) { yp_token_t operator = parser->previous; - yp_node_t *expression = parse_expression(parser, binding_power, "Expected expression after `*'."); + yp_node_t *expression = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_STAR); return (yp_node_t *) yp_splat_node_create(parser, &operator, expression); } - return parse_expression(parser, binding_power, message); + return parse_expression(parser, binding_power, diag_id); } // Convert the given node into a valid target node. @@ -8059,7 +8059,7 @@ parse_target(yp_parser_t *parser, yp_node_t *target) { /* fallthrough */ case YP_NUMBERED_REFERENCE_READ_NODE: assert(sizeof(yp_global_variable_target_node_t) == sizeof(yp_numbered_reference_read_node_t)); - yp_diagnostic_list_append(&parser->error_list, target->location.start, target->location.end, "Can't set variable"); + yp_diagnostic_list_append(&parser->error_list, target->location.start, target->location.end, YP_ERR_WRITE_TARGET_READONLY); /* fallthrough */ case YP_GLOBAL_VARIABLE_READ_NODE: assert(sizeof(yp_global_variable_target_node_t) == sizeof(yp_global_variable_read_node_t)); @@ -8122,7 +8122,7 @@ parse_target(yp_parser_t *parser, yp_node_t *target) { target->type = YP_LOCAL_VARIABLE_TARGET_NODE; if (token_is_numbered_parameter(message.start, message.end)) { - yp_diagnostic_list_append(&parser->error_list, message.start, message.end, "reserved for numbered parameter"); + yp_diagnostic_list_append(&parser->error_list, message.start, message.end, YP_ERR_PARAMETER_NUMBERED_RESERVED); } return target; @@ -8166,7 +8166,7 @@ parse_target(yp_parser_t *parser, yp_node_t *target) { // In this case we have a node that we don't know how to convert // into a target. We need to treat it as an error. For now, we'll // mark it as an error and just skip right past it. - yp_diagnostic_list_append(&parser->error_list, target->location.start, target->location.end, "Unexpected write target."); + yp_diagnostic_list_append(&parser->error_list, target->location.start, target->location.end, YP_ERR_WRITE_TARGET_UNEXPECTED); return target; } } @@ -8191,7 +8191,7 @@ parse_write(yp_parser_t *parser, yp_node_t *target, yp_token_t *operator, yp_nod } case YP_BACK_REFERENCE_READ_NODE: case YP_NUMBERED_REFERENCE_READ_NODE: - yp_diagnostic_list_append(&parser->error_list, target->location.start, target->location.end, "Can't set variable"); + yp_diagnostic_list_append(&parser->error_list, target->location.start, target->location.end, YP_ERR_WRITE_TARGET_READONLY); /* fallthrough */ case YP_GLOBAL_VARIABLE_READ_NODE: { yp_global_variable_write_node_t *node = yp_global_variable_write_node_create(parser, target, operator, value); @@ -8263,7 +8263,7 @@ parse_write(yp_parser_t *parser, yp_node_t *target, yp_token_t *operator, yp_nod target = (yp_node_t *) yp_local_variable_write_node_create(parser, constant_id, 0, value, &message, operator); if (token_is_numbered_parameter(message.start, message.end)) { - yp_diagnostic_list_append(&parser->error_list, message.start, message.end, "reserved for numbered parameter"); + yp_diagnostic_list_append(&parser->error_list, message.start, message.end, YP_ERR_PARAMETER_NUMBERED_RESERVED); } return target; @@ -8336,7 +8336,7 @@ parse_write(yp_parser_t *parser, yp_node_t *target, yp_token_t *operator, yp_nod // In this case we have a node that we don't know how to convert into a // target. We need to treat it as an error. For now, we'll mark it as an // error and just skip right past it. - yp_diagnostic_list_append(&parser->error_list, operator->start, operator->end, "Unexpected `='."); + yp_diagnostic_list_append(&parser->error_list, operator->start, operator->end, YP_ERR_EXPECT_EXPRESSION_AFTER_EQUAL); return target; } } @@ -8381,14 +8381,14 @@ parse_targets(yp_parser_t *parser, yp_node_t *first_target, yp_binding_power_t b // others yet. if (has_splat) { - yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, "Multiple splats in multi-assignment."); + yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, YP_ERR_MULTI_ASSIGN_MULTI_SPLATS); } yp_token_t star_operator = parser->previous; yp_node_t *name = NULL; if (token_begins_expression_p(parser->current.type)) { - name = parse_expression(parser, binding_power, "Expected an expression after '*'."); + name = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_STAR); name = parse_target(parser, name); } @@ -8401,10 +8401,10 @@ parse_targets(yp_parser_t *parser, yp_node_t *first_target, yp_binding_power_t b // the node when it returns. yp_token_t lparen = parser->previous; - yp_node_t *first_child_target = parse_expression(parser, YP_BINDING_POWER_STATEMENT, "Expected an expression after '('."); + yp_node_t *first_child_target = parse_expression(parser, YP_BINDING_POWER_STATEMENT, YP_ERR_EXPECT_EXPRESSION_AFTER_LPAREN); yp_node_t *child_target = parse_targets(parser, first_child_target, YP_BINDING_POWER_STATEMENT); - expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, "Expected an ')' after multi-assignment."); + expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, YP_ERR_EXPECT_RPAREN_AFTER_MULTI); yp_token_t rparen = parser->previous; if (YP_NODE_TYPE_P(child_target, YP_MULTI_WRITE_NODE) && first_target == NULL && result->targets.size == 0) { @@ -8447,7 +8447,7 @@ parse_targets(yp_parser_t *parser, yp_node_t *first_target, yp_binding_power_t b // If we get here, then we weren't able to parse anything at all, so // we need to return a missing node. yp_node_destroy(parser, (yp_node_t *) result); - yp_diagnostic_list_append(&parser->error_list, operator.start, operator.end, "Expected index after for."); + yp_diagnostic_list_append(&parser->error_list, operator.start, operator.end, YP_ERR_FOR_INDEX); return (yp_node_t *) yp_missing_node_create(parser, operator.start, operator.end); } @@ -8459,7 +8459,7 @@ parse_targets(yp_parser_t *parser, yp_node_t *first_target, yp_binding_power_t b return (yp_node_t *) result; } - yp_node_t *target = parse_expression(parser, binding_power, "Expected another expression after ','."); + yp_node_t *target = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_COMMA); target = parse_target(parser, target); yp_multi_write_node_targets_append(result, target); @@ -8487,7 +8487,7 @@ parse_statements(yp_parser_t *parser, yp_context_t context) { context_push(parser, context); while (true) { - yp_node_t *node = parse_expression(parser, YP_BINDING_POWER_STATEMENT, "Expected to be able to parse an expression."); + yp_node_t *node = parse_expression(parser, YP_BINDING_POWER_STATEMENT, YP_ERR_CANNOT_PARSE_EXPRESSION); yp_statements_node_body_append(statements, node); // If we're recovering from a syntax error, then we need to stop parsing the @@ -8532,7 +8532,7 @@ parse_statements(yp_parser_t *parser, yp_context_t context) { while (accept_any(parser, 2, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON)); if (context_terminator(context, &parser->current)) break; } else { - expect(parser, YP_TOKEN_NEWLINE, "Expected a newline or semicolon after statement."); + expect(parser, YP_TOKEN_NEWLINE, YP_ERR_EXPECT_EOL_AFTER_STATEMENT); } } @@ -8555,9 +8555,9 @@ parse_assocs(yp_parser_t *parser, yp_node_t *node) { yp_node_t *value = NULL; if (token_begins_expression_p(parser->current.type)) { - value = parse_expression(parser, YP_BINDING_POWER_DEFINED, "Expected an expression after ** in hash."); + value = parse_expression(parser, YP_BINDING_POWER_DEFINED, YP_ERR_EXPECT_EXPRESSION_AFTER_SPLAT_HASH); } else if (yp_parser_local_depth(parser, &operator) == -1) { - yp_diagnostic_list_append(&parser->error_list, operator.start, operator.end, "Expected an expression after ** in hash."); + yp_diagnostic_list_append(&parser->error_list, operator.start, operator.end, YP_ERR_EXPECT_EXPRESSION_AFTER_SPLAT_HASH); } element = (yp_node_t *) yp_assoc_splat_node_create(parser, value, &operator); @@ -8571,24 +8571,24 @@ parse_assocs(yp_parser_t *parser, yp_node_t *node) { yp_node_t *value = NULL; if (token_begins_expression_p(parser->current.type)) { - value = parse_expression(parser, YP_BINDING_POWER_DEFINED, "Expected an expression after the label in hash."); + value = parse_expression(parser, YP_BINDING_POWER_DEFINED, YP_ERR_HASH_EXPRESSION_AFTER_LABEL); } element = (yp_node_t *) yp_assoc_node_create(parser, key, &operator, value); break; } default: { - yp_node_t *key = parse_expression(parser, YP_BINDING_POWER_DEFINED, "Expected a key in the hash literal."); + yp_node_t *key = parse_expression(parser, YP_BINDING_POWER_DEFINED, YP_ERR_HASH_KEY); yp_token_t operator; if (yp_symbol_node_label_p(key)) { operator = not_provided(parser); } else { - expect(parser, YP_TOKEN_EQUAL_GREATER, "Expected a => between the key and the value in the hash."); + expect(parser, YP_TOKEN_EQUAL_GREATER, YP_ERR_HASH_ROCKET); operator = parser->previous; } - yp_node_t *value = parse_expression(parser, YP_BINDING_POWER_DEFINED, "Expected a value in the hash literal."); + yp_node_t *value = parse_expression(parser, YP_BINDING_POWER_DEFINED, YP_ERR_HASH_VALUE); element = (yp_node_t *) yp_assoc_node_create(parser, key, &operator, value); break; } @@ -8636,7 +8636,7 @@ parse_arguments(yp_parser_t *parser, yp_arguments_t *arguments, bool accepts_for while (!match_type_p(parser, YP_TOKEN_EOF)) { if (parsed_block_argument) { - yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, "Unexpected argument after block argument."); + yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_ARGUMENT_AFTER_BLOCK); } yp_node_t *argument = NULL; @@ -8645,7 +8645,7 @@ parse_arguments(yp_parser_t *parser, yp_arguments_t *arguments, bool accepts_for case YP_TOKEN_USTAR_STAR: case YP_TOKEN_LABEL: { if (parsed_bare_hash) { - yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, "Unexpected bare hash."); + yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_ARGUMENT_BARE_HASH); } yp_keyword_hash_node_t *hash = yp_keyword_hash_node_create(parser); @@ -8664,9 +8664,9 @@ parse_arguments(yp_parser_t *parser, yp_arguments_t *arguments, bool accepts_for yp_node_t *expression = NULL; if (token_begins_expression_p(parser->current.type)) { - expression = parse_expression(parser, YP_BINDING_POWER_DEFINED, "Expected to be able to parse an argument."); + expression = parse_expression(parser, YP_BINDING_POWER_DEFINED, YP_ERR_EXPECT_ARGUMENT); } else if (yp_parser_local_depth(parser, &operator) == -1) { - yp_diagnostic_list_append(&parser->error_list, operator.start, operator.end, "unexpected & when parent method is not forwarding."); + yp_diagnostic_list_append(&parser->error_list, operator.start, operator.end, YP_ERR_ARGUMENT_NO_FORWARDING_AMP); } argument = (yp_node_t *)yp_block_argument_node_create(parser, &operator, expression); @@ -8680,15 +8680,15 @@ parse_arguments(yp_parser_t *parser, yp_arguments_t *arguments, bool accepts_for if (match_any_type_p(parser, 2, YP_TOKEN_PARENTHESIS_RIGHT, YP_TOKEN_COMMA)) { if (yp_parser_local_depth(parser, &parser->previous) == -1) { - yp_diagnostic_list_append(&parser->error_list, operator.start, operator.end, "unexpected * when parent method is not forwarding."); + yp_diagnostic_list_append(&parser->error_list, operator.start, operator.end, YP_ERR_ARGUMENT_NO_FORWARDING_STAR); } argument = (yp_node_t *) yp_splat_node_create(parser, &operator, NULL); } else { - yp_node_t *expression = parse_expression(parser, YP_BINDING_POWER_DEFINED, "Expected an expression after '*' in argument."); + yp_node_t *expression = parse_expression(parser, YP_BINDING_POWER_DEFINED, YP_ERR_EXPECT_EXPRESSION_AFTER_SPLAT); if (parsed_bare_hash) { - yp_diagnostic_list_append(&parser->error_list, operator.start, expression->location.end, "Unexpected splat argument after double splat."); + yp_diagnostic_list_append(&parser->error_list, operator.start, expression->location.end, YP_ERR_ARGUMENT_SPLAT_AFTER_ASSOC_SPLAT); } argument = (yp_node_t *) yp_splat_node_create(parser, &operator, expression); @@ -8704,11 +8704,11 @@ parse_arguments(yp_parser_t *parser, yp_arguments_t *arguments, bool accepts_for // If the token begins an expression then this ... was not actually // argument forwarding but was instead a range. yp_token_t operator = parser->previous; - yp_node_t *right = parse_expression(parser, YP_BINDING_POWER_RANGE, "Expected a value after the operator."); + yp_node_t *right = parse_expression(parser, YP_BINDING_POWER_RANGE, YP_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR); argument = (yp_node_t *) yp_range_node_create(parser, NULL, &operator, right); } else { if (yp_parser_local_depth(parser, &parser->previous) == -1) { - yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, "unexpected ... when parent method is not forwarding."); + yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, YP_ERR_ARGUMENT_NO_FORWARDING_ELLIPSES); } argument = (yp_node_t *)yp_forwarding_arguments_node_create(parser, &parser->previous); @@ -8719,12 +8719,12 @@ parse_arguments(yp_parser_t *parser, yp_arguments_t *arguments, bool accepts_for /* fallthrough */ default: { if (argument == NULL) { - argument = parse_expression(parser, YP_BINDING_POWER_DEFINED, "Expected to be able to parse an argument."); + argument = parse_expression(parser, YP_BINDING_POWER_DEFINED, YP_ERR_EXPECT_ARGUMENT); } if (yp_symbol_node_label_p(argument) || accept(parser, YP_TOKEN_EQUAL_GREATER)) { if (parsed_bare_hash) { - yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, "Unexpected bare hash argument."); + yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, YP_ERR_ARGUMENT_BARE_HASH); } yp_token_t operator; @@ -8737,7 +8737,7 @@ parse_arguments(yp_parser_t *parser, yp_arguments_t *arguments, bool accepts_for yp_keyword_hash_node_t *bare_hash = yp_keyword_hash_node_create(parser); // Finish parsing the one we are part way through - yp_node_t *value = parse_expression(parser, YP_BINDING_POWER_DEFINED, "Expected a value in the hash literal."); + yp_node_t *value = parse_expression(parser, YP_BINDING_POWER_DEFINED, YP_ERR_HASH_VALUE); argument = (yp_node_t *) yp_assoc_node_create(parser, argument, &operator, value); yp_keyword_hash_node_elements_append(bare_hash, argument); @@ -8793,7 +8793,7 @@ parse_arguments(yp_parser_t *parser, yp_arguments_t *arguments, bool accepts_for // It can recurse infinitely down, and splats are allowed to group arguments. static yp_required_destructured_parameter_node_t * parse_required_destructured_parameter(yp_parser_t *parser) { - expect(parser, YP_TOKEN_PARENTHESIS_LEFT, "Expected '(' to start a required parameter."); + expect(parser, YP_TOKEN_PARENTHESIS_LEFT, YP_ERR_EXPECT_LPAREN_REQ_PARAMETER); yp_token_t opening = parser->previous; yp_required_destructured_parameter_node_t *node = yp_required_destructured_parameter_node_create(parser, &opening); @@ -8804,7 +8804,7 @@ parse_required_destructured_parameter(yp_parser_t *parser) { if (node->parameters.size > 0 && match_type_p(parser, YP_TOKEN_PARENTHESIS_RIGHT)) { if (parsed_splat) { - yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, "Unexpected splat after splat."); + yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, YP_ERR_ARGUMENT_SPLAT_AFTER_SPLAT); } param = (yp_node_t *) yp_splat_node_create(parser, &parser->previous, NULL); @@ -8816,7 +8816,7 @@ parse_required_destructured_parameter(yp_parser_t *parser) { param = (yp_node_t *) parse_required_destructured_parameter(parser); } else if (accept(parser, YP_TOKEN_USTAR)) { if (parsed_splat) { - yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, "Unexpected splat after splat."); + yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, YP_ERR_ARGUMENT_SPLAT_AFTER_SPLAT); } yp_token_t star = parser->previous; @@ -8831,7 +8831,7 @@ parse_required_destructured_parameter(yp_parser_t *parser) { param = (yp_node_t *) yp_splat_node_create(parser, &star, value); parsed_splat = true; } else { - expect(parser, YP_TOKEN_IDENTIFIER, "Expected an identifier for a required parameter."); + expect(parser, YP_TOKEN_IDENTIFIER, YP_ERR_EXPECT_IDENT_REQ_PARAMETER); yp_token_t name = parser->previous; param = (yp_node_t *) yp_required_parameter_node_create(parser, &name); @@ -8841,7 +8841,7 @@ parse_required_destructured_parameter(yp_parser_t *parser) { yp_required_destructured_parameter_node_append_parameter(node, param); } while (accept(parser, YP_TOKEN_COMMA)); - expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, "Expected ')' to end a required parameter."); + expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, YP_ERR_EXPECT_RPAREN_REQ_PARAMETER); yp_required_destructured_parameter_node_closing_set(node, &parser->previous); return node; @@ -8896,12 +8896,12 @@ update_parameter_state(yp_parser_t *parser, yp_token_t *token, yp_parameters_ord } if (token->type == YP_TOKEN_USTAR && *current == YP_PARAMETERS_ORDER_AFTER_OPTIONAL) { - yp_diagnostic_list_append(&parser->error_list, token->start, token->end, "Unexpected parameter *"); + yp_diagnostic_list_append(&parser->error_list, token->start, token->end, YP_ERR_PARAMETER_STAR); } if (*current == YP_PARAMETERS_ORDER_NOTHING_AFTER || state > *current) { // We know what transition we failed on, so we can provide a better error here. - yp_diagnostic_list_append(&parser->error_list, token->start, token->end, "Unexpected parameter order"); + yp_diagnostic_list_append(&parser->error_list, token->start, token->end, YP_ERR_PARAMETER_ORDER); } else if (state < *current) { *current = state; } @@ -8956,7 +8956,7 @@ parse_parameters( if (params->block == NULL) { yp_parameters_node_block_set(params, param); } else { - yp_diagnostic_list_append(&parser->error_list, param->base.location.start, param->base.location.end, "Unexpected multiple block parameter"); + yp_diagnostic_list_append(&parser->error_list, param->base.location.start, param->base.location.end, YP_ERR_PARAMETER_BLOCK_MULTI); yp_parameters_node_posts_append(params, (yp_node_t *) param); } @@ -8964,7 +8964,7 @@ parse_parameters( } case YP_TOKEN_UDOT_DOT_DOT: { if (!allows_forwarding_parameter) { - yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, "Unexpected ..."); + yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_ARGUMENT_NO_FORWARDING_ELLIPSES); } if (order > YP_PARAMETERS_ORDER_NOTHING_AFTER) { update_parameter_state(parser, &parser->current, &order); @@ -8987,16 +8987,16 @@ parse_parameters( parser_lex(parser); switch (parser->previous.type) { case YP_TOKEN_CONSTANT: - yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, "Formal argument cannot be a constant"); + yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, YP_ERR_ARGUMENT_FORMAL_CONSTANT); break; case YP_TOKEN_INSTANCE_VARIABLE: - yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, "Formal argument cannot be an instance variable"); + yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, YP_ERR_ARGUMENT_FORMAL_IVAR); break; case YP_TOKEN_GLOBAL_VARIABLE: - yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, "Formal argument cannot be a global variable"); + yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, YP_ERR_ARGUMENT_FORMAL_GLOBAL); break; case YP_TOKEN_CLASS_VARIABLE: - yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, "Formal argument cannot be a class variable"); + yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, YP_ERR_ARGUMENT_FORMAL_CLASS); break; default: break; } @@ -9014,7 +9014,7 @@ parse_parameters( if (accept(parser, YP_TOKEN_EQUAL)) { yp_token_t operator = parser->previous; context_push(parser, YP_CONTEXT_DEFAULT_PARAMS); - yp_node_t *value = parse_expression(parser, binding_power, "Expected to find a default value for the parameter."); + yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_PARAMETER_NO_DEFAULT); yp_optional_parameter_node_t *param = yp_optional_parameter_node_create(parser, &name, &operator, value); yp_parameters_node_optionals_append(params, param); @@ -9072,7 +9072,7 @@ parse_parameters( yp_node_t *value = NULL; if (token_begins_expression_p(parser->current.type)) { context_push(parser, YP_CONTEXT_DEFAULT_PARAMS); - value = parse_expression(parser, binding_power, "Expected to find a default value for the keyword parameter."); + value = parse_expression(parser, binding_power, YP_ERR_PARAMETER_NO_DEFAULT_KW); context_pop(parser); } @@ -9113,7 +9113,7 @@ parse_parameters( if (params->rest == NULL) { yp_parameters_node_rest_set(params, param); } else { - yp_diagnostic_list_append(&parser->error_list, param->base.location.start, param->base.location.end, "Unexpected multiple splat parameters."); + yp_diagnostic_list_append(&parser->error_list, param->base.location.start, param->base.location.end, YP_ERR_PARAMETER_SPLAT_MULTI); yp_parameters_node_posts_append(params, (yp_node_t *) param); } @@ -9147,7 +9147,7 @@ parse_parameters( if (params->keyword_rest == NULL) { yp_parameters_node_keyword_rest_set(params, param); } else { - yp_diagnostic_list_append(&parser->error_list, param->location.start, param->location.end, "Unexpected multiple double splat parameters."); + yp_diagnostic_list_append(&parser->error_list, param->location.start, param->location.end, YP_ERR_PARAMETER_ASSOC_SPLAT_MULTI); yp_parameters_node_posts_append(params, param); } @@ -9165,11 +9165,11 @@ parse_parameters( if (params->rest == NULL) { yp_parameters_node_rest_set(params, param); } else { - yp_diagnostic_list_append(&parser->error_list, param->base.location.start, param->base.location.end, "Unexpected multiple splat parameters."); + yp_diagnostic_list_append(&parser->error_list, param->base.location.start, param->base.location.end, YP_ERR_PARAMETER_SPLAT_MULTI); yp_parameters_node_posts_append(params, (yp_node_t *) param); } } else { - yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, "Unexpected ','."); + yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, YP_ERR_PARAMETER_WILD_LOOSE_COMMA); } } @@ -9210,7 +9210,7 @@ parse_rescues(yp_parser_t *parser, yp_begin_node_t *parent_node) { parser_lex(parser); yp_rescue_node_operator_set(rescue, &parser->previous); - yp_node_t *reference = parse_expression(parser, YP_BINDING_POWER_INDEX, "Expected an exception variable after `=>` in rescue statement."); + yp_node_t *reference = parse_expression(parser, YP_BINDING_POWER_INDEX, YP_ERR_RESCUE_VARIABLE); reference = parse_target(parser, reference); yp_rescue_node_reference_set(rescue, reference); @@ -9228,7 +9228,7 @@ parse_rescues(yp_parser_t *parser, yp_begin_node_t *parent_node) { // we'll attempt to parse it here and any others delimited by commas. do { - yp_node_t *expression = parse_starred_expression(parser, YP_BINDING_POWER_DEFINED, "Expected to find a rescued expression."); + yp_node_t *expression = parse_starred_expression(parser, YP_BINDING_POWER_DEFINED, YP_ERR_RESCUE_EXPRESSION); yp_rescue_node_exceptions_append(rescue, expression); // If we hit a newline, then this is the end of the rescue expression. We @@ -9240,7 +9240,7 @@ parse_rescues(yp_parser_t *parser, yp_begin_node_t *parent_node) { if (accept(parser, YP_TOKEN_EQUAL_GREATER)) { yp_rescue_node_operator_set(rescue, &parser->previous); - yp_node_t *reference = parse_expression(parser, YP_BINDING_POWER_INDEX, "Expected an exception variable after `=>` in rescue statement."); + yp_node_t *reference = parse_expression(parser, YP_BINDING_POWER_INDEX, YP_ERR_RESCUE_VARIABLE); reference = parse_target(parser, reference); yp_rescue_node_reference_set(rescue, reference); @@ -9254,7 +9254,7 @@ parse_rescues(yp_parser_t *parser, yp_begin_node_t *parent_node) { if (accept_any(parser, 2, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON)) { accept(parser, YP_TOKEN_KEYWORD_THEN); } else { - expect(parser, YP_TOKEN_KEYWORD_THEN, "Expected a terminator after rescue clause."); + expect(parser, YP_TOKEN_KEYWORD_THEN, YP_ERR_RESCUE_TERM); } if (!match_any_type_p(parser, 3, YP_TOKEN_KEYWORD_ELSE, YP_TOKEN_KEYWORD_ENSURE, YP_TOKEN_KEYWORD_END)) { @@ -9374,7 +9374,7 @@ parse_block_parameters( yp_block_parameters_node_t *block_parameters = yp_block_parameters_node_create(parser, parameters, opening); if (accept(parser, YP_TOKEN_SEMICOLON)) { do { - expect(parser, YP_TOKEN_IDENTIFIER, "Expected a local variable name."); + expect(parser, YP_TOKEN_IDENTIFIER, YP_ERR_BLOCK_PARAM_LOCAL_VARIABLE); yp_parser_local_add_token(parser, &parser->previous); yp_block_local_variable_node_t *local = yp_block_local_variable_node_create(parser, &parser->previous); @@ -9406,7 +9406,7 @@ parse_block(yp_parser_t *parser) { parameters = parse_block_parameters(parser, true, &block_parameters_opening, false); accept(parser, YP_TOKEN_NEWLINE); parser->command_start = true; - expect(parser, YP_TOKEN_PIPE, "Expected block parameters to end with '|'."); + expect(parser, YP_TOKEN_PIPE, YP_ERR_BLOCK_PARAM_PIPE_TERM); } yp_block_parameters_node_closing_set(parameters, &parser->previous); @@ -9420,7 +9420,7 @@ parse_block(yp_parser_t *parser) { statements = (yp_node_t *) parse_statements(parser, YP_CONTEXT_BLOCK_BRACES); } - expect(parser, YP_TOKEN_BRACE_RIGHT, "Expected block beginning with '{' to end with '}'."); + expect(parser, YP_TOKEN_BRACE_RIGHT, YP_ERR_BLOCK_TERM_BRACE); } else { if (!match_type_p(parser, YP_TOKEN_KEYWORD_END)) { if (!match_any_type_p(parser, 3, YP_TOKEN_KEYWORD_RESCUE, YP_TOKEN_KEYWORD_ELSE, YP_TOKEN_KEYWORD_ENSURE)) { @@ -9435,7 +9435,7 @@ parse_block(yp_parser_t *parser) { } } - expect(parser, YP_TOKEN_KEYWORD_END, "Expected block beginning with 'do' to end with 'end'."); + expect(parser, YP_TOKEN_KEYWORD_END, YP_ERR_BLOCK_TERM_END); } yp_constant_id_list_t locals = parser->current_scope->locals; @@ -9462,7 +9462,7 @@ parse_arguments_list(yp_parser_t *parser, yp_arguments_t *arguments, bool accept yp_accepts_block_stack_push(parser, true); parse_arguments(parser, arguments, true, YP_TOKEN_PARENTHESIS_RIGHT); - expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, "Expected a ')' to close the argument list."); + expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, YP_ERR_ARGUMENT_TERM_PAREN); yp_accepts_block_stack_pop(parser); arguments->closing_loc = YP_LOCATION_TOKEN_VALUE(&parser->previous); @@ -9502,7 +9502,8 @@ parse_conditional(yp_parser_t *parser, yp_context_t context) { yp_token_t keyword = parser->previous; context_push(parser, YP_CONTEXT_PREDICATE); - yp_node_t *predicate = parse_expression(parser, YP_BINDING_POWER_MODIFIER, "Expected to find a predicate for the conditional."); + yp_diagnostic_id_t error_id = context == YP_CONTEXT_IF ? YP_ERR_CONDITIONAL_IF_PREDICATE : YP_ERR_CONDITIONAL_UNLESS_PREDICATE; + yp_node_t *predicate = parse_expression(parser, YP_BINDING_POWER_MODIFIER, error_id); // Predicates are closed by a term, a "then", or a term and then a "then". accept_any(parser, 2, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON); @@ -9540,7 +9541,7 @@ parse_conditional(yp_parser_t *parser, yp_context_t context) { if (context == YP_CONTEXT_IF) { while (accept(parser, YP_TOKEN_KEYWORD_ELSIF)) { yp_token_t elsif_keyword = parser->previous; - yp_node_t *predicate = parse_expression(parser, YP_BINDING_POWER_MODIFIER, "Expected to find a predicate for the elsif clause."); + yp_node_t *predicate = parse_expression(parser, YP_BINDING_POWER_MODIFIER, YP_ERR_CONDITIONAL_ELSIF_PREDICATE); // Predicates are closed by a term, a "then", or a term and then a "then". accept_any(parser, 2, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON); @@ -9567,7 +9568,7 @@ parse_conditional(yp_parser_t *parser, yp_context_t context) { yp_accepts_block_stack_pop(parser); accept_any(parser, 2, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON); - expect(parser, YP_TOKEN_KEYWORD_END, "Expected `end` to close `else` clause."); + expect(parser, YP_TOKEN_KEYWORD_END, YP_ERR_CONDITIONAL_TERM_ELSE); yp_else_node_t *else_node = yp_else_node_create(parser, &else_keyword, else_statements, &parser->previous); @@ -9583,7 +9584,8 @@ parse_conditional(yp_parser_t *parser, yp_context_t context) { break; } } else { - expect(parser, YP_TOKEN_KEYWORD_END, "Expected `end` to close conditional statement."); + // We should specialize this error message to refer to 'if' or 'unless' explicitly. + expect(parser, YP_TOKEN_KEYWORD_END, YP_ERR_CONDITIONAL_TERM); } // Set the appropriate end location for all of the nodes in the subtree. @@ -9733,7 +9735,7 @@ parse_string_part(yp_parser_t *parser) { parser->brace_nesting = brace_nesting; lex_state_set(parser, state); - expect(parser, YP_TOKEN_EMBEXPR_END, "Expected a closing delimiter for an embedded expression."); + expect(parser, YP_TOKEN_EMBEXPR_END, YP_ERR_EMBEXPR_END); yp_token_t closing = parser->previous; return (yp_node_t *) yp_embedded_statements_node_create(parser, &opening, statements, &closing); @@ -9787,7 +9789,7 @@ parse_string_part(yp_parser_t *parser) { // we'll not attempt to lex this token and instead just return a // missing node. default: - expect(parser, YP_TOKEN_IDENTIFIER, "Expected a valid embedded variable."); + expect(parser, YP_TOKEN_IDENTIFIER, YP_ERR_EMBVAR_INVALID); variable = (yp_node_t *) yp_missing_node_create(parser, parser->current.start, parser->current.end); break; } @@ -9796,7 +9798,7 @@ parse_string_part(yp_parser_t *parser) { } default: parser_lex(parser); - yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, "Could not understand string part"); + yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, YP_ERR_CANNOT_PARSE_STRING_PART); return NULL; } } @@ -9827,7 +9829,7 @@ parse_symbol(yp_parser_t *parser, yp_lex_mode_t *lex_mode, yp_lex_state_t next_s symbol = parser->previous; break; default: - expect(parser, YP_TOKEN_IDENTIFIER, "Expected symbol."); + expect(parser, YP_TOKEN_IDENTIFIER, YP_ERR_SYMBOL_INVALID); symbol = parser->previous; break; } @@ -9871,7 +9873,7 @@ parse_symbol(yp_parser_t *parser, yp_lex_mode_t *lex_mode, yp_lex_state_t next_s } if (next_state != YP_LEX_STATE_NONE) lex_state_set(parser, next_state); - expect(parser, YP_TOKEN_STRING_END, "Expected a closing delimiter for an interpolated symbol."); + expect(parser, YP_TOKEN_STRING_END, YP_ERR_SYMBOL_TERM_INTERPOLATED); return (yp_node_t *) yp_interpolated_symbol_node_create(parser, &opening, &node_list, &parser->previous); } @@ -9886,7 +9888,7 @@ parse_symbol(yp_parser_t *parser, yp_lex_mode_t *lex_mode, yp_lex_state_t next_s if (next_state != YP_LEX_STATE_NONE) { lex_state_set(parser, next_state); } - expect(parser, YP_TOKEN_STRING_END, "Expected a closing delimiter for a dynamic symbol."); + expect(parser, YP_TOKEN_STRING_END, YP_ERR_SYMBOL_TERM_DYNAMIC); return (yp_node_t *) yp_symbol_node_create_and_unescape(parser, &opening, &content, &parser->previous, YP_UNESCAPE_ALL); } @@ -9914,7 +9916,7 @@ parse_undef_argument(yp_parser_t *parser) { return parse_symbol(parser, &lex_mode, YP_LEX_STATE_NONE); } default: - yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, "Expected a bare word or symbol argument."); + yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_UNDEF_ARGUMENT); return (yp_node_t *) yp_missing_node_create(parser, parser->current.start, parser->current.end); } } @@ -9956,7 +9958,7 @@ parse_alias_argument(yp_parser_t *parser, bool first) { parser_lex(parser); return (yp_node_t *) yp_global_variable_read_node_create(parser, &parser->previous); default: - yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, "Expected a bare word, symbol or global variable argument."); + yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_ALIAS_ARGUMENT); return (yp_node_t *) yp_missing_node_create(parser, parser->current.start, parser->current.end); } } @@ -10175,7 +10177,7 @@ parse_heredoc_dedent(yp_parser_t *parser, yp_node_t *node, yp_heredoc_quote_t qu } static yp_node_t * -parse_pattern(yp_parser_t *parser, bool top_pattern, const char *message); +parse_pattern(yp_parser_t *parser, bool top_pattern, yp_diagnostic_id_t diag_id); // Accept any number of constants joined by :: delimiters. static yp_node_t * @@ -10184,7 +10186,7 @@ parse_pattern_constant_path(yp_parser_t *parser, yp_node_t *node) { // path nodes. while (accept(parser, YP_TOKEN_COLON_COLON)) { yp_token_t delimiter = parser->previous; - expect(parser, YP_TOKEN_CONSTANT, "Expected a constant after the :: operator."); + expect(parser, YP_TOKEN_CONSTANT, YP_ERR_CONSTANT_PATH_COLON_COLON_CONSTANT); yp_node_t *child = (yp_node_t *) yp_constant_read_node_create(parser, &parser->previous); node = (yp_node_t *)yp_constant_path_node_create(parser, node, &delimiter, child); @@ -10206,9 +10208,9 @@ parse_pattern_constant_path(yp_parser_t *parser, yp_node_t *node) { accept(parser, YP_TOKEN_NEWLINE); if (!accept(parser, YP_TOKEN_BRACKET_RIGHT)) { - inner = parse_pattern(parser, true, "Expected a pattern expression after the [ operator."); + inner = parse_pattern(parser, true, YP_ERR_PATTERN_EXPRESSION_AFTER_BRACKET); accept(parser, YP_TOKEN_NEWLINE); - expect(parser, YP_TOKEN_BRACKET_RIGHT, "Expected a ] to close the pattern expression."); + expect(parser, YP_TOKEN_BRACKET_RIGHT, YP_ERR_PATTERN_TERM_BRACKET); } closing = parser->previous; @@ -10217,8 +10219,8 @@ parse_pattern_constant_path(yp_parser_t *parser, yp_node_t *node) { opening = parser->previous; if (!accept(parser, YP_TOKEN_PARENTHESIS_RIGHT)) { - inner = parse_pattern(parser, true, "Expected a pattern expression after the ( operator."); - expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, "Expected a ) to close the pattern expression."); + inner = parse_pattern(parser, true, YP_ERR_PATTERN_EXPRESSION_AFTER_PAREN); + expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, YP_ERR_PATTERN_TERM_PAREN); } closing = parser->previous; @@ -10343,7 +10345,7 @@ parse_pattern_hash(yp_parser_t *parser, yp_node_t *first_assoc) { if (!match_any_type_p(parser, 7, YP_TOKEN_COMMA, YP_TOKEN_KEYWORD_THEN, YP_TOKEN_BRACE_RIGHT, YP_TOKEN_BRACKET_RIGHT, YP_TOKEN_PARENTHESIS_RIGHT, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON)) { // Here we have a value for the first assoc in the list, so we will parse it // now and update the first assoc. - yp_node_t *value = parse_pattern(parser, false, "Expected a pattern expression after the key."); + yp_node_t *value = parse_pattern(parser, false, YP_ERR_PATTERN_EXPRESSION_AFTER_KEY); yp_assoc_node_t *assoc = (yp_assoc_node_t *) first_assoc; assoc->base.location.end = value->location.end; @@ -10373,12 +10375,12 @@ parse_pattern_hash(yp_parser_t *parser, yp_node_t *first_assoc) { if (match_type_p(parser, YP_TOKEN_USTAR_STAR)) { assoc = parse_pattern_keyword_rest(parser); } else { - expect(parser, YP_TOKEN_LABEL, "Expected a label after the `,'."); + expect(parser, YP_TOKEN_LABEL, YP_ERR_PATTERN_LABEL_AFTER_COMMA); yp_node_t *key = (yp_node_t *) yp_symbol_node_label_create(parser, &parser->previous); yp_node_t *value = NULL; if (!match_any_type_p(parser, 7, YP_TOKEN_COMMA, YP_TOKEN_KEYWORD_THEN, YP_TOKEN_BRACE_RIGHT, YP_TOKEN_BRACKET_RIGHT, YP_TOKEN_PARENTHESIS_RIGHT, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON)) { - value = parse_pattern(parser, false, "Expected a pattern expression after the key."); + value = parse_pattern(parser, false, YP_ERR_PATTERN_EXPRESSION_AFTER_KEY); } else { const yp_location_t *value_loc = &((yp_symbol_node_t *) key)->value_loc; yp_parser_local_add_location(parser, value_loc->start, value_loc->end); @@ -10399,7 +10401,7 @@ parse_pattern_hash(yp_parser_t *parser, yp_node_t *first_assoc) { // Parse a pattern expression primitive. static yp_node_t * -parse_pattern_primitive(yp_parser_t *parser, const char *message) { +parse_pattern_primitive(yp_parser_t *parser, yp_diagnostic_id_t diag_id) { switch (parser->current.type) { case YP_TOKEN_IDENTIFIER: { parser_lex(parser); @@ -10418,11 +10420,11 @@ parse_pattern_primitive(yp_parser_t *parser, const char *message) { // Otherwise, we'll parse the inner pattern, then deal with it depending // on the type it returns. - yp_node_t *inner = parse_pattern(parser, true, "Expected a pattern expression after the [ operator."); + yp_node_t *inner = parse_pattern(parser, true, YP_ERR_PATTERN_EXPRESSION_AFTER_BRACKET); accept(parser, YP_TOKEN_NEWLINE); - expect(parser, YP_TOKEN_BRACKET_RIGHT, "Expected a ] to close the pattern expression."); + expect(parser, YP_TOKEN_BRACKET_RIGHT, YP_ERR_PATTERN_TERM_BRACKET); yp_token_t closing = parser->previous; switch (YP_NODE_TYPE(inner)) { @@ -10486,15 +10488,15 @@ parse_pattern_primitive(yp_parser_t *parser, const char *message) { key = parse_pattern_keyword_rest(parser); break; case YP_TOKEN_STRING_BEGIN: - key = parse_expression(parser, YP_BINDING_POWER_MAX, "Expected a key in the hash pattern."); + key = parse_expression(parser, YP_BINDING_POWER_MAX, YP_ERR_PATTERN_HASH_KEY); if (!yp_symbol_node_label_p(key)) { - yp_diagnostic_list_append(&parser->error_list, key->location.start, key->location.end, "Expected a label as the key in the hash pattern."); + yp_diagnostic_list_append(&parser->error_list, key->location.start, key->location.end, YP_ERR_PATTERN_HASH_KEY_LABEL); } break; default: parser_lex(parser); - yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, "Expected a key in the hash pattern."); + yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, YP_ERR_PATTERN_HASH_KEY); key = (yp_node_t *) yp_missing_node_create(parser, parser->previous.start, parser->previous.end); break; } @@ -10503,7 +10505,7 @@ parse_pattern_primitive(yp_parser_t *parser, const char *message) { node = parse_pattern_hash(parser, (yp_node_t *) yp_assoc_node_create(parser, key, &operator, NULL)); accept(parser, YP_TOKEN_NEWLINE); - expect(parser, YP_TOKEN_BRACE_RIGHT, "Expected a } to close the pattern expression."); + expect(parser, YP_TOKEN_BRACE_RIGHT, YP_ERR_PATTERN_TERM_BRACE); yp_token_t closing = parser->previous; node->base.location.start = opening.start; @@ -10525,18 +10527,18 @@ parse_pattern_primitive(yp_parser_t *parser, const char *message) { // expression as the right side of the range. switch (parser->current.type) { case YP_CASE_PRIMITIVE: { - yp_node_t *right = parse_expression(parser, YP_BINDING_POWER_MAX, "Expected an expression after the range operator."); + yp_node_t *right = parse_expression(parser, YP_BINDING_POWER_MAX, YP_ERR_PATTERN_EXPRESSION_AFTER_RANGE); return (yp_node_t *) yp_range_node_create(parser, NULL, &operator, right); } default: { - yp_diagnostic_list_append(&parser->error_list, operator.start, operator.end, "Expected an expression after the range operator."); + yp_diagnostic_list_append(&parser->error_list, operator.start, operator.end, YP_ERR_PATTERN_EXPRESSION_AFTER_RANGE); yp_node_t *right = (yp_node_t *) yp_missing_node_create(parser, operator.start, operator.end); return (yp_node_t *) yp_range_node_create(parser, NULL, &operator, right); } } } case YP_CASE_PRIMITIVE: { - yp_node_t *node = parse_expression(parser, YP_BINDING_POWER_MAX, message); + yp_node_t *node = parse_expression(parser, YP_BINDING_POWER_MAX, diag_id); // Now that we have a primitive, we need to check if it's part of a range. if (accept_any(parser, 2, YP_TOKEN_DOT_DOT, YP_TOKEN_DOT_DOT_DOT)) { @@ -10547,7 +10549,7 @@ parse_pattern_primitive(yp_parser_t *parser, const char *message) { // node. Otherwise, we'll create an endless range. switch (parser->current.type) { case YP_CASE_PRIMITIVE: { - yp_node_t *right = parse_expression(parser, YP_BINDING_POWER_MAX, "Expected an expression after the range operator."); + yp_node_t *right = parse_expression(parser, YP_BINDING_POWER_MAX, YP_ERR_PATTERN_EXPRESSION_AFTER_RANGE); return (yp_node_t *) yp_range_node_create(parser, node, &operator, right); } default: @@ -10607,17 +10609,17 @@ parse_pattern_primitive(yp_parser_t *parser, const char *message) { yp_token_t lparen = parser->current; parser_lex(parser); - yp_node_t *expression = parse_expression(parser, YP_BINDING_POWER_STATEMENT, "Expected an expression after the pin operator."); + yp_node_t *expression = parse_expression(parser, YP_BINDING_POWER_STATEMENT, YP_ERR_PATTERN_EXPRESSION_AFTER_PIN); parser->pattern_matching_newlines = previous_pattern_matching_newlines; accept(parser, YP_TOKEN_NEWLINE); - expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, "Expected a closing parenthesis after the expression."); + expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, YP_ERR_PATTERN_TERM_PAREN); return (yp_node_t *) yp_pinned_expression_node_create(parser, expression, &operator, &lparen, &parser->previous); } default: { // If we get here, then we have a pin operator followed by something // not understood. We'll create a missing node and return that. - yp_diagnostic_list_append(&parser->error_list, operator.start, operator.end, "Expected a variable after the pin operator."); + yp_diagnostic_list_append(&parser->error_list, operator.start, operator.end, YP_ERR_PATTERN_EXPRESSION_AFTER_PIN); yp_node_t *variable = (yp_node_t *) yp_missing_node_create(parser, operator.start, operator.end); return (yp_node_t *) yp_pinned_variable_node_create(parser, &operator, variable); } @@ -10627,7 +10629,7 @@ parse_pattern_primitive(yp_parser_t *parser, const char *message) { yp_token_t delimiter = parser->current; parser_lex(parser); - expect(parser, YP_TOKEN_CONSTANT, "Expected a constant after the :: operator."); + expect(parser, YP_TOKEN_CONSTANT, YP_ERR_CONSTANT_PATH_COLON_COLON_CONSTANT); yp_node_t *child = (yp_node_t *) yp_constant_read_node_create(parser, &parser->previous); yp_constant_path_node_t *node = yp_constant_path_node_create(parser, NULL, &delimiter, child); @@ -10641,7 +10643,7 @@ parse_pattern_primitive(yp_parser_t *parser, const char *message) { return parse_pattern_constant_path(parser, node); } default: - yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, message); + yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, diag_id); return (yp_node_t *) yp_missing_node_create(parser, parser->current.start, parser->current.end); } } @@ -10649,7 +10651,7 @@ parse_pattern_primitive(yp_parser_t *parser, const char *message) { // Parse any number of primitives joined by alternation and ended optionally by // assignment. static yp_node_t * -parse_pattern_primitives(yp_parser_t *parser, const char *message) { +parse_pattern_primitives(yp_parser_t *parser, yp_diagnostic_id_t diag_id) { yp_node_t *node = NULL; do { @@ -10666,9 +10668,9 @@ parse_pattern_primitives(yp_parser_t *parser, const char *message) { case YP_TOKEN_UDOT_DOT_DOT: case YP_CASE_PRIMITIVE: { if (node == NULL) { - node = parse_pattern_primitive(parser, message); + node = parse_pattern_primitive(parser, diag_id); } else { - yp_node_t *right = parse_pattern_primitive(parser, "Expected to be able to parse a pattern after `|'."); + yp_node_t *right = parse_pattern_primitive(parser, YP_ERR_PATTERN_EXPRESSION_AFTER_PIPE); node = (yp_node_t *) yp_alternation_pattern_node_create(parser, node, right, &operator); } @@ -10679,13 +10681,13 @@ parse_pattern_primitives(yp_parser_t *parser, const char *message) { if (node != NULL) { yp_node_destroy(parser, node); } - node = parse_pattern(parser, false, "Expected a pattern after the opening parenthesis."); + node = parse_pattern(parser, false, YP_ERR_PATTERN_EXPRESSION_AFTER_PAREN); - expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, "Expected a closing parenthesis after the pattern."); + expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, YP_ERR_PATTERN_TERM_PAREN); break; } default: { - yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, message); + yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, diag_id); yp_node_t *right = (yp_node_t *) yp_missing_node_create(parser, parser->current.start, parser->current.end); if (node == NULL) { @@ -10704,7 +10706,7 @@ parse_pattern_primitives(yp_parser_t *parser, const char *message) { while (accept(parser, YP_TOKEN_EQUAL_GREATER)) { yp_token_t operator = parser->previous; - expect(parser, YP_TOKEN_IDENTIFIER, "Expected an identifier after the `=>' operator."); + expect(parser, YP_TOKEN_IDENTIFIER, YP_ERR_PATTERN_IDENT_AFTER_HROCKET); yp_token_t identifier = parser->previous; yp_parser_local_add_token(parser, &identifier); @@ -10717,7 +10719,7 @@ parse_pattern_primitives(yp_parser_t *parser, const char *message) { // Parse a pattern matching expression. static yp_node_t * -parse_pattern(yp_parser_t *parser, bool top_pattern, const char *message) { +parse_pattern(yp_parser_t *parser, bool top_pattern, yp_diagnostic_id_t diag_id) { yp_node_t *node = NULL; bool leading_rest = false; @@ -10745,7 +10747,7 @@ parse_pattern(yp_parser_t *parser, bool top_pattern, const char *message) { } /* fallthrough */ default: - node = parse_pattern_primitives(parser, message); + node = parse_pattern_primitives(parser, diag_id); break; } @@ -10777,12 +10779,12 @@ parse_pattern(yp_parser_t *parser, bool top_pattern, const char *message) { // will continue to parse the rest of the patterns, but we will indicate // it as an error. if (trailing_rest) { - yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, "Unexpected rest pattern."); + yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, YP_ERR_PATTERN_REST); } trailing_rest = true; } else { - node = parse_pattern_primitives(parser, "Expected a pattern after the comma."); + node = parse_pattern_primitives(parser, YP_ERR_PATTERN_EXPRESSION_AFTER_COMMA); } yp_node_list_append(&nodes, node); @@ -10850,7 +10852,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { } if (yp_array_node_size(array) != 0) { - expect(parser, YP_TOKEN_COMMA, "Expected a separator for the elements in an array."); + expect(parser, YP_TOKEN_COMMA, YP_ERR_ARRAY_SEPARATOR); } // If we have a right bracket immediately following a comma, this is @@ -10862,11 +10864,11 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { if (accept(parser, YP_TOKEN_USTAR)) { yp_token_t operator = parser->previous; - yp_node_t *expression = parse_expression(parser, YP_BINDING_POWER_DEFINED, "Expected an expression after '*' in the array."); + yp_node_t *expression = parse_expression(parser, YP_BINDING_POWER_DEFINED, YP_ERR_ARRAY_EXPRESSION_AFTER_STAR); element = (yp_node_t *) yp_splat_node_create(parser, &operator, expression); } else if (match_any_type_p(parser, 2, YP_TOKEN_LABEL, YP_TOKEN_USTAR_STAR)) { if (parsed_bare_hash) { - yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, "Unexpected bare hash."); + yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_EXPRESSION_BARE_HASH); } yp_keyword_hash_node_t *hash = yp_keyword_hash_node_create(parser); @@ -10878,11 +10880,11 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { parsed_bare_hash = true; } else { - element = parse_expression(parser, YP_BINDING_POWER_DEFINED, "Expected an element for the array."); + element = parse_expression(parser, YP_BINDING_POWER_DEFINED, YP_ERR_ARRAY_EXPRESSION); if (yp_symbol_node_label_p(element) || accept(parser, YP_TOKEN_EQUAL_GREATER)) { if (parsed_bare_hash) { - yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, "Unexpected bare hash."); + yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, YP_ERR_EXPRESSION_BARE_HASH); } yp_keyword_hash_node_t *hash = yp_keyword_hash_node_create(parser); @@ -10894,7 +10896,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { operator = not_provided(parser); } - yp_node_t *value = parse_expression(parser, YP_BINDING_POWER_DEFINED, "Expected a value in the hash literal."); + yp_node_t *value = parse_expression(parser, YP_BINDING_POWER_DEFINED, YP_ERR_HASH_VALUE); yp_node_t *assoc = (yp_node_t *) yp_assoc_node_create(parser, element, &operator, value); yp_keyword_hash_node_elements_append(hash, assoc); @@ -10912,7 +10914,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { } accept(parser, YP_TOKEN_NEWLINE); - expect(parser, YP_TOKEN_BRACKET_RIGHT, "Expected a closing bracket for the array."); + expect(parser, YP_TOKEN_BRACKET_RIGHT, YP_ERR_ARRAY_TERM); yp_array_node_close_set(array, &parser->previous); yp_accepts_block_stack_pop(parser); @@ -10927,14 +10929,14 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { // If this is the end of the file or we match a right parenthesis, then // we have an empty parentheses node, and we can immediately return. if (match_any_type_p(parser, 2, YP_TOKEN_PARENTHESIS_RIGHT, YP_TOKEN_EOF)) { - expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, "Expected a closing parenthesis."); + expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, YP_ERR_EXPECT_RPAREN); return (yp_node_t *) yp_parentheses_node_create(parser, &opening, NULL, &parser->previous); } // Otherwise, we're going to parse the first statement in the list of // statements within the parentheses. yp_accepts_block_stack_push(parser, true); - yp_node_t *statement = parse_expression(parser, YP_BINDING_POWER_STATEMENT, "Expected to be able to parse an expression."); + yp_node_t *statement = parse_expression(parser, YP_BINDING_POWER_STATEMENT, YP_ERR_CANNOT_PARSE_EXPRESSION); while (accept_any(parser, 2, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON)); // If we hit a right parenthesis, then we're done parsing the parentheses @@ -10992,7 +10994,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { // Ignore semicolon without statements before them if (accept_any(parser, 2, YP_TOKEN_SEMICOLON, YP_TOKEN_NEWLINE)) continue; - yp_node_t *node = parse_expression(parser, YP_BINDING_POWER_STATEMENT, "Expected to be able to parse an expression."); + yp_node_t *node = parse_expression(parser, YP_BINDING_POWER_STATEMENT, YP_ERR_CANNOT_PARSE_EXPRESSION); yp_statements_node_body_append(statements, node); // If we're recovering from a syntax error, then we need to stop parsing the @@ -11009,7 +11011,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { context_pop(parser); yp_accepts_block_stack_pop(parser); - expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, "Expected a closing parenthesis."); + expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, YP_ERR_EXPECT_RPAREN); return (yp_node_t *) yp_parentheses_node_create(parser, &opening, (yp_node_t *) statements, &parser->previous); } @@ -11024,7 +11026,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { } yp_accepts_block_stack_pop(parser); - expect(parser, YP_TOKEN_BRACE_RIGHT, "Expected a closing delimiter for a hash literal."); + expect(parser, YP_TOKEN_BRACE_RIGHT, YP_ERR_HASH_TERM); yp_hash_node_closing_loc_set(node, &parser->previous); return (yp_node_t *) node; @@ -11084,7 +11086,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { parser_lex(parser); yp_token_t delimiter = parser->previous; - expect(parser, YP_TOKEN_CONSTANT, "Expected a constant after ::."); + expect(parser, YP_TOKEN_CONSTANT, YP_ERR_CONSTANT_PATH_COLON_COLON_CONSTANT); yp_node_t *constant = (yp_node_t *) yp_constant_read_node_create(parser, &parser->previous); yp_node_t *node = (yp_node_t *)yp_constant_path_node_create(parser, NULL, &delimiter, constant); @@ -11100,7 +11102,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { yp_token_t operator = parser->current; parser_lex(parser); - yp_node_t *right = parse_expression(parser, binding_power, "Expected a value after the operator."); + yp_node_t *right = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR); return (yp_node_t *) yp_range_node_create(parser, NULL, &operator, right); } case YP_TOKEN_FLOAT: @@ -11229,7 +11231,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { } lex_state_set(parser, YP_LEX_STATE_END); - expect(parser, YP_TOKEN_HEREDOC_END, "Expected a closing delimiter for heredoc."); + expect(parser, YP_TOKEN_HEREDOC_END, YP_ERR_HEREDOC_TERM); if (quote == YP_HEREDOC_QUOTE_BACKTICK) { assert(YP_NODE_TYPE_P(node, YP_INTERPOLATED_X_STRING_NODE)); @@ -11254,7 +11256,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { return (yp_node_t *) yp_string_concat_node_create( parser, node, - parse_expression(parser, YP_BINDING_POWER_CALL, "Expected string on the right side of concatenation.") + parse_expression(parser, YP_BINDING_POWER_CALL, YP_ERR_CANNOT_PARSE_EXPRESSION) ); } else { return node; @@ -11302,7 +11304,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { case YP_SYMBOL_NODE: case YP_INTERPOLATED_SYMBOL_NODE: { if (!YP_NODE_TYPE_P(old_name, YP_SYMBOL_NODE) && !YP_NODE_TYPE_P(old_name, YP_INTERPOLATED_SYMBOL_NODE)) { - yp_diagnostic_list_append(&parser->error_list, old_name->location.start, old_name->location.end, "Expected a bare word or symbol argument."); + yp_diagnostic_list_append(&parser->error_list, old_name->location.start, old_name->location.end, YP_ERR_ALIAS_ARGUMENT); } break; } @@ -11311,10 +11313,10 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { case YP_GLOBAL_VARIABLE_READ_NODE: { if (YP_NODE_TYPE_P(old_name, YP_BACK_REFERENCE_READ_NODE) || YP_NODE_TYPE_P(old_name, YP_NUMBERED_REFERENCE_READ_NODE) || YP_NODE_TYPE_P(old_name, YP_GLOBAL_VARIABLE_READ_NODE)) { if (YP_NODE_TYPE_P(old_name, YP_NUMBERED_REFERENCE_READ_NODE)) { - yp_diagnostic_list_append(&parser->error_list, old_name->location.start, old_name->location.end, "Can't make alias for number variables."); + yp_diagnostic_list_append(&parser->error_list, old_name->location.start, old_name->location.end, YP_ERR_ALIAS_ARGUMENT); } } else { - yp_diagnostic_list_append(&parser->error_list, old_name->location.start, old_name->location.end, "Expected a global variable."); + yp_diagnostic_list_append(&parser->error_list, old_name->location.start, old_name->location.end, YP_ERR_ALIAS_ARGUMENT); } break; } @@ -11336,7 +11338,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { ) { predicate = NULL; } else { - predicate = parse_expression(parser, YP_BINDING_POWER_COMPOSITION, "Expected a value after case keyword."); + predicate = parse_expression(parser, YP_BINDING_POWER_COMPOSITION, YP_ERR_CASE_EXPRESSION_AFTER_CASE); while (accept_any(parser, 2, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON)); } @@ -11360,14 +11362,14 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { do { if (accept(parser, YP_TOKEN_USTAR)) { yp_token_t operator = parser->previous; - yp_node_t *expression = parse_expression(parser, YP_BINDING_POWER_DEFINED, "Expected a value after `*' operator."); + yp_node_t *expression = parse_expression(parser, YP_BINDING_POWER_DEFINED, YP_ERR_EXPECT_EXPRESSION_AFTER_STAR); yp_splat_node_t *splat_node = yp_splat_node_create(parser, &operator, expression); yp_when_node_conditions_append(when_node, (yp_node_t *) splat_node); if (YP_NODE_TYPE_P(expression, YP_MISSING_NODE)) break; } else { - yp_node_t *condition = parse_expression(parser, YP_BINDING_POWER_DEFINED, "Expected a value after when keyword."); + yp_node_t *condition = parse_expression(parser, YP_BINDING_POWER_DEFINED, YP_ERR_CASE_EXPRESSION_AFTER_WHEN); yp_when_node_conditions_append(when_node, condition); if (YP_NODE_TYPE_P(condition, YP_MISSING_NODE)) break; @@ -11377,7 +11379,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { if (accept_any(parser, 2, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON)) { accept(parser, YP_TOKEN_KEYWORD_THEN); } else { - expect(parser, YP_TOKEN_KEYWORD_THEN, "Expected a delimiter after the predicates of a `when' clause."); + expect(parser, YP_TOKEN_KEYWORD_THEN, YP_ERR_EXPECT_WHEN_DELIMITER); } if (!match_any_type_p(parser, 3, YP_TOKEN_KEYWORD_WHEN, YP_TOKEN_KEYWORD_ELSE, YP_TOKEN_KEYWORD_END)) { @@ -11401,18 +11403,18 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { parser_lex(parser); yp_token_t in_keyword = parser->previous; - yp_node_t *pattern = parse_pattern(parser, true, "Expected a pattern after `in' keyword."); + yp_node_t *pattern = parse_pattern(parser, true, YP_ERR_PATTERN_EXPRESSION_AFTER_IN); parser->pattern_matching_newlines = previous_pattern_matching_newlines; // Since we're in the top-level of the case-in node we need to check // for guard clauses in the form of `if` or `unless` statements. if (accept(parser, YP_TOKEN_KEYWORD_IF_MODIFIER)) { yp_token_t keyword = parser->previous; - yp_node_t *predicate = parse_expression(parser, YP_BINDING_POWER_DEFINED, "Expected a value after guard keyword."); + yp_node_t *predicate = parse_expression(parser, YP_BINDING_POWER_DEFINED, YP_ERR_CONDITIONAL_IF_PREDICATE); pattern = (yp_node_t *) yp_if_node_modifier_create(parser, pattern, &keyword, predicate); } else if (accept(parser, YP_TOKEN_KEYWORD_UNLESS_MODIFIER)) { yp_token_t keyword = parser->previous; - yp_node_t *predicate = parse_expression(parser, YP_BINDING_POWER_DEFINED, "Expected a value after guard keyword."); + yp_node_t *predicate = parse_expression(parser, YP_BINDING_POWER_DEFINED, YP_ERR_CONDITIONAL_UNLESS_PREDICATE); pattern = (yp_node_t *) yp_unless_node_modifier_create(parser, pattern, &keyword, predicate); } @@ -11427,7 +11429,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { then_keyword = not_provided(parser); } } else { - expect(parser, YP_TOKEN_KEYWORD_THEN, "Expected a delimiter after the predicates of an `in' clause."); + expect(parser, YP_TOKEN_KEYWORD_THEN, YP_ERR_EXPECT_WHEN_DELIMITER); then_keyword = parser->previous; } @@ -11450,7 +11452,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { accept_any(parser, 2, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON); if (accept(parser, YP_TOKEN_KEYWORD_ELSE)) { if (case_node->conditions.size < 1) { - yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, "Unexpected else without no when clauses in case statement."); + yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, YP_ERR_CASE_LONELY_ELSE); } yp_token_t else_keyword = parser->previous; @@ -11465,7 +11467,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { yp_case_node_consequent_set(case_node, else_node); } - expect(parser, YP_TOKEN_KEYWORD_END, "Expected case statement to end with an end keyword."); + expect(parser, YP_TOKEN_KEYWORD_END, YP_ERR_CASE_TERM); yp_case_node_end_keyword_loc_set(case_node, &parser->previous); return (yp_node_t *) case_node; } @@ -11486,7 +11488,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { yp_begin_node_t *begin_node = yp_begin_node_create(parser, &begin_keyword, begin_statements); parse_rescues(parser, begin_node); - expect(parser, YP_TOKEN_KEYWORD_END, "Expected `end` to close `begin` statement."); + expect(parser, YP_TOKEN_KEYWORD_END, YP_ERR_BEGIN_TERM); begin_node->base.location.end = parser->previous.end; yp_begin_node_end_keyword_set(begin_node, &parser->previous); @@ -11495,7 +11497,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { &parser->error_list, begin_node->else_clause->base.location.start, begin_node->else_clause->base.location.end, - "else without rescue is useless" + YP_ERR_BEGIN_LONELY_ELSE ); } @@ -11505,11 +11507,11 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { parser_lex(parser); yp_token_t keyword = parser->previous; - expect(parser, YP_TOKEN_BRACE_LEFT, "Expected '{' after 'BEGIN'."); + expect(parser, YP_TOKEN_BRACE_LEFT, YP_ERR_BEGIN_UPCASE_BRACE); yp_token_t opening = parser->previous; yp_statements_node_t *statements = parse_statements(parser, YP_CONTEXT_PREEXE); - expect(parser, YP_TOKEN_BRACE_RIGHT, "Expected '}' after 'BEGIN' statements."); + expect(parser, YP_TOKEN_BRACE_RIGHT, YP_ERR_BEGIN_UPCASE_TERM); return (yp_node_t *) yp_pre_execution_node_create(parser, &keyword, &opening, statements, &parser->previous); } case YP_TOKEN_KEYWORD_BREAK: @@ -11542,7 +11544,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { (parser->current_context->context == YP_CONTEXT_CLASS) || (parser->current_context->context == YP_CONTEXT_MODULE) ) { - yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, "Invalid return in class/module body"); + yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_RETURN_INVALID); } return (yp_node_t *) yp_return_node_create(parser, &keyword, arguments.arguments); } @@ -11580,7 +11582,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { if (accept(parser, YP_TOKEN_LESS_LESS)) { yp_token_t operator = parser->previous; - yp_node_t *expression = parse_expression(parser, YP_BINDING_POWER_NOT, "Expected to find an expression after `<<`."); + yp_node_t *expression = parse_expression(parser, YP_BINDING_POWER_NOT, YP_ERR_EXPECT_EXPRESSION_AFTER_LESS_LESS); yp_parser_scope_push(parser, true); accept_any(parser, 2, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON); @@ -11597,7 +11599,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { statements = (yp_node_t *) parse_rescues_as_begin(parser, (yp_statements_node_t *) statements); } - expect(parser, YP_TOKEN_KEYWORD_END, "Expected `end` to close `class` statement."); + expect(parser, YP_TOKEN_KEYWORD_END, YP_ERR_CLASS_TERM); yp_constant_id_list_t locals = parser->current_scope->locals; yp_parser_scope_pop(parser); @@ -11605,10 +11607,10 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { return (yp_node_t *) yp_singleton_class_node_create(parser, &locals, &class_keyword, &operator, expression, statements, &parser->previous); } - yp_node_t *constant_path = parse_expression(parser, YP_BINDING_POWER_INDEX, "Expected to find a class name after `class`."); + yp_node_t *constant_path = parse_expression(parser, YP_BINDING_POWER_INDEX, YP_ERR_CLASS_NAME); yp_token_t name = parser->previous; if (name.type != YP_TOKEN_CONSTANT) { - yp_diagnostic_list_append(&parser->error_list, name.start, name.end, "Expected a constant name after `class`."); + yp_diagnostic_list_append(&parser->error_list, name.start, name.end, YP_ERR_CLASS_NAME); } yp_token_t inheritance_operator; @@ -11621,7 +11623,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { parser->command_start = true; parser_lex(parser); - superclass = parse_expression(parser, YP_BINDING_POWER_COMPOSITION, "Expected to find a superclass after `<`."); + superclass = parse_expression(parser, YP_BINDING_POWER_COMPOSITION, YP_ERR_CLASS_SUPERCLASS); } else { inheritance_operator = not_provided(parser); superclass = NULL; @@ -11642,10 +11644,10 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { statements = (yp_node_t *) parse_rescues_as_begin(parser, (yp_statements_node_t *) statements); } - expect(parser, YP_TOKEN_KEYWORD_END, "Expected `end` to close `class` statement."); + expect(parser, YP_TOKEN_KEYWORD_END, YP_ERR_CLASS_TERM); if (context_def_p(parser)) { - yp_diagnostic_list_append(&parser->error_list, class_keyword.start, class_keyword.end, "Class definition in method body"); + yp_diagnostic_list_append(&parser->error_list, class_keyword.start, class_keyword.end, YP_ERR_CLASS_IN_METHOD); } yp_constant_id_list_t locals = parser->current_scope->locals; @@ -11684,7 +11686,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { name = parse_method_definition_name(parser); if (name.type == YP_TOKEN_MISSING) { - yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, "Expected a method name after receiver."); + yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, YP_ERR_DEF_NAME_AFTER_RECEIVER); } } else { name = parser->previous; @@ -11752,7 +11754,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { name = parse_method_definition_name(parser); if (name.type == YP_TOKEN_MISSING) { - yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, "Expected a method name after receiver."); + yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, YP_ERR_DEF_NAME_AFTER_RECEIVER); } } else { name = identifier; @@ -11762,13 +11764,13 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { case YP_TOKEN_PARENTHESIS_LEFT: { parser_lex(parser); yp_token_t lparen = parser->previous; - yp_node_t *expression = parse_expression(parser, YP_BINDING_POWER_STATEMENT, "Expected to be able to parse receiver."); + yp_node_t *expression = parse_expression(parser, YP_BINDING_POWER_STATEMENT, YP_ERR_DEF_RECEIVER); - expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, "Expected closing ')' for receiver."); + expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, YP_ERR_EXPECT_RPAREN); yp_token_t rparen = parser->previous; lex_state_set(parser, YP_LEX_STATE_FNAME); - expect_any(parser, "Expected '.' or '::' after receiver", 2, YP_TOKEN_DOT, YP_TOKEN_COLON_COLON); + expect_any(parser, YP_ERR_DEF_RECEIVER_TERM, 2, YP_TOKEN_DOT, YP_TOKEN_COLON_COLON); operator = parser->previous; receiver = (yp_node_t *) yp_parentheses_node_create(parser, &lparen, expression, &rparen); @@ -11782,7 +11784,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { name = parse_method_definition_name(parser); if (name.type == YP_TOKEN_MISSING) { - yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, "Expected a method name after receiver."); + yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, YP_ERR_DEF_NAME); } break; } @@ -11805,7 +11807,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { lex_state_set(parser, YP_LEX_STATE_BEG); parser->command_start = true; - expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, "Expected ')' after left parenthesis."); + expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, YP_ERR_DEF_PARAMS_TERM_PAREN); rparen = parser->previous; break; } @@ -11836,18 +11838,18 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { if (accept(parser, YP_TOKEN_EQUAL)) { if (token_is_setter_name(&name)) { - yp_diagnostic_list_append(&parser->error_list, name.start, name.end, "Setter method cannot be defined in an endless method definition"); + yp_diagnostic_list_append(&parser->error_list, name.start, name.end, YP_ERR_DEF_ENDLESS_SETTER); } equal = parser->previous; context_push(parser, YP_CONTEXT_DEF); statements = (yp_node_t *) yp_statements_node_create(parser); - yp_node_t *statement = parse_expression(parser, YP_BINDING_POWER_DEFINED + 1, "Expected to be able to parse body of endless method definition."); + yp_node_t *statement = parse_expression(parser, YP_BINDING_POWER_DEFINED + 1, YP_ERR_DEF_ENDLESS); if (accept(parser, YP_TOKEN_KEYWORD_RESCUE_MODIFIER)) { yp_token_t rescue_keyword = parser->previous; - yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after the rescue keyword."); + yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_RESCUE_MODIFIER_VALUE); yp_rescue_modifier_node_t *rescue_node = yp_rescue_modifier_node_create(parser, statement, &rescue_keyword, value); statement = (yp_node_t *)rescue_node; } @@ -11861,7 +11863,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { if (lparen.type == YP_TOKEN_NOT_PROVIDED) { lex_state_set(parser, YP_LEX_STATE_BEG); parser->command_start = true; - expect_any(parser, "Expected a terminator after the parameters", 2, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON); + expect_any(parser, YP_ERR_DEF_PARAMS_TERM, 2, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON); } else { accept_any(parser, 2, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON); } @@ -11882,7 +11884,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { yp_accepts_block_stack_pop(parser); yp_do_loop_stack_pop(parser); - expect(parser, YP_TOKEN_KEYWORD_END, "Expected `end` to close `def` statement."); + expect(parser, YP_TOKEN_KEYWORD_END, YP_ERR_DEF_TERM); end_keyword = parser->previous; } @@ -11914,18 +11916,18 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { if (accept(parser, YP_TOKEN_PARENTHESIS_LEFT)) { lparen = parser->previous; - expression = parse_expression(parser, YP_BINDING_POWER_COMPOSITION, "Expected expression after `defined?`."); + expression = parse_expression(parser, YP_BINDING_POWER_COMPOSITION, YP_ERR_DEFINED_EXPRESSION); if (parser->recovering) { rparen = not_provided(parser); } else { - expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, "Expected ')' after 'defined?' expression."); + expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, YP_ERR_EXPECT_RPAREN); rparen = parser->previous; } } else { lparen = not_provided(parser); rparen = not_provided(parser); - expression = parse_expression(parser, YP_BINDING_POWER_DEFINED, "Expected expression after `defined?`."); + expression = parse_expression(parser, YP_BINDING_POWER_DEFINED, YP_ERR_DEFINED_EXPRESSION); } return (yp_node_t *) yp_defined_node_create( @@ -11940,11 +11942,11 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { parser_lex(parser); yp_token_t keyword = parser->previous; - expect(parser, YP_TOKEN_BRACE_LEFT, "Expected '{' after 'END'."); + expect(parser, YP_TOKEN_BRACE_LEFT, YP_ERR_END_UPCASE_BRACE); yp_token_t opening = parser->previous; yp_statements_node_t *statements = parse_statements(parser, YP_CONTEXT_POSTEXE); - expect(parser, YP_TOKEN_BRACE_RIGHT, "Expected '}' after 'END' statements."); + expect(parser, YP_TOKEN_BRACE_RIGHT, YP_ERR_END_UPCASE_TERM); return (yp_node_t *) yp_post_execution_node_create(parser, &keyword, &opening, statements, &parser->previous); } case YP_TOKEN_KEYWORD_FALSE: @@ -11957,10 +11959,10 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { yp_node_t *index = parse_targets(parser, NULL, YP_BINDING_POWER_INDEX); yp_do_loop_stack_push(parser, true); - expect(parser, YP_TOKEN_KEYWORD_IN, "Expected keyword in."); + expect(parser, YP_TOKEN_KEYWORD_IN, YP_ERR_FOR_IN); yp_token_t in_keyword = parser->previous; - yp_node_t *collection = parse_expression(parser, YP_BINDING_POWER_COMPOSITION, "Expected collection."); + yp_node_t *collection = parse_expression(parser, YP_BINDING_POWER_COMPOSITION, YP_ERR_FOR_COLLECTION); yp_do_loop_stack_pop(parser); yp_token_t do_keyword; @@ -11975,7 +11977,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { if (!accept(parser, YP_TOKEN_KEYWORD_END)) { statements = parse_statements(parser, YP_CONTEXT_FOR); - expect(parser, YP_TOKEN_KEYWORD_END, "Expected `end` to close for loop."); + expect(parser, YP_TOKEN_KEYWORD_END, YP_ERR_FOR_TERM); } return (yp_node_t *) yp_for_node_create(parser, index, collection, statements, &for_keyword, &in_keyword, &do_keyword, &parser->previous); @@ -12024,17 +12026,17 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { if (accept(parser, YP_TOKEN_PARENTHESIS_RIGHT)) { arguments.closing_loc = YP_LOCATION_TOKEN_VALUE(&parser->previous); } else { - receiver = parse_expression(parser, YP_BINDING_POWER_COMPOSITION, "Expected expression after `not`."); + receiver = parse_expression(parser, YP_BINDING_POWER_COMPOSITION, YP_ERR_NOT_EXPRESSION); yp_flip_flop(receiver); if (!parser->recovering) { accept(parser, YP_TOKEN_NEWLINE); - expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, "Expected ')' after 'not' expression."); + expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, YP_ERR_EXPECT_RPAREN); arguments.closing_loc = YP_LOCATION_TOKEN_VALUE(&parser->previous); } } } else { - receiver = parse_expression(parser, YP_BINDING_POWER_DEFINED, "Expected expression after `not`."); + receiver = parse_expression(parser, YP_BINDING_POWER_DEFINED, YP_ERR_NOT_EXPRESSION); yp_flip_flop(receiver); } @@ -12047,7 +12049,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { parser_lex(parser); yp_token_t module_keyword = parser->previous; - yp_node_t *constant_path = parse_expression(parser, YP_BINDING_POWER_INDEX, "Expected to find a module name after `module`."); + yp_node_t *constant_path = parse_expression(parser, YP_BINDING_POWER_INDEX, YP_ERR_MODULE_NAME); yp_token_t name; // If we can recover from a syntax error that occurred while parsing @@ -12060,7 +12062,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { while (accept(parser, YP_TOKEN_COLON_COLON)) { yp_token_t double_colon = parser->previous; - expect(parser, YP_TOKEN_CONSTANT, "Expected to find a module name after `::`."); + expect(parser, YP_TOKEN_CONSTANT, YP_ERR_CONSTANT_PATH_COLON_COLON_CONSTANT); yp_node_t *constant = (yp_node_t *) yp_constant_read_node_create(parser, &parser->previous); constant_path = (yp_node_t *) yp_constant_path_node_create(parser, constant_path, &double_colon, constant); @@ -12071,7 +12073,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { // syntax error. We handle that here as well. name = parser->previous; if (name.type != YP_TOKEN_CONSTANT) { - yp_diagnostic_list_append(&parser->error_list, name.start, name.end, "Expected to find a module name after `module`."); + yp_diagnostic_list_append(&parser->error_list, name.start, name.end, YP_ERR_MODULE_NAME); } yp_parser_scope_push(parser, true); @@ -12092,10 +12094,10 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { yp_constant_id_list_t locals = parser->current_scope->locals; yp_parser_scope_pop(parser); - expect(parser, YP_TOKEN_KEYWORD_END, "Expected `end` to close `module` statement."); + expect(parser, YP_TOKEN_KEYWORD_END, YP_ERR_MODULE_TERM); if (context_def_p(parser)) { - yp_diagnostic_list_append(&parser->error_list, module_keyword.start, module_keyword.end, "Module definition in method body"); + yp_diagnostic_list_append(&parser->error_list, module_keyword.start, module_keyword.end, YP_ERR_MODULE_IN_METHOD); } return (yp_node_t *) yp_module_node_create(parser, &locals, &module_keyword, constant_path, &name, statements, &parser->previous); @@ -12120,7 +12122,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { parser_lex(parser); yp_token_t keyword = parser->previous; - yp_node_t *predicate = parse_expression(parser, YP_BINDING_POWER_COMPOSITION, "Expected predicate expression after `until`."); + yp_node_t *predicate = parse_expression(parser, YP_BINDING_POWER_COMPOSITION, YP_ERR_CONDITIONAL_UNTIL_PREDICATE); yp_do_loop_stack_pop(parser); accept_any(parser, 3, YP_TOKEN_KEYWORD_DO_LOOP, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON); @@ -12131,7 +12133,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { statements = parse_statements(parser, YP_CONTEXT_UNTIL); yp_accepts_block_stack_pop(parser); accept_any(parser, 2, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON); - expect(parser, YP_TOKEN_KEYWORD_END, "Expected `end` to close `until` statement."); + expect(parser, YP_TOKEN_KEYWORD_END, YP_ERR_UNTIL_TERM); } return (yp_node_t *) yp_until_node_create(parser, &keyword, &parser->previous, predicate, statements, 0); @@ -12141,7 +12143,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { parser_lex(parser); yp_token_t keyword = parser->previous; - yp_node_t *predicate = parse_expression(parser, YP_BINDING_POWER_COMPOSITION, "Expected predicate expression after `while`."); + yp_node_t *predicate = parse_expression(parser, YP_BINDING_POWER_COMPOSITION, YP_ERR_CONDITIONAL_WHILE_PREDICATE); yp_do_loop_stack_pop(parser); accept_any(parser, 3, YP_TOKEN_KEYWORD_DO_LOOP, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON); @@ -12152,7 +12154,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { statements = parse_statements(parser, YP_CONTEXT_WHILE); yp_accepts_block_stack_pop(parser); accept_any(parser, 2, YP_TOKEN_NEWLINE, YP_TOKEN_SEMICOLON); - expect(parser, YP_TOKEN_KEYWORD_END, "Expected `end` to close `while` statement."); + expect(parser, YP_TOKEN_KEYWORD_END, YP_ERR_WHILE_TERM); } return (yp_node_t *) yp_while_node_create(parser, &keyword, &parser->previous, predicate, statements, 0); @@ -12165,7 +12167,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { accept(parser, YP_TOKEN_WORDS_SEP); if (match_type_p(parser, YP_TOKEN_STRING_END)) break; - expect(parser, YP_TOKEN_STRING_CONTENT, "Expected a symbol in a `%i` list."); + expect(parser, YP_TOKEN_STRING_CONTENT, YP_ERR_LIST_I_LOWER_ELEMENT); yp_token_t opening = not_provided(parser); yp_token_t closing = not_provided(parser); @@ -12174,7 +12176,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { yp_array_node_elements_append(array, symbol); } - expect(parser, YP_TOKEN_STRING_END, "Expected a closing delimiter for a `%i` list."); + expect(parser, YP_TOKEN_STRING_END, YP_ERR_LIST_I_LOWER_TERM); yp_array_node_close_set(array, &parser->previous); return (yp_node_t *) array; @@ -12310,7 +12312,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { break; } default: - expect(parser, YP_TOKEN_STRING_CONTENT, "Expected a symbol in a `%I` list."); + expect(parser, YP_TOKEN_STRING_CONTENT, YP_ERR_LIST_I_UPPER_ELEMENT); parser_lex(parser); break; } @@ -12321,7 +12323,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { yp_array_node_elements_append(array, current); } - expect(parser, YP_TOKEN_STRING_END, "Expected a closing delimiter for a `%I` list."); + expect(parser, YP_TOKEN_STRING_END, YP_ERR_LIST_I_UPPER_TERM); yp_array_node_close_set(array, &parser->previous); return (yp_node_t *) array; @@ -12337,7 +12339,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { accept(parser, YP_TOKEN_WORDS_SEP); if (match_type_p(parser, YP_TOKEN_STRING_END)) break; - expect(parser, YP_TOKEN_STRING_CONTENT, "Expected a string in a `%w` list."); + expect(parser, YP_TOKEN_STRING_CONTENT, YP_ERR_LIST_W_LOWER_ELEMENT); yp_token_t opening = not_provided(parser); yp_token_t closing = not_provided(parser); @@ -12345,7 +12347,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { yp_array_node_elements_append(array, string); } - expect(parser, YP_TOKEN_STRING_END, "Expected a closing delimiter for a `%w` list."); + expect(parser, YP_TOKEN_STRING_END, YP_ERR_LIST_W_LOWER_TERM); yp_array_node_close_set(array, &parser->previous); return (yp_node_t *) array; @@ -12461,7 +12463,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { break; } default: - expect(parser, YP_TOKEN_STRING_CONTENT, "Expected a string in a `%W` list."); + expect(parser, YP_TOKEN_STRING_CONTENT, YP_ERR_LIST_W_UPPER_ELEMENT); parser_lex(parser); break; } @@ -12472,7 +12474,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { yp_array_node_elements_append(array, current); } - expect(parser, YP_TOKEN_STRING_END, "Expected a closing delimiter for a `%W` list."); + expect(parser, YP_TOKEN_STRING_END, YP_ERR_LIST_W_UPPER_TERM); yp_array_node_close_set(array, &parser->previous); return (yp_node_t *) array; @@ -12536,7 +12538,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { } } - expect(parser, YP_TOKEN_REGEXP_END, "Expected a closing delimiter for a regular expression."); + expect(parser, YP_TOKEN_REGEXP_END, YP_ERR_REGEXP_TERM); yp_interpolated_regular_expression_node_closing_set(node, &parser->previous); return (yp_node_t *) node; @@ -12600,7 +12602,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { } } - expect(parser, YP_TOKEN_STRING_END, "Expected a closing delimiter for an xstring."); + expect(parser, YP_TOKEN_STRING_END, YP_ERR_XSTRING_TERM); yp_interpolated_xstring_node_closing_set(node, &parser->previous); return (yp_node_t *) node; } @@ -12618,7 +12620,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { yp_node_t *name = NULL; if (token_begins_expression_p(parser->current.type)) { - name = parse_expression(parser, YP_BINDING_POWER_INDEX, "Expected an expression after '*'."); + name = parse_expression(parser, YP_BINDING_POWER_INDEX, YP_ERR_EXPECT_EXPRESSION_AFTER_STAR); } yp_node_t *splat = (yp_node_t *) yp_splat_node_create(parser, &operator, name); @@ -12628,7 +12630,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { parser_lex(parser); yp_token_t operator = parser->previous; - yp_node_t *receiver = parse_expression(parser, yp_binding_powers[parser->previous.type].right, "Expected a receiver after unary !."); + yp_node_t *receiver = parse_expression(parser, yp_binding_powers[parser->previous.type].right, YP_ERR_UNARY_RECEIVER_BANG); yp_call_node_t *node = yp_call_node_unary_create(parser, &operator, receiver, "!"); yp_flip_flop(receiver); @@ -12638,7 +12640,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { parser_lex(parser); yp_token_t operator = parser->previous; - yp_node_t *receiver = parse_expression(parser, yp_binding_powers[parser->previous.type].right, "Expected a receiver after unary ~."); + yp_node_t *receiver = parse_expression(parser, yp_binding_powers[parser->previous.type].right, YP_ERR_UNARY_RECEIVER_TILDE); yp_call_node_t *node = yp_call_node_unary_create(parser, &operator, receiver, "~"); return (yp_node_t *) node; @@ -12647,7 +12649,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { parser_lex(parser); yp_token_t operator = parser->previous; - yp_node_t *receiver = parse_expression(parser, yp_binding_powers[parser->previous.type].right, "Expected a receiver after unary -."); + yp_node_t *receiver = parse_expression(parser, yp_binding_powers[parser->previous.type].right, YP_ERR_UNARY_RECEIVER_MINUS); yp_call_node_t *node = yp_call_node_unary_create(parser, &operator, receiver, "-@"); return (yp_node_t *) node; @@ -12656,7 +12658,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { parser_lex(parser); yp_token_t operator = parser->previous; - yp_node_t *node = parse_expression(parser, yp_binding_powers[parser->previous.type].right, "Expected a receiver after unary -."); + yp_node_t *node = parse_expression(parser, yp_binding_powers[parser->previous.type].right, YP_ERR_UNARY_RECEIVER_MINUS); switch (YP_NODE_TYPE(node)) { case YP_INTEGER_NODE: @@ -12695,7 +12697,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { } accept(parser, YP_TOKEN_NEWLINE); - expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, "Expected ')' after left parenthesis."); + expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, YP_ERR_EXPECT_RPAREN); yp_block_parameters_node_closing_set(params, &parser->previous); break; @@ -12722,10 +12724,10 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { if (!accept(parser, YP_TOKEN_BRACE_RIGHT)) { body = (yp_node_t *) parse_statements(parser, YP_CONTEXT_LAMBDA_BRACES); - expect(parser, YP_TOKEN_BRACE_RIGHT, "Expecting '}' to close lambda block."); + expect(parser, YP_TOKEN_BRACE_RIGHT, YP_ERR_LAMBDA_TERM_BRACE); } } else { - expect(parser, YP_TOKEN_KEYWORD_DO, "Expected a 'do' keyword or a '{' to open lambda block."); + expect(parser, YP_TOKEN_KEYWORD_DO, YP_ERR_LAMBDA_OPEN); opening = parser->previous; if (!match_any_type_p(parser, 3, YP_TOKEN_KEYWORD_END, YP_TOKEN_KEYWORD_RESCUE, YP_TOKEN_KEYWORD_ENSURE)) { @@ -12739,7 +12741,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { body = (yp_node_t *) parse_rescues_as_begin(parser, (yp_statements_node_t *) body); } - expect(parser, YP_TOKEN_KEYWORD_END, "Expecting 'end' keyword to close lambda block."); + expect(parser, YP_TOKEN_KEYWORD_END, YP_ERR_LAMBDA_TERM_END); } yp_constant_id_list_t locals = parser->current_scope->locals; @@ -12751,7 +12753,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { parser_lex(parser); yp_token_t operator = parser->previous; - yp_node_t *receiver = parse_expression(parser, yp_binding_powers[parser->previous.type].right, "Expected a receiver after unary +."); + yp_node_t *receiver = parse_expression(parser, yp_binding_powers[parser->previous.type].right, YP_ERR_UNARY_RECEIVER_PLUS); yp_call_node_t *node = yp_call_node_unary_create(parser, &operator, receiver, "+@"); return (yp_node_t *) node; @@ -12793,7 +12795,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { } else if (!lex_interpolation) { // If we don't accept interpolation then we expect the // string to start with a single string content node. - expect(parser, YP_TOKEN_STRING_CONTENT, "Expected string content after opening delimiter."); + expect(parser, YP_TOKEN_STRING_CONTENT, YP_ERR_EXPECT_STRING_CONTENT); yp_token_t content = parser->previous; // It is unfortunately possible to have multiple string @@ -12820,12 +12822,12 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { yp_node_list_append(&parts, part); } - expect(parser, YP_TOKEN_STRING_END, "Expected a closing delimiter for a string literal."); + expect(parser, YP_TOKEN_STRING_END, YP_ERR_STRING_LITERAL_TERM); node = (yp_node_t *) yp_interpolated_string_node_create(parser, &opening, &parts, &parser->previous); } else if (accept(parser, YP_TOKEN_LABEL_END)) { node = (yp_node_t *) yp_symbol_node_create_and_unescape(parser, &opening, &content, &parser->previous, YP_UNESCAPE_ALL); } else { - expect(parser, YP_TOKEN_STRING_END, "Expected a closing delimiter for a string literal."); + expect(parser, YP_TOKEN_STRING_END, YP_ERR_STRING_LITERAL_TERM); node = (yp_node_t *) yp_string_node_create_and_unescape(parser, &opening, &content, &parser->previous, YP_UNESCAPE_MINIMAL); } } else if (match_type_p(parser, YP_TOKEN_STRING_CONTENT)) { @@ -12857,7 +12859,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { if (accept(parser, YP_TOKEN_LABEL_END)) { node = (yp_node_t *) yp_interpolated_symbol_node_create(parser, &opening, &parts, &parser->previous); } else { - expect(parser, YP_TOKEN_STRING_END, "Expected a closing delimiter for an interpolated string."); + expect(parser, YP_TOKEN_STRING_END, YP_ERR_STRING_INTERPOLATED_TERM); node = (yp_node_t *) yp_interpolated_string_node_create(parser, &opening, &parts, &parser->previous); } } @@ -12875,7 +12877,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { if (accept(parser, YP_TOKEN_LABEL_END)) { node = (yp_node_t *) yp_interpolated_symbol_node_create(parser, &opening, &parts, &parser->previous); } else { - expect(parser, YP_TOKEN_STRING_END, "Expected a closing delimiter for an interpolated string."); + expect(parser, YP_TOKEN_STRING_END, YP_ERR_STRING_INTERPOLATED_TERM); node = (yp_node_t *) yp_interpolated_string_node_create(parser, &opening, &parts, &parser->previous); } } @@ -12896,7 +12898,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { // parsed. If it cannot be concatenated with the previous // node, then we'll need to add a syntax error. if (!YP_NODE_TYPE_P(node, YP_STRING_NODE) && !YP_NODE_TYPE_P(node, YP_INTERPOLATED_STRING_NODE)) { - yp_diagnostic_list_append(&parser->error_list, node->location.start, node->location.end, "Unexpected string concatenation."); + yp_diagnostic_list_append(&parser->error_list, node->location.start, node->location.end, YP_ERR_STRING_CONCATENATION); } // Either way we will create a concat node to hold the @@ -12923,8 +12925,8 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { } static inline yp_node_t * -parse_assignment_value(yp_parser_t *parser, yp_binding_power_t previous_binding_power, yp_binding_power_t binding_power, const char *message) { - yp_node_t *value = parse_starred_expression(parser, binding_power, message); +parse_assignment_value(yp_parser_t *parser, yp_binding_power_t previous_binding_power, yp_binding_power_t binding_power, yp_diagnostic_id_t diag_id) { + yp_node_t *value = parse_starred_expression(parser, binding_power, diag_id); if (previous_binding_power == YP_BINDING_POWER_STATEMENT && (YP_NODE_TYPE_P(value, YP_SPLAT_NODE) || match_type_p(parser, YP_TOKEN_COMMA))) { yp_token_t opening = not_provided(parser); @@ -12934,7 +12936,7 @@ parse_assignment_value(yp_parser_t *parser, yp_binding_power_t previous_binding_ value = (yp_node_t *) array; while (accept(parser, YP_TOKEN_COMMA)) { - yp_node_t *element = parse_starred_expression(parser, binding_power, "Expected an element for the array."); + yp_node_t *element = parse_starred_expression(parser, binding_power, YP_ERR_ARRAY_ELEMENT); yp_array_node_elements_append(array, element); if (YP_NODE_TYPE_P(element, YP_MISSING_NODE)) break; } @@ -12963,7 +12965,7 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t /* fallthrough */ case YP_CASE_WRITABLE: { parser_lex(parser); - yp_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, "Expected a value after =."); + yp_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_EQUAL); return parse_write(parser, node, &token, value); } case YP_SPLAT_NODE: { @@ -12972,7 +12974,7 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t switch (YP_NODE_TYPE(splat_node->expression)) { case YP_CASE_WRITABLE: parser_lex(parser); - yp_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, "Expected a value after =."); + yp_node_t *value = parse_assignment_value(parser, previous_binding_power, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_EQUAL); return parse_write(parser, (yp_node_t *) splat_node, &token, value); default: break; @@ -12985,7 +12987,7 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t // In this case we have an = sign, but we don't know what it's for. We // need to treat it as an error. For now, we'll mark it as an error // and just skip right past it. - yp_diagnostic_list_append(&parser->error_list, token.start, token.end, "Unexpected `='."); + yp_diagnostic_list_append(&parser->error_list, token.start, token.end, YP_ERR_EXPECT_EXPRESSION_AFTER_EQUAL); return node; } } @@ -12993,12 +12995,12 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t switch (YP_NODE_TYPE(node)) { case YP_BACK_REFERENCE_READ_NODE: case YP_NUMBERED_REFERENCE_READ_NODE: - yp_diagnostic_list_append(&parser->error_list, node->location.start, node->location.end, "Can't set variable"); + yp_diagnostic_list_append(&parser->error_list, node->location.start, node->location.end, YP_ERR_WRITE_TARGET_READONLY); /* fallthrough */ case YP_GLOBAL_VARIABLE_READ_NODE: { parser_lex(parser); - yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after &&="); + yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ); yp_node_t *result = (yp_node_t *) yp_global_variable_and_write_node_create(parser, node, &token, value); yp_node_destroy(parser, node); @@ -13007,7 +13009,7 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t case YP_CLASS_VARIABLE_READ_NODE: { parser_lex(parser); - yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after &&="); + yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ); yp_node_t *result = (yp_node_t *) yp_class_variable_and_write_node_create(parser, (yp_class_variable_read_node_t *) node, &token, value); yp_node_destroy(parser, node); @@ -13016,13 +13018,13 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t case YP_CONSTANT_PATH_NODE: { parser_lex(parser); - yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after &&="); + yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ); return (yp_node_t *) yp_constant_path_and_write_node_create(parser, (yp_constant_path_node_t *) node, &token, value); } case YP_CONSTANT_READ_NODE: { parser_lex(parser); - yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after &&="); + yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ); yp_node_t *result = (yp_node_t *) yp_constant_and_write_node_create(parser, (yp_constant_read_node_t *) node, &token, value); yp_node_destroy(parser, node); @@ -13031,7 +13033,7 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t case YP_INSTANCE_VARIABLE_READ_NODE: { parser_lex(parser); - yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after &&="); + yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ); yp_node_t *result = (yp_node_t *) yp_instance_variable_and_write_node_create(parser, (yp_instance_variable_read_node_t *) node, &token, value); yp_node_destroy(parser, node); @@ -13041,7 +13043,7 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t yp_local_variable_read_node_t *cast = (yp_local_variable_read_node_t *) node; parser_lex(parser); - yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after &&="); + yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ); yp_node_t *result = (yp_node_t *) yp_local_variable_and_write_node_create(parser, node, &token, value, cast->name, cast->depth); yp_node_destroy(parser, node); @@ -13058,11 +13060,11 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t yp_constant_id_t constant_id = yp_parser_local_add_location(parser, message_loc.start, message_loc.end); if (token_is_numbered_parameter(message_loc.start, message_loc.end)) { - yp_diagnostic_list_append(&parser->error_list, message_loc.start, message_loc.end, "reserved for numbered parameter"); + yp_diagnostic_list_append(&parser->error_list, message_loc.start, message_loc.end, YP_ERR_PARAMETER_NUMBERED_RESERVED); } parser_lex(parser); - yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after &&="); + yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ); yp_node_t *result = (yp_node_t *) yp_local_variable_and_write_node_create(parser, node, &token, value, constant_id, 0); yp_node_destroy(parser, node); @@ -13072,12 +13074,12 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t parser_lex(parser); node = parse_target(parser, node); - yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after &&="); + yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ); return (yp_node_t *) yp_call_and_write_node_create(parser, (yp_call_node_t *) node, &token, value); } case YP_MULTI_WRITE_NODE: { parser_lex(parser); - yp_diagnostic_list_append(&parser->error_list, token.start, token.end, "Cannot use `&&=' on a multi-write."); + yp_diagnostic_list_append(&parser->error_list, token.start, token.end, YP_ERR_AMPAMPEQ_MULTI_ASSIGN); return node; } default: @@ -13086,7 +13088,7 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t // In this case we have an &&= sign, but we don't know what it's for. // We need to treat it as an error. For now, we'll mark it as an error // and just skip right past it. - yp_diagnostic_list_append(&parser->error_list, token.start, token.end, "Unexpected `&&='."); + yp_diagnostic_list_append(&parser->error_list, token.start, token.end, YP_ERR_EXPECT_EXPRESSION_AFTER_AMPAMPEQ); return node; } } @@ -13094,12 +13096,12 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t switch (YP_NODE_TYPE(node)) { case YP_BACK_REFERENCE_READ_NODE: case YP_NUMBERED_REFERENCE_READ_NODE: - yp_diagnostic_list_append(&parser->error_list, node->location.start, node->location.end, "Can't set variable"); + yp_diagnostic_list_append(&parser->error_list, node->location.start, node->location.end, YP_ERR_WRITE_TARGET_READONLY); /* fallthrough */ case YP_GLOBAL_VARIABLE_READ_NODE: { parser_lex(parser); - yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after ||="); + yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ); yp_node_t *result = (yp_node_t *) yp_global_variable_or_write_node_create(parser, node, &token, value); yp_node_destroy(parser, node); @@ -13108,7 +13110,7 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t case YP_CLASS_VARIABLE_READ_NODE: { parser_lex(parser); - yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after ||="); + yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ); yp_node_t *result = (yp_node_t *) yp_class_variable_or_write_node_create(parser, (yp_class_variable_read_node_t *) node, &token, value); yp_node_destroy(parser, node); @@ -13117,13 +13119,13 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t case YP_CONSTANT_PATH_NODE: { parser_lex(parser); - yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after ||="); + yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ); return (yp_node_t *) yp_constant_path_or_write_node_create(parser, (yp_constant_path_node_t *) node, &token, value); } case YP_CONSTANT_READ_NODE: { parser_lex(parser); - yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after ||="); + yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ); yp_node_t *result = (yp_node_t *) yp_constant_or_write_node_create(parser, (yp_constant_read_node_t *) node, &token, value); yp_node_destroy(parser, node); @@ -13132,7 +13134,7 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t case YP_INSTANCE_VARIABLE_READ_NODE: { parser_lex(parser); - yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after ||="); + yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ); yp_node_t *result = (yp_node_t *) yp_instance_variable_or_write_node_create(parser, (yp_instance_variable_read_node_t *) node, &token, value); yp_node_destroy(parser, node); @@ -13142,7 +13144,7 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t yp_local_variable_read_node_t *cast = (yp_local_variable_read_node_t *) node; parser_lex(parser); - yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after ||="); + yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ); yp_node_t *result = (yp_node_t *) yp_local_variable_or_write_node_create(parser, node, &token, value, cast->name, cast->depth); yp_node_destroy(parser, node); @@ -13159,11 +13161,11 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t yp_constant_id_t constant_id = yp_parser_local_add_location(parser, message_loc.start, message_loc.end); if (token_is_numbered_parameter(message_loc.start, message_loc.end)) { - yp_diagnostic_list_append(&parser->error_list, message_loc.start, message_loc.end, "reserved for numbered parameter"); + yp_diagnostic_list_append(&parser->error_list, message_loc.start, message_loc.end, YP_ERR_PARAMETER_NUMBERED_RESERVED); } parser_lex(parser); - yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after ||="); + yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ); yp_node_t *result = (yp_node_t *) yp_local_variable_or_write_node_create(parser, node, &token, value, constant_id, 0); yp_node_destroy(parser, node); @@ -13173,12 +13175,12 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t parser_lex(parser); node = parse_target(parser, node); - yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after ||="); + yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ); return (yp_node_t *) yp_call_or_write_node_create(parser, (yp_call_node_t *) node, &token, value); } case YP_MULTI_WRITE_NODE: { parser_lex(parser); - yp_diagnostic_list_append(&parser->error_list, token.start, token.end, "Cannot use `||=' on a multi-write."); + yp_diagnostic_list_append(&parser->error_list, token.start, token.end, YP_ERR_PIPEPIPEEQ_MULTI_ASSIGN); return node; } default: @@ -13187,7 +13189,7 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t // In this case we have an ||= sign, but we don't know what it's for. // We need to treat it as an error. For now, we'll mark it as an error // and just skip right past it. - yp_diagnostic_list_append(&parser->error_list, token.start, token.end, "Unexpected `||='."); + yp_diagnostic_list_append(&parser->error_list, token.start, token.end, YP_ERR_EXPECT_EXPRESSION_AFTER_PIPEPIPEEQ); return node; } } @@ -13205,12 +13207,12 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t switch (YP_NODE_TYPE(node)) { case YP_BACK_REFERENCE_READ_NODE: case YP_NUMBERED_REFERENCE_READ_NODE: - yp_diagnostic_list_append(&parser->error_list, node->location.start, node->location.end, "Can't set variable"); + yp_diagnostic_list_append(&parser->error_list, node->location.start, node->location.end, YP_ERR_WRITE_TARGET_READONLY); /* fallthrough */ case YP_GLOBAL_VARIABLE_READ_NODE: { parser_lex(parser); - yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after the operator."); + yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR); yp_node_t *result = (yp_node_t *) yp_global_variable_operator_write_node_create(parser, node, &token, value); yp_node_destroy(parser, node); @@ -13219,7 +13221,7 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t case YP_CLASS_VARIABLE_READ_NODE: { parser_lex(parser); - yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after the operator."); + yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR); yp_node_t *result = (yp_node_t *) yp_class_variable_operator_write_node_create(parser, (yp_class_variable_read_node_t *) node, &token, value); yp_node_destroy(parser, node); @@ -13228,13 +13230,13 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t case YP_CONSTANT_PATH_NODE: { parser_lex(parser); - yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after the operator."); + yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR); return (yp_node_t *) yp_constant_path_operator_write_node_create(parser, (yp_constant_path_node_t *) node, &token, value); } case YP_CONSTANT_READ_NODE: { parser_lex(parser); - yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after the operator."); + yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR); yp_node_t *result = (yp_node_t *) yp_constant_operator_write_node_create(parser, (yp_constant_read_node_t *) node, &token, value); yp_node_destroy(parser, node); @@ -13243,7 +13245,7 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t case YP_INSTANCE_VARIABLE_READ_NODE: { parser_lex(parser); - yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after the operator."); + yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR); yp_node_t *result = (yp_node_t *) yp_instance_variable_operator_write_node_create(parser, (yp_instance_variable_read_node_t *) node, &token, value); yp_node_destroy(parser, node); @@ -13253,7 +13255,7 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t yp_local_variable_read_node_t *cast = (yp_local_variable_read_node_t *) node; parser_lex(parser); - yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after the operator."); + yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR); yp_node_t *result = (yp_node_t *) yp_local_variable_operator_write_node_create(parser, node, &token, value, cast->name, cast->depth); yp_node_destroy(parser, node); @@ -13270,11 +13272,11 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t yp_constant_id_t constant_id = yp_parser_local_add_location(parser, message_loc.start, message_loc.end); if (token_is_numbered_parameter(message_loc.start, message_loc.end)) { - yp_diagnostic_list_append(&parser->error_list, message_loc.start, message_loc.end, "reserved for numbered parameter"); + yp_diagnostic_list_append(&parser->error_list, message_loc.start, message_loc.end, YP_ERR_PARAMETER_NUMBERED_RESERVED); } parser_lex(parser); - yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after the operator."); + yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR); yp_node_t *result = (yp_node_t *) yp_local_variable_operator_write_node_create(parser, node, &token, value, constant_id, 0); yp_node_destroy(parser, node); @@ -13284,12 +13286,12 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t node = parse_target(parser, node); parser_lex(parser); - yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after the operator."); + yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR); return (yp_node_t *) yp_call_operator_write_node_create(parser, (yp_call_node_t *) node, &token, value); } case YP_MULTI_WRITE_NODE: { parser_lex(parser); - yp_diagnostic_list_append(&parser->error_list, token.start, token.end, "Unexpected operator."); + yp_diagnostic_list_append(&parser->error_list, token.start, token.end, YP_ERR_OPERATOR_MULTI_ASSIGN); return node; } default: @@ -13298,7 +13300,7 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t // In this case we have an operator but we don't know what it's for. // We need to treat it as an error. For now, we'll mark it as an error // and just skip right past it. - yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, "Unexpected operator."); + yp_diagnostic_list_append(&parser->error_list, parser->previous.start, parser->previous.end, YP_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR); return node; } } @@ -13306,14 +13308,14 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t case YP_TOKEN_KEYWORD_AND: { parser_lex(parser); - yp_node_t *right = parse_expression(parser, binding_power, "Expected a value after the operator."); + yp_node_t *right = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR); return (yp_node_t *) yp_and_node_create(parser, node, &token, right); } case YP_TOKEN_KEYWORD_OR: case YP_TOKEN_PIPE_PIPE: { parser_lex(parser); - yp_node_t *right = parse_expression(parser, binding_power, "Expected a value after the operator."); + yp_node_t *right = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR); return (yp_node_t *) yp_or_node_create(parser, node, &token, right); } case YP_TOKEN_EQUAL_TILDE: { @@ -13324,7 +13326,7 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t // // In this case, `foo` should be a method call and not a local yet. parser_lex(parser); - yp_node_t *argument = parse_expression(parser, binding_power, "Expected a value after the operator."); + yp_node_t *argument = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR); // If the receiver of this =~ is a regular expression node, then we need // to introduce local variables for it based on its named capture groups. @@ -13375,7 +13377,7 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t case YP_TOKEN_STAR_STAR: { parser_lex(parser); - yp_node_t *argument = parse_expression(parser, binding_power, "Expected a value after the operator."); + yp_node_t *argument = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR); return (yp_node_t *) yp_call_node_binary_create(parser, node, &token, argument); } case YP_TOKEN_AMPERSAND_DOT: @@ -13402,7 +13404,7 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t break; } default: { - yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, "Expected a valid method name"); + yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, YP_ERR_DEF_NAME); message = (yp_token_t) { .type = YP_TOKEN_MISSING, .start = parser->previous.end, .end = parser->previous.end }; } } @@ -13427,7 +13429,7 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t yp_node_t *right = NULL; if (token_begins_expression_p(parser->current.type)) { - right = parse_expression(parser, binding_power, "Expected a value after the operator."); + right = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_OPERATOR); } return (yp_node_t *) yp_range_node_create(parser, node, &token, right); @@ -13436,14 +13438,14 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t yp_token_t keyword = parser->current; parser_lex(parser); - yp_node_t *predicate = parse_expression(parser, binding_power, "Expected a predicate after `if'."); + yp_node_t *predicate = parse_expression(parser, binding_power, YP_ERR_CONDITIONAL_IF_PREDICATE); return (yp_node_t *) yp_if_node_modifier_create(parser, node, &keyword, predicate); } case YP_TOKEN_KEYWORD_UNLESS_MODIFIER: { yp_token_t keyword = parser->current; parser_lex(parser); - yp_node_t *predicate = parse_expression(parser, binding_power, "Expected a predicate after `unless'."); + yp_node_t *predicate = parse_expression(parser, binding_power, YP_ERR_CONDITIONAL_UNLESS_PREDICATE); return (yp_node_t *) yp_unless_node_modifier_create(parser, node, &keyword, predicate); } case YP_TOKEN_KEYWORD_UNTIL_MODIFIER: { @@ -13451,7 +13453,7 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t yp_statements_node_t *statements = yp_statements_node_create(parser); yp_statements_node_body_append(statements, node); - yp_node_t *predicate = parse_expression(parser, binding_power, "Expected a predicate after 'until'"); + yp_node_t *predicate = parse_expression(parser, binding_power, YP_ERR_CONDITIONAL_UNTIL_PREDICATE); return (yp_node_t *) yp_until_node_modifier_create(parser, &token, predicate, statements, YP_NODE_TYPE_P(node, YP_BEGIN_NODE) ? YP_LOOP_FLAGS_BEGIN_MODIFIER : 0); } case YP_TOKEN_KEYWORD_WHILE_MODIFIER: { @@ -13459,12 +13461,12 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t yp_statements_node_t *statements = yp_statements_node_create(parser); yp_statements_node_body_append(statements, node); - yp_node_t *predicate = parse_expression(parser, binding_power, "Expected a predicate after 'while'"); + yp_node_t *predicate = parse_expression(parser, binding_power, YP_ERR_CONDITIONAL_WHILE_PREDICATE); return (yp_node_t *) yp_while_node_modifier_create(parser, &token, predicate, statements, YP_NODE_TYPE_P(node, YP_BEGIN_NODE) ? YP_LOOP_FLAGS_BEGIN_MODIFIER : 0); } case YP_TOKEN_QUESTION_MARK: { parser_lex(parser); - yp_node_t *true_expression = parse_expression(parser, YP_BINDING_POWER_DEFINED, "Expected a value after '?'"); + yp_node_t *true_expression = parse_expression(parser, YP_BINDING_POWER_DEFINED, YP_ERR_TERNARY_EXPRESSION_TRUE); if (parser->recovering) { // If parsing the true expression of this ternary resulted in a syntax @@ -13480,10 +13482,10 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t } accept(parser, YP_TOKEN_NEWLINE); - expect(parser, YP_TOKEN_COLON, "Expected ':' after true expression in ternary operator."); + expect(parser, YP_TOKEN_COLON, YP_ERR_TERNARY_COLON); yp_token_t colon = parser->previous; - yp_node_t *false_expression = parse_expression(parser, YP_BINDING_POWER_DEFINED, "Expected a value after ':'"); + yp_node_t *false_expression = parse_expression(parser, YP_BINDING_POWER_DEFINED, YP_ERR_TERNARY_EXPRESSION_FALSE); return (yp_node_t *) yp_if_node_ternary_create(parser, node, true_expression, &colon, false_expression); } @@ -13552,7 +13554,7 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t return (yp_node_t *) yp_call_node_shorthand_create(parser, node, &delimiter, &arguments); } default: { - yp_diagnostic_list_append(&parser->error_list, delimiter.start, delimiter.end, "Expected identifier or constant after '::'"); + yp_diagnostic_list_append(&parser->error_list, delimiter.start, delimiter.end, YP_ERR_CONSTANT_PATH_COLON_COLON_CONSTANT); yp_node_t *child = (yp_node_t *) yp_missing_node_create(parser, delimiter.start, delimiter.end); return (yp_node_t *)yp_constant_path_node_create(parser, node, &delimiter, child); } @@ -13561,7 +13563,7 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t case YP_TOKEN_KEYWORD_RESCUE_MODIFIER: { parser_lex(parser); accept(parser, YP_TOKEN_NEWLINE); - yp_node_t *value = parse_expression(parser, binding_power, "Expected a value after the rescue keyword."); + yp_node_t *value = parse_expression(parser, binding_power, YP_ERR_RESCUE_MODIFIER_VALUE); return (yp_node_t *) yp_rescue_modifier_node_create(parser, node, &token, value); } @@ -13578,7 +13580,7 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t parse_arguments(parser, &arguments, false, YP_TOKEN_BRACKET_RIGHT); yp_accepts_block_stack_pop(parser); - expect(parser, YP_TOKEN_BRACKET_RIGHT, "Expected ']' to close the bracket expression."); + expect(parser, YP_TOKEN_BRACKET_RIGHT, YP_ERR_EXPECT_RBRACKET); } arguments.closing_loc = YP_LOCATION_TOKEN_VALUE(&parser->previous); @@ -13612,7 +13614,7 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t parser_lex(parser); - yp_node_t *pattern = parse_pattern(parser, true, "Expected a pattern after `in'."); + yp_node_t *pattern = parse_pattern(parser, true, YP_ERR_PATTERN_EXPRESSION_AFTER_IN); parser->pattern_matching_newlines = previous_pattern_matching_newlines; return (yp_node_t *) yp_match_predicate_node_create(parser, node, pattern, &operator); @@ -13627,7 +13629,7 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t parser_lex(parser); - yp_node_t *pattern = parse_pattern(parser, true, "Expected a pattern after `=>'."); + yp_node_t *pattern = parse_pattern(parser, true, YP_ERR_PATTERN_EXPRESSION_AFTER_HROCKET); parser->pattern_matching_newlines = previous_pattern_matching_newlines; return (yp_node_t *) yp_match_required_node_create(parser, node, pattern, &operator); @@ -13645,7 +13647,7 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t // Consumers of this function should always check parser->recovering to // determine if they need to perform additional cleanup. static yp_node_t * -parse_expression(yp_parser_t *parser, yp_binding_power_t binding_power, const char *message) { +parse_expression(yp_parser_t *parser, yp_binding_power_t binding_power, yp_diagnostic_id_t diag_id) { yp_token_t recovery = parser->previous; yp_node_t *node = parse_expression_prefix(parser, binding_power); @@ -13653,7 +13655,7 @@ parse_expression(yp_parser_t *parser, yp_binding_power_t binding_power, const ch // parse_expression_prefix is going to be a missing node. In that case we need // to add the error message to the parser's error list. if (YP_NODE_TYPE_P(node, YP_MISSING_NODE)) { - yp_diagnostic_list_append(&parser->error_list, recovery.end, recovery.end, message); + yp_diagnostic_list_append(&parser->error_list, recovery.end, recovery.end, diag_id); return node; } From 5b5ae3d9e064e17e2a7d8d21d739fcc62ae1075c Mon Sep 17 00:00:00 2001 From: Takashi Kokubun Date: Thu, 7 Sep 2023 10:57:52 -0700 Subject: [PATCH 23/46] Rewrite Integer#times in Ruby (#8388) --- gems/bundled_gems | 2 +- numeric.c | 53 ---------------------------------- numeric.rb | 23 +++++++++++++++ test/ruby/test_backtrace.rb | 6 ++-- test/ruby/test_integer.rb | 23 +++++++++++---- test/ruby/test_settracefunc.rb | 18 ++++++------ 6 files changed, 53 insertions(+), 72 deletions(-) diff --git a/gems/bundled_gems b/gems/bundled_gems index 34433723fa5368..a12fd3bac3e2cf 100644 --- a/gems/bundled_gems +++ b/gems/bundled_gems @@ -19,5 +19,5 @@ matrix 0.4.2 https://github.com/ruby/matrix prime 0.1.2 https://github.com/ruby/prime rbs 3.2.1 https://github.com/ruby/rbs typeprof 0.21.8 https://github.com/ruby/typeprof -debug 1.8.0 https://github.com/ruby/debug +debug 1.8.0 https://github.com/ruby/debug 927587afb6aac69b358b86a01f602d207053e8d2 racc 1.7.1 https://github.com/ruby/racc diff --git a/numeric.c b/numeric.c index 6afb5b50dede91..82fac8320fea45 100644 --- a/numeric.c +++ b/numeric.c @@ -5652,58 +5652,6 @@ int_downto(VALUE from, VALUE to) return from; } -static VALUE -int_dotimes_size(VALUE num, VALUE args, VALUE eobj) -{ - if (FIXNUM_P(num)) { - if (NUM2LONG(num) <= 0) return INT2FIX(0); - } - else { - if (RTEST(rb_funcall(num, '<', 1, INT2FIX(0)))) return INT2FIX(0); - } - return num; -} - -/* - * call-seq: - * times {|i| ... } -> self - * times -> enumerator - * - * Calls the given block +self+ times with each integer in (0..self-1): - * - * a = [] - * 5.times {|i| a.push(i) } # => 5 - * a # => [0, 1, 2, 3, 4] - * - * With no block given, returns an Enumerator. - * - */ - -static VALUE -int_dotimes(VALUE num) -{ - RETURN_SIZED_ENUMERATOR(num, 0, 0, int_dotimes_size); - - if (FIXNUM_P(num)) { - long i, end; - - end = FIX2LONG(num); - for (i=0; i integer @@ -6243,7 +6191,6 @@ Init_Numeric(void) rb_define_method(rb_cInteger, "nobits?", int_nobits_p, 1); rb_define_method(rb_cInteger, "upto", int_upto, 1); rb_define_method(rb_cInteger, "downto", int_downto, 1); - rb_define_method(rb_cInteger, "times", int_dotimes, 0); rb_define_method(rb_cInteger, "succ", int_succ, 0); rb_define_method(rb_cInteger, "next", int_succ, 0); rb_define_method(rb_cInteger, "pred", int_pred, 0); diff --git a/numeric.rb b/numeric.rb index 806b65becd035e..3c059a58a4881f 100644 --- a/numeric.rb +++ b/numeric.rb @@ -217,6 +217,29 @@ def size Primitive.cexpr! 'rb_int_size(self)' end + # call-seq: + # times {|i| ... } -> self + # times -> enumerator + # + # Calls the given block +self+ times with each integer in (0..self-1): + # + # a = [] + # 5.times {|i| a.push(i) } # => 5 + # a # => [0, 1, 2, 3, 4] + # + # With no block given, returns an Enumerator. + def times + unless block_given? + return to_enum(:times) { self < 0 ? 0 : self } + end + i = 0 + while i < self + yield i + i = i.succ + end + self + end + # call-seq: # to_i -> self # diff --git a/test/ruby/test_backtrace.rb b/test/ruby/test_backtrace.rb index bb0562c0bb8e79..d35dead95bbab8 100644 --- a/test/ruby/test_backtrace.rb +++ b/test/ruby/test_backtrace.rb @@ -215,15 +215,15 @@ def self.foo @res = caller_locations(2, 1).inspect end @line = __LINE__ + 1 - 1.times.map { 1.times.map { foo } } - assert_equal("[\"#{__FILE__}:#{@line}:in `times'\"]", @res) + [1].map.map { [1].map.map { foo } } + assert_equal("[\"#{__FILE__}:#{@line}:in `map'\"]", @res) end def test_caller_location_path_cfunc_iseq_no_pc def self.foo @res = caller_locations(2, 1)[0].path end - 1.times.map { 1.times.map { foo } } + [1].map.map { [1].map.map { foo } } assert_equal(__FILE__, @res) end diff --git a/test/ruby/test_integer.rb b/test/ruby/test_integer.rb index 3e8d68702c0271..31cb8d6cf54d7b 100644 --- a/test/ruby/test_integer.rb +++ b/test/ruby/test_integer.rb @@ -321,23 +321,34 @@ def test_times_bignum_redefine_plus_lt begin; called = false Integer.class_eval do - alias old_plus + - undef + - define_method(:+){|x| called = true; 1} + alias old_succ succ + undef succ + define_method(:succ){|x| called = true; x+1} alias old_lt < undef < define_method(:<){|x| called = true} end + + fix = 1 + fix.times{break 0} + fix_called = called + + called = false + big = 2**65 big.times{break 0} + big_called = called + Integer.class_eval do - undef + - alias + old_plus + undef succ + alias succ old_succ undef < alias < old_lt end + + # Asssert that Fixnum and Bignum behave consistently bug18377 = "[ruby-core:106361]" - assert_equal(false, called, bug18377) + assert_equal(fix_called, big_called, bug18377) end; end diff --git a/test/ruby/test_settracefunc.rb b/test/ruby/test_settracefunc.rb index 3641bd091699d3..76891e3c973c31 100644 --- a/test/ruby/test_settracefunc.rb +++ b/test/ruby/test_settracefunc.rb @@ -504,7 +504,7 @@ def trace_by_tracepoint *trace_events 1: trace = TracePoint.trace(*trace_events){|tp| next if !target_thread? 2: events << [tp.event, tp.lineno, tp.path, _defined_class.(tp), tp.method_id, tp.self, tp.binding&.eval("_local_var"), _get_data.(tp)] if tp.path == 'xyzzy' 3: } - 4: 1.times{|;_local_var| _local_var = :inner + 4: [1].each{|;_local_var| _local_var = :inner 5: tap{} 6: } 7: class XYZZY @@ -531,10 +531,10 @@ def trace_by_tracepoint *trace_events answer_events = [ # [:line, 4, 'xyzzy', self.class, method, self, :outer, :nothing], - [:c_call, 4, 'xyzzy', Integer, :times, 1, nil, :nothing], + [:c_call, 4, 'xyzzy', Array, :each, [1], nil, :nothing], [:line, 4, 'xyzzy', self.class, method, self, nil, :nothing], [:line, 5, 'xyzzy', self.class, method, self, :inner, :nothing], - [:c_return, 4, "xyzzy", Integer, :times, 1, nil, 1], + [:c_return, 4, "xyzzy", Array, :each, [1], nil, [1]], [:line, 7, 'xyzzy', self.class, method, self, :outer, :nothing], [:c_call, 7, "xyzzy", Module, :const_added, TestSetTraceFunc, nil, :nothing], [:c_return, 7, "xyzzy", Module, :const_added, TestSetTraceFunc, nil, nil], @@ -639,7 +639,7 @@ def trace_by_set_trace_func 1: set_trace_func(lambda{|event, file, line, id, binding, klass| 2: events << [event, line, file, klass, id, binding&.eval('self'), binding&.eval("_local_var")] if file == 'xyzzy' 3: }) - 4: 1.times{|;_local_var| _local_var = :inner + 4: [1].map{|;_local_var| _local_var = :inner 5: tap{} 6: } 7: class XYZZY @@ -994,7 +994,7 @@ def test_tracepoint_block /return/ =~ tp.event ? tp.return_value : nil ] }.enable{ - 1.times{ + [1].map{ 3 } method_for_test_tracepoint_block{ @@ -1004,10 +1004,10 @@ def test_tracepoint_block # pp events # expected_events = [[:b_call, :test_tracepoint_block, TestSetTraceFunc, TestSetTraceFunc, nil], - [:c_call, :times, Integer, Integer, nil], + [:c_call, :map, Array, Array, nil], [:b_call, :test_tracepoint_block, TestSetTraceFunc, TestSetTraceFunc, nil], [:b_return, :test_tracepoint_block, TestSetTraceFunc, TestSetTraceFunc, 3], - [:c_return, :times, Integer, Integer, 1], + [:c_return, :map, Array, Array, [3]], [:call, :method_for_test_tracepoint_block, TestSetTraceFunc, TestSetTraceFunc, nil], [:b_call, :test_tracepoint_block, TestSetTraceFunc, TestSetTraceFunc, nil], [:b_return, :test_tracepoint_block, TestSetTraceFunc, TestSetTraceFunc, 4], @@ -1310,7 +1310,7 @@ def test_a_call next if !target_thread? events << tp.event }.enable{ - 1.times{ + [1].map{ 3 } method_for_test_tracepoint_block{ @@ -1332,7 +1332,7 @@ def test_a_return next if !target_thread? events << tp.event }.enable{ - 1.times{ + [1].map{ 3 } method_for_test_tracepoint_block{ From 60a52caf87c7e9ddfca73120c9d5b5030793ed77 Mon Sep 17 00:00:00 2001 From: Mike Dalessio Date: Thu, 7 Sep 2023 13:07:43 -0400 Subject: [PATCH 24/46] [ruby/yarp] Avoid an extra "stop" parameter to yp_strspn_whitespace_newlines and use yp_strspn_inline_whitespace instead. Partially reverts implementation details from #1152 https://github.com/ruby/yarp/commit/c8f9f4cfde --- yarp/util/yp_char.c | 9 ++------- yarp/util/yp_char.h | 2 +- yarp/yarp.c | 11 +++++++++-- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/yarp/util/yp_char.c b/yarp/util/yp_char.c index e9f1ef45c20997..ae0ffea6b83b38 100644 --- a/yarp/util/yp_char.c +++ b/yarp/util/yp_char.c @@ -75,7 +75,7 @@ yp_strspn_whitespace(const uint8_t *string, ptrdiff_t length) { // whitespace while also tracking the location of each newline. Disallows // searching past the given maximum number of characters. size_t -yp_strspn_whitespace_newlines(const uint8_t *string, ptrdiff_t length, yp_newline_list_t *newline_list, bool stop_at_newline) { +yp_strspn_whitespace_newlines(const uint8_t *string, ptrdiff_t length, yp_newline_list_t *newline_list) { if (length <= 0) return 0; size_t size = 0; @@ -83,12 +83,7 @@ yp_strspn_whitespace_newlines(const uint8_t *string, ptrdiff_t length, yp_newlin while (size < maximum && (yp_byte_table[string[size]] & YP_CHAR_BIT_WHITESPACE)) { if (string[size] == '\n') { - if (stop_at_newline) { - return size + 1; - } - else { - yp_newline_list_append(newline_list, string + size); - } + yp_newline_list_append(newline_list, string + size); } size++; diff --git a/yarp/util/yp_char.h b/yarp/util/yp_char.h index 67ba31d34d687a..e155b69d64d8c6 100644 --- a/yarp/util/yp_char.h +++ b/yarp/util/yp_char.h @@ -15,7 +15,7 @@ size_t yp_strspn_whitespace(const uint8_t *string, ptrdiff_t length); // whitespace while also tracking the location of each newline. Disallows // searching past the given maximum number of characters. size_t -yp_strspn_whitespace_newlines(const uint8_t *string, ptrdiff_t length, yp_newline_list_t *newline_list, bool stop_at_newline); +yp_strspn_whitespace_newlines(const uint8_t *string, ptrdiff_t length, yp_newline_list_t *newline_list); // Returns the number of characters at the start of the string that are inline // whitespace. Disallows searching past the given maximum number of characters. diff --git a/yarp/yarp.c b/yarp/yarp.c index 07ee4d8a8f163f..ba3e821e359df9 100644 --- a/yarp/yarp.c +++ b/yarp/yarp.c @@ -7045,9 +7045,16 @@ parser_lex(yp_parser_t *parser) { // going to trim it off the beginning and create a new token. size_t whitespace; - bool should_stop = parser->heredoc_end; + if (parser->heredoc_end) { + whitespace = yp_strspn_inline_whitespace(parser->current.end, parser->end - parser->current.end); + if (peek_offset(parser, (ptrdiff_t)whitespace) == '\n') { + whitespace += 1; + } + } else { + whitespace = yp_strspn_whitespace_newlines(parser->current.end, parser->end - parser->current.end, &parser->newline_list); + } - if ((whitespace = yp_strspn_whitespace_newlines(parser->current.end, parser->end - parser->current.end, &parser->newline_list, should_stop)) > 0) { + if (whitespace > 0) { parser->current.end += whitespace; if (peek_offset(parser, -1) == '\n') { // mutates next_start From fcdedf7f47b0ec495a0e3adca4c3f44b84afa98e Mon Sep 17 00:00:00 2001 From: Takashi Kokubun Date: Thu, 7 Sep 2023 11:22:34 -0700 Subject: [PATCH 25/46] YJIT: Decrease SEND_MAX_DEPTH to 5 (#8390) --- yjit/src/codegen.rs | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs index a99594c3abd8d3..a32657beeb5359 100644 --- a/yjit/src/codegen.rs +++ b/yjit/src/codegen.rs @@ -2035,10 +2035,10 @@ fn jit_chain_guard( } } -// up to 5 different classes, and embedded or not for each +// up to 10 different classes, and embedded or not for each pub const GET_IVAR_MAX_DEPTH: i32 = 10; -// up to 5 different classes, and embedded or not for each +// up to 10 different classes, and embedded or not for each pub const SET_IVAR_MAX_DEPTH: i32 = 10; // hashes and arrays @@ -2047,11 +2047,8 @@ pub const OPT_AREF_MAX_CHAIN_DEPTH: i32 = 2; // expandarray pub const EXPANDARRAY_MAX_CHAIN_DEPTH: i32 = 4; -// up to 10 different classes -pub const SEND_MAX_DEPTH: i32 = 20; - -// up to 20 different methods for send -pub const SEND_MAX_CHAIN_DEPTH: i32 = 20; +// up to 5 different methods for send +pub const SEND_MAX_DEPTH: i32 = 5; // up to 20 different offsets for case-when pub const CASE_WHEN_MAX_DEPTH: i32 = 20; @@ -4385,7 +4382,7 @@ fn jit_rb_kernel_instance_of( jit, asm, ocb, - SEND_MAX_CHAIN_DEPTH, + SEND_MAX_DEPTH, Counter::guard_send_instance_of_class_mismatch, ); @@ -4986,7 +4983,7 @@ fn jit_obj_respond_to( jit, asm, ocb, - SEND_MAX_CHAIN_DEPTH, + SEND_MAX_DEPTH, Counter::guard_send_respond_to_mid_mismatch, ); @@ -6038,7 +6035,7 @@ fn gen_send_iseq( jit, asm, ocb, - SEND_MAX_CHAIN_DEPTH, + SEND_MAX_DEPTH, Counter::guard_send_block_arg_type, ); @@ -7186,7 +7183,7 @@ fn gen_send_general( jit, asm, ocb, - SEND_MAX_CHAIN_DEPTH, + SEND_MAX_DEPTH, Counter::guard_send_send_chain, ); @@ -7428,7 +7425,7 @@ fn gen_invokeblock_specialized( } // Fallback to dynamic dispatch if this callsite is megamorphic - if asm.ctx.get_chain_depth() as i32 >= SEND_MAX_CHAIN_DEPTH { + if asm.ctx.get_chain_depth() as i32 >= SEND_MAX_DEPTH { gen_counter_incr(asm, Counter::invokeblock_megamorphic); return None; } @@ -7462,7 +7459,7 @@ fn gen_invokeblock_specialized( jit, asm, ocb, - SEND_MAX_CHAIN_DEPTH, + SEND_MAX_DEPTH, Counter::guard_invokeblock_tag_changed, ); @@ -7478,7 +7475,7 @@ fn gen_invokeblock_specialized( jit, asm, ocb, - SEND_MAX_CHAIN_DEPTH, + SEND_MAX_DEPTH, Counter::guard_invokeblock_iseq_block_changed, ); @@ -7521,7 +7518,7 @@ fn gen_invokeblock_specialized( jit, asm, ocb, - SEND_MAX_CHAIN_DEPTH, + SEND_MAX_DEPTH, Counter::guard_invokeblock_tag_changed, ); @@ -7602,7 +7599,7 @@ fn gen_invokesuper_specialized( }; // Fallback to dynamic dispatch if this callsite is megamorphic - if asm.ctx.get_chain_depth() as i32 >= SEND_MAX_CHAIN_DEPTH { + if asm.ctx.get_chain_depth() as i32 >= SEND_MAX_DEPTH { gen_counter_incr(asm, Counter::invokesuper_megamorphic); return None; } @@ -7686,7 +7683,7 @@ fn gen_invokesuper_specialized( jit, asm, ocb, - SEND_MAX_CHAIN_DEPTH, + SEND_MAX_DEPTH, Counter::guard_invokesuper_me_changed, ); From ed712e0e9d591bdaa84e9eaac832a9632aee5139 Mon Sep 17 00:00:00 2001 From: Matthew Draper Date: Thu, 24 Aug 2023 16:27:17 +0930 Subject: [PATCH 26/46] Skip allocation if handle_interrupt arg is already usable If the supplied hash is already frozen and compare-by-identity, we can use it directly (still checking its contents are valid symbols), without making a new copy. --- thread.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/thread.c b/thread.c index 4073325b9d890f..80a097f6f42545 100644 --- a/thread.c +++ b/thread.c @@ -2018,10 +2018,12 @@ handle_interrupt_arg_check_i(VALUE key, VALUE val, VALUE args) rb_raise(rb_eArgError, "unknown mask signature"); } - if (!*maskp) { - *maskp = rb_ident_hash_new(); + if (maskp) { + if (!*maskp) { + *maskp = rb_ident_hash_new(); + } + rb_hash_aset(*maskp, key, val); } - rb_hash_aset(*maskp, key, val); return ST_CONTINUE; } @@ -2147,13 +2149,20 @@ rb_thread_s_handle_interrupt(VALUE self, VALUE mask_arg) rb_raise(rb_eArgError, "block is needed."); } - mask = 0; mask_arg = rb_to_hash_type(mask_arg); - rb_hash_foreach(mask_arg, handle_interrupt_arg_check_i, (VALUE)&mask); - if (!mask) { - return rb_yield(Qnil); + + if (OBJ_FROZEN(mask_arg) && rb_hash_compare_by_id_p(mask_arg)) { + rb_hash_foreach(mask_arg, handle_interrupt_arg_check_i, 0); + mask = mask_arg; + } else { + mask = 0; + rb_hash_foreach(mask_arg, handle_interrupt_arg_check_i, (VALUE)&mask); + if (!mask) { + return rb_yield(Qnil); + } + OBJ_FREEZE_RAW(mask); } - OBJ_FREEZE_RAW(mask); + rb_ary_push(th->pending_interrupt_mask_stack, mask); if (!rb_threadptr_pending_interrupt_empty_p(th)) { th->pending_interrupt_queue_checked = 0; From aed52151043561dbe9657abd07f1abfcd97df817 Mon Sep 17 00:00:00 2001 From: Matthew Draper Date: Thu, 24 Aug 2023 17:53:23 +0930 Subject: [PATCH 27/46] Optimize handle_interrupt(Exception => ..) as a common case When interrupt behavior is configured for all possible exceptions using 'Exception', there's no need to iterate the pending exception's ancestors for hash lookups. More significantly, by storing the catch-all timing symbol directly in the mask stack, we can skip allocating the hash we would otherwise need. --- thread.c | 77 ++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 55 insertions(+), 22 deletions(-) diff --git a/thread.c b/thread.c index 80a097f6f42545..7654fc03a45b48 100644 --- a/thread.c +++ b/thread.c @@ -1891,6 +1891,23 @@ enum handle_interrupt_timing { INTERRUPT_NEVER }; +static enum handle_interrupt_timing +rb_threadptr_pending_interrupt_from_symbol(rb_thread_t *th, VALUE sym) +{ + if (sym == sym_immediate) { + return INTERRUPT_IMMEDIATE; + } + else if (sym == sym_on_blocking) { + return INTERRUPT_ON_BLOCKING; + } + else if (sym == sym_never) { + return INTERRUPT_NEVER; + } + else { + rb_raise(rb_eThreadError, "unknown mask signature"); + } +} + static enum handle_interrupt_timing rb_threadptr_pending_interrupt_check_mask(rb_thread_t *th, VALUE err) { @@ -1903,6 +1920,16 @@ rb_threadptr_pending_interrupt_check_mask(rb_thread_t *th, VALUE err) for (i=0; i Date: Sun, 3 Sep 2023 17:02:57 -0700 Subject: [PATCH 28/46] GC: Only force alloc slowpath for NEWOBJ hook Previously, configuring any GC event hook would cause all allocations to go through the newobj slowpath. We should only need to do that when the newobj specifically is subscribed to. This renames flags.has_hook to flags.has_newobj_hook, to make this new usage clear. newobj_of0 was the only place which previously checked this flag. --- gc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/gc.c b/gc.c index c71fdd10ed91ca..d2cce59aaca2fc 100644 --- a/gc.c +++ b/gc.c @@ -747,7 +747,7 @@ typedef struct rb_objspace { unsigned int during_compacting : 1; unsigned int during_reference_updating : 1; unsigned int gc_stressful: 1; - unsigned int has_hook: 1; + unsigned int has_newobj_hook: 1; unsigned int during_minor_gc : 1; unsigned int during_incremental_marking : 1; unsigned int measure_gc : 1; @@ -2466,7 +2466,7 @@ rb_objspace_set_event_hook(const rb_event_flag_t event) { rb_objspace_t *objspace = &rb_objspace; objspace->hook_events = event & RUBY_INTERNAL_EVENT_OBJSPACE_MASK; - objspace->flags.has_hook = (objspace->hook_events != 0); + objspace->flags.has_newobj_hook = !!(objspace->hook_events & RUBY_INTERNAL_EVENT_NEWOBJ); } static void @@ -2476,7 +2476,7 @@ gc_event_hook_body(rb_execution_context_t *ec, rb_objspace_t *objspace, const rb EXEC_EVENT_HOOK(ec, event, ec->cfp->self, 0, 0, 0, data); } -#define gc_event_hook_available_p(objspace) ((objspace)->flags.has_hook) +#define gc_event_newobj_hook_needed_p(objspace) ((objspace)->flags.has_newobj_hook) #define gc_event_hook_needed_p(objspace, event) ((objspace)->hook_events & (event)) #define gc_event_hook_prep(objspace, event, data, prep) do { \ @@ -2836,7 +2836,7 @@ newobj_of0(VALUE klass, VALUE flags, int wb_protected, rb_ractor_t *cr, size_t a if (!UNLIKELY(during_gc || ruby_gc_stressful || - gc_event_hook_available_p(objspace)) && + gc_event_newobj_hook_needed_p(objspace)) && wb_protected) { obj = newobj_alloc(objspace, cr, size_pool_idx, false); newobj_init(klass, flags, wb_protected, objspace, obj); From 89edce432115c1bb46b2de0f4cd1e50c6e02ec41 Mon Sep 17 00:00:00 2001 From: Takashi Kokubun Date: Thu, 7 Sep 2023 20:15:08 -0700 Subject: [PATCH 29/46] YJIT: Decrease IVAR_MAX_DEPTH to 8 (#8398) --- yjit/src/codegen.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs index a32657beeb5359..e00c1788c38497 100644 --- a/yjit/src/codegen.rs +++ b/yjit/src/codegen.rs @@ -2035,11 +2035,11 @@ fn jit_chain_guard( } } -// up to 10 different classes, and embedded or not for each -pub const GET_IVAR_MAX_DEPTH: i32 = 10; +// up to 8 different shapes for each +pub const GET_IVAR_MAX_DEPTH: i32 = 8; -// up to 10 different classes, and embedded or not for each -pub const SET_IVAR_MAX_DEPTH: i32 = 10; +// up to 8 different shapes for each +pub const SET_IVAR_MAX_DEPTH: i32 = 8; // hashes and arrays pub const OPT_AREF_MAX_CHAIN_DEPTH: i32 = 2; From 78233e83529d7e3aee030cc6760f45104247fe51 Mon Sep 17 00:00:00 2001 From: Ian Candy Date: Thu, 7 Sep 2023 23:15:24 -0400 Subject: [PATCH 30/46] Add `String#getbyte` YJIT implementation (#8397) * Add getbyte JIT implementation Adds an implementation for String#getbyte for YJIT, along with a bootstrap test. This should be helpful for pure Ruby implementations and to avoid unneeded allocations. Co-authored-by: John Hawthorn * Skip the getbyte test for RJIT for now --------- Co-authored-by: John Hawthorn Co-authored-by: Takashi Kokubun --- bootstraptest/test_yjit.rb | 18 ++++++++++++++++++ yjit/src/codegen.rs | 29 +++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/bootstraptest/test_yjit.rb b/bootstraptest/test_yjit.rb index 3c53641f91e2fb..82fd1e13766c6b 100644 --- a/bootstraptest/test_yjit.rb +++ b/bootstraptest/test_yjit.rb @@ -1832,6 +1832,24 @@ def jittable_method jittable_method } +# test getbyte on string class +assert_equal '[97, :nil, 97, :nil, :raised]', %q{ + def getbyte(s, i) + byte = begin + s.getbyte(i) + rescue TypeError + :raised + end + + byte || :nil + end + + getbyte("a", 0) + getbyte("a", 0) + + [getbyte("a", 0), getbyte("a", 1), getbyte("a", -1), getbyte("a", -2), getbyte("a", "a")] +} unless defined?(RubyVM::RJIT) && RubyVM::RJIT.enabled? # Not yet working on RJIT + # Test << operator on string subclass assert_equal 'abab', %q{ class MyString < String; end diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs index e00c1788c38497..69b1c52c9ca739 100644 --- a/yjit/src/codegen.rs +++ b/yjit/src/codegen.rs @@ -4713,6 +4713,34 @@ fn jit_rb_str_bytesize( true } +fn jit_rb_str_getbyte( + jit: &mut JITState, + asm: &mut Assembler, + _ocb: &mut OutlinedCb, + _ci: *const rb_callinfo, + _cme: *const rb_callable_method_entry_t, + _block: Option, + _argc: i32, + _known_recv_class: *const VALUE, +) -> bool { + asm.comment("String#getbyte"); + extern "C" { + fn rb_str_getbyte(str: VALUE, index: VALUE) -> VALUE; + } + // Raises when non-integers are passed in + jit_prepare_routine_call(jit, asm); + + let index = asm.stack_pop(1); + let recv = asm.stack_pop(1); + let ret_opnd = asm.ccall(rb_str_getbyte as *const u8, vec![recv, index]); + + // Can either return a FIXNUM or nil + let out_opnd = asm.stack_push(Type::UnknownImm); + asm.mov(out_opnd, ret_opnd); + + true +} + // Codegen for rb_str_to_s() // When String#to_s is called on a String instance, the method returns self and // most of the overhead comes from setting up the method call. We observed that @@ -8758,6 +8786,7 @@ impl CodegenGlobals { self.yjit_reg_method(rb_cString, "to_s", jit_rb_str_to_s); self.yjit_reg_method(rb_cString, "to_str", jit_rb_str_to_s); self.yjit_reg_method(rb_cString, "bytesize", jit_rb_str_bytesize); + self.yjit_reg_method(rb_cString, "getbyte", jit_rb_str_getbyte); self.yjit_reg_method(rb_cString, "<<", jit_rb_str_concat); self.yjit_reg_method(rb_cString, "+@", jit_rb_str_uplus); From b6df6f911c6745a1e57a1d5dd7bc1c22a57722a8 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Fri, 8 Sep 2023 12:22:55 +0900 Subject: [PATCH 31/46] Continue even if addr or rnglists headers not found Fix up commit 31d1226, "Avoid aborting inside addr2line.c". Source code informations did not appear in C level backtrace since that change. --- addr2line.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addr2line.c b/addr2line.c index 358eccc5fc841f..7956cc457aace3 100644 --- a/addr2line.c +++ b/addr2line.c @@ -1496,7 +1496,7 @@ addr_header_init(obj_info_t *obj, addr_header_t *header) { header->ptr = p; - if (!p) return false; + if (!p) return true; header->unit_length = *(uint32_t *)p; p += sizeof(uint32_t); @@ -1539,7 +1539,7 @@ static bool rnglists_header_init(obj_info_t *obj, rnglists_header_t *header) { const char *p = obj->debug_rnglists.ptr; - if (!p) return false; + if (!p) return true; header->unit_length = *(uint32_t *)p; p += sizeof(uint32_t); From 15fd897629cc8743a468dfae55c06f4d70150f1e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 8 Sep 2023 02:42:32 +0000 Subject: [PATCH 32/46] Bump actions/cache from 3.3.1 to 3.3.2 Bumps [actions/cache](https://github.com/actions/cache) from 3.3.1 to 3.3.2. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8...704facf57e6136b1bc63b828d79edcd491f0ee84) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/windows.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 71209a5c9c48a3..b686cea295eac1 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -82,7 +82,7 @@ jobs: ${{ steps.find-patch.outputs.needs }} if: ${{ steps.find-patch.outputs.needs != '' }} - - uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3.3.1 + - uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84 # v3.3.2 with: path: C:\vcpkg\downloads key: ${{ runner.os }}-vcpkg-download-${{ env.OS_VER }}-${{ github.sha }} @@ -90,7 +90,7 @@ jobs: ${{ runner.os }}-vcpkg-download-${{ env.OS_VER }}- ${{ runner.os }}-vcpkg-download- - - uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 # v3.3.1 + - uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84 # v3.3.2 with: path: C:\vcpkg\installed key: ${{ runner.os }}-vcpkg-installed-${{ env.OS_VER }}-${{ github.sha }} From be21a056d229652ae5cf6926e96c1517aa43453f Mon Sep 17 00:00:00 2001 From: Samuel Williams Date: Fri, 8 Sep 2023 20:44:46 +1200 Subject: [PATCH 33/46] Try default `gcc` 9.4.0 to see if it exhibits the same compiler bugs. (#8394) * Revert "Extract `do_mutex_lock_check_interrupts` to try and fix `ppc64le`. (#8393)" This reverts commit 5184b40dd4dc446660cd35c3e53896324e95b317. * .travis.yml: Try default gcc 9.4.0 instead of gcc-10 in ppc64le and s390x. Use gcc 9.4.0 instead of gcc-10 to avoid the current failures by a possible GCC 10 compiler bug in the Travis ppc64le and s390x cases. And it also aligns with RubyCI Ubuntu ppc64le and s390x where the default gcc is used. --------- Co-authored-by: Jun Aruga --- .travis.yml | 4 ++-- thread_sync.c | 32 +++++++++----------------------- 2 files changed, 11 insertions(+), 25 deletions(-) diff --git a/.travis.yml b/.travis.yml index c6054ae6723a46..11ae8a9b4567f7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -82,12 +82,12 @@ env: - &ppc64le-linux name: ppc64le-linux arch: ppc64le - <<: *gcc-10 + compiler: gcc - &s390x-linux name: s390x-linux arch: s390x - <<: *gcc-10 + compiler: gcc - &arm32-linux name: arm32-linux diff --git a/thread_sync.c b/thread_sync.c index 63f0228d9d1a7b..85ebec4d8cfc3d 100644 --- a/thread_sync.c +++ b/thread_sync.c @@ -290,28 +290,6 @@ delete_from_waitq(VALUE value) return Qnil; } -static void -do_mutex_lock_check_interrupts(int interruptible_p, rb_fiber_t *fiber, rb_mutex_t *mutex, rb_thread_t *thread) -{ - // We extracted this function because we suspect there can be a codegen bug - // on ppc64le and moving this code to a separate function seems to fix the - // problem, at least in my tests. - if (interruptible_p) { - /* release mutex before checking for interrupts...as interrupt checking - * code might call rb_raise() */ - if (mutex->fiber == fiber) { - mutex->fiber = 0; - } - - RUBY_VM_CHECK_INTS_BLOCKING(thread->ec); /* may release mutex */ - - if (!mutex->fiber) { - mutex->fiber = fiber; - } - } -} - - static VALUE do_mutex_lock(VALUE self, int interruptible_p) { @@ -400,7 +378,15 @@ do_mutex_lock(VALUE self, int interruptible_p) rb_ractor_sleeper_threads_dec(th->ractor); } - do_mutex_lock_check_interrupts(interruptible_p, fiber, mutex, th); + if (interruptible_p) { + /* release mutex before checking for interrupts...as interrupt checking + * code might call rb_raise() */ + if (mutex->fiber == fiber) mutex->fiber = 0; + RUBY_VM_CHECK_INTS_BLOCKING(th->ec); /* may release mutex */ + if (!mutex->fiber) { + mutex->fiber = fiber; + } + } } if (mutex->fiber == fiber) mutex_locked(th, self); From f39b576e76b493b3fc5a9280295855fd8c9fb480 Mon Sep 17 00:00:00 2001 From: Kevin Newton Date: Thu, 7 Sep 2023 13:00:45 -0400 Subject: [PATCH 34/46] [ruby/yarp] Multi target nodes https://github.com/ruby/yarp/commit/fa53fe88e4 --- test/yarp/location_test.rb | 19 +- test/yarp/snapshots/arrays.txt | 82 ++-- test/yarp/snapshots/for.txt | 24 +- test/yarp/snapshots/method_calls.txt | 74 ++-- .../seattlerb/masgn_anon_splat_arg.txt | 18 +- .../seattlerb/masgn_arg_colon_arg.txt | 32 +- .../snapshots/seattlerb/masgn_arg_ident.txt | 32 +- .../seattlerb/masgn_arg_splat_arg.txt | 14 +- .../yarp/snapshots/seattlerb/masgn_colon2.txt | 20 +- .../yarp/snapshots/seattlerb/masgn_colon3.txt | 28 +- .../seattlerb/masgn_command_call.txt | 11 +- .../seattlerb/masgn_double_paren.txt | 28 +- .../snapshots/seattlerb/masgn_lhs_splat.txt | 10 +- test/yarp/snapshots/seattlerb/masgn_paren.txt | 12 +- .../snapshots/seattlerb/masgn_splat_arg.txt | 22 +- .../seattlerb/masgn_splat_arg_arg.txt | 24 +- test/yarp/snapshots/seattlerb/masgn_star.txt | 6 +- .../seattlerb/masgn_var_star_var.txt | 14 +- .../seattlerb/mlhs_back_anonsplat.txt | 16 +- .../snapshots/seattlerb/mlhs_back_splat.txt | 19 +- .../seattlerb/mlhs_front_anonsplat.txt | 22 +- .../snapshots/seattlerb/mlhs_front_splat.txt | 26 +- .../seattlerb/mlhs_mid_anonsplat.txt | 22 +- .../snapshots/seattlerb/mlhs_mid_splat.txt | 22 +- test/yarp/snapshots/seattlerb/mlhs_rescue.txt | 12 +- .../snapshots/seattlerb/parse_line_to_ary.txt | 12 +- .../unparser/corpus/literal/assignment.txt | 394 ++++++++++-------- .../unparser/corpus/literal/defined.txt | 12 +- .../snapshots/unparser/corpus/literal/for.txt | 16 +- .../unparser/corpus/literal/send.txt | 12 +- test/yarp/snapshots/variables.txt | 102 +++-- .../snapshots/whitequark/and_or_masgn.txt | 24 +- .../snapshots/whitequark/cond_begin_masgn.txt | 12 +- test/yarp/snapshots/whitequark/for.txt | 8 +- test/yarp/snapshots/whitequark/for_mlhs.txt | 4 +- .../snapshots/whitequark/if_masgn__24.txt | 12 +- test/yarp/snapshots/whitequark/masgn.txt | 38 +- test/yarp/snapshots/whitequark/masgn_attr.txt | 118 +++--- test/yarp/snapshots/whitequark/masgn_cmd.txt | 12 +- .../yarp/snapshots/whitequark/masgn_const.txt | 40 +- .../snapshots/whitequark/masgn_nested.txt | 52 +-- .../yarp/snapshots/whitequark/masgn_splat.txt | 178 ++++---- .../snapshots/whitequark/not_masgn__24.txt | 12 +- .../snapshots/whitequark/rescue_mod_masgn.txt | 12 +- yarp/config.yml | 20 +- yarp/yarp.c | 169 ++++---- 46 files changed, 970 insertions(+), 898 deletions(-) diff --git a/test/yarp/location_test.rb b/test/yarp/location_test.rb index d86afb0b3bb1a4..386177122da92e 100644 --- a/test/yarp/location_test.rb +++ b/test/yarp/location_test.rb @@ -223,7 +223,7 @@ def test_ClassVariableReadNode def test_ClassVariableTargetNode assert_location(ClassVariableTargetNode, "@@foo, @@bar = baz", 0...5) do |node| - node.targets.first + node.target.targets.first end end @@ -251,7 +251,7 @@ def test_ConstantPathOrWriteNode def test_ConstantPathTargetNode assert_location(ConstantPathTargetNode, "::Foo, ::Bar = baz", 0...5) do |node| - node.targets.first + node.target.targets.first end end @@ -280,7 +280,7 @@ def test_ConstantReadNode def test_ConstantTargetNode assert_location(ConstantTargetNode, "Foo, Bar = baz", 0...3) do |node| - node.targets.first + node.target.targets.first end end @@ -378,7 +378,7 @@ def test_GlobalVariableReadNode def test_GlobalVariableTargetNode assert_location(GlobalVariableTargetNode, "$foo, $bar = baz", 0...4) do |node| - node.targets.first + node.target.targets.first end end @@ -430,7 +430,7 @@ def test_InstanceVariableReadNode def test_InstanceVariableTargetNode assert_location(InstanceVariableTargetNode, "@foo, @bar = baz", 0...4) do |node| - node.targets.first + node.target.targets.first end end @@ -517,7 +517,7 @@ def test_LocalVariableReadNode def test_LocalVariableTargetNode assert_location(LocalVariableTargetNode, "foo, bar = baz", 0...3) do |node| - node.targets.first + node.target.targets.first end end @@ -537,6 +537,11 @@ def test_ModuleNode assert_location(ModuleNode, "module Foo end") end + def test_MultiTargetNode + assert_location(MultiTargetNode, "for foo, bar in baz do end", 4...12, &:index) + assert_location(MultiTargetNode, "foo, bar = baz", 0...8, &:target) + end + def test_MultiWriteNode assert_location(MultiWriteNode, "foo, bar = baz") end @@ -690,7 +695,7 @@ def test_SourceLineNode end def test_SplatNode - assert_location(SplatNode, "*foo = bar", 0...4) { |node| node.targets.first } + assert_location(SplatNode, "*foo = bar", 0...4) { |node| node.target.targets.first } end def test_StatementsNode diff --git a/test/yarp/snapshots/arrays.txt b/test/yarp/snapshots/arrays.txt index ec251f0827757d..b8f87295b45fb4 100644 --- a/test/yarp/snapshots/arrays.txt +++ b/test/yarp/snapshots/arrays.txt @@ -317,56 +317,58 @@ ProgramNode(0...511)( "[]=" ), MultiWriteNode(191...212)( - [CallNode(191...197)( - CallNode(191...194)( - nil, - nil, - (191...194), - nil, - nil, + MultiTargetNode(191...205)( + [CallNode(191...197)( + CallNode(191...194)( + nil, + nil, + (191...194), + nil, + nil, + nil, + nil, + 2, + "foo" + ), nil, + (194...197), + (194...195), + ArgumentsNode(195...196)([IntegerNode(195...196)()]), + (196...197), nil, - 2, - "foo" + 0, + "[]=" ), - nil, - (194...197), - (194...195), - ArgumentsNode(195...196)([IntegerNode(195...196)()]), - (196...197), - nil, - 0, - "[]=" - ), - CallNode(199...205)( - CallNode(199...202)( - nil, - nil, - (199...202), - nil, - nil, + CallNode(199...205)( + CallNode(199...202)( + nil, + nil, + (199...202), + nil, + nil, + nil, + nil, + 2, + "bar" + ), nil, + (202...205), + (202...203), + ArgumentsNode(203...204)([IntegerNode(203...204)()]), + (204...205), nil, - 2, - "bar" - ), - nil, - (202...205), - (202...203), - ArgumentsNode(203...204)([IntegerNode(203...204)()]), - (204...205), - nil, - 0, - "[]=" - )], + 0, + "[]=" + )], + nil, + nil + ), (206...207), ArrayNode(208...212)( [IntegerNode(208...209)(), IntegerNode(211...212)()], nil, nil - ), - nil, - nil + ) ), CallNode(214...233)( CallNode(214...217)( diff --git a/test/yarp/snapshots/for.txt b/test/yarp/snapshots/for.txt index 53eb1caf581484..77f85312e389b9 100644 --- a/test/yarp/snapshots/for.txt +++ b/test/yarp/snapshots/for.txt @@ -2,11 +2,9 @@ ProgramNode(0...143)( [:i, :j, :k], StatementsNode(0...143)( [ForNode(0...20)( - MultiWriteNode(4...5)( + MultiTargetNode(4...5)( [LocalVariableTargetNode(4...5)(:i, 0)], nil, - nil, - nil, nil ), RangeNode(9...14)( @@ -22,11 +20,9 @@ ProgramNode(0...143)( (17...20) ), ForNode(22...44)( - MultiWriteNode(26...27)( + MultiTargetNode(26...27)( [LocalVariableTargetNode(26...27)(:i, 0)], nil, - nil, - nil, nil ), RangeNode(31...36)( @@ -42,12 +38,10 @@ ProgramNode(0...143)( (41...44) ), ForNode(46...68)( - MultiWriteNode(50...53)( + MultiTargetNode(50...53)( [LocalVariableTargetNode(50...51)(:i, 0), LocalVariableTargetNode(52...53)(:j, 0)], nil, - nil, - nil, nil ), RangeNode(57...62)( @@ -63,13 +57,11 @@ ProgramNode(0...143)( (65...68) ), ForNode(70...94)( - MultiWriteNode(74...79)( + MultiTargetNode(74...79)( [LocalVariableTargetNode(74...75)(:i, 0), LocalVariableTargetNode(76...77)(:j, 0), LocalVariableTargetNode(78...79)(:k, 0)], nil, - nil, - nil, nil ), RangeNode(83...88)( @@ -85,11 +77,9 @@ ProgramNode(0...143)( (91...94) ), ForNode(96...119)( - MultiWriteNode(100...101)( + MultiTargetNode(100...101)( [LocalVariableTargetNode(100...101)(:i, 0)], nil, - nil, - nil, nil ), RangeNode(105...110)( @@ -105,11 +95,9 @@ ProgramNode(0...143)( (116...119) ), ForNode(121...143)( - MultiWriteNode(125...126)( + MultiTargetNode(125...126)( [LocalVariableTargetNode(125...126)(:i, 0)], nil, - nil, - nil, nil ), RangeNode(130...135)( diff --git a/test/yarp/snapshots/method_calls.txt b/test/yarp/snapshots/method_calls.txt index 6cec125ec12abb..7ab43d0a844ed7 100644 --- a/test/yarp/snapshots/method_calls.txt +++ b/test/yarp/snapshots/method_calls.txt @@ -348,56 +348,58 @@ ProgramNode(0...1237)( "b" ), MultiWriteNode(181...204)( - [CallNode(181...188)( - CallNode(181...184)( - nil, - nil, - (181...184), + MultiTargetNode(181...197)( + [CallNode(181...188)( + CallNode(181...184)( + nil, + nil, + (181...184), + nil, + nil, + nil, + nil, + 2, + "foo" + ), + (184...185), + (185...188), nil, nil, nil, nil, - 2, - "foo" + 0, + "foo=" ), - (184...185), - (185...188), - nil, - nil, - nil, - nil, - 0, - "foo=" - ), - CallNode(190...197)( - CallNode(190...193)( - nil, - nil, - (190...193), + CallNode(190...197)( + CallNode(190...193)( + nil, + nil, + (190...193), + nil, + nil, + nil, + nil, + 2, + "bar" + ), + (193...194), + (194...197), nil, nil, nil, nil, - 2, - "bar" - ), - (193...194), - (194...197), - nil, - nil, - nil, - nil, - 0, - "bar=" - )], + 0, + "bar=" + )], + nil, + nil + ), (198...199), ArrayNode(200...204)( [IntegerNode(200...201)(), IntegerNode(203...204)()], nil, nil - ), - nil, - nil + ) ), CallNode(206...210)( CallNode(206...207)(nil, nil, (206...207), nil, nil, nil, nil, 2, "a"), diff --git a/test/yarp/snapshots/seattlerb/masgn_anon_splat_arg.txt b/test/yarp/snapshots/seattlerb/masgn_anon_splat_arg.txt index c57ea8778fa388..e52928eb916264 100644 --- a/test/yarp/snapshots/seattlerb/masgn_anon_splat_arg.txt +++ b/test/yarp/snapshots/seattlerb/masgn_anon_splat_arg.txt @@ -2,18 +2,14 @@ ProgramNode(0...8)( [:a], StatementsNode(0...8)( [MultiWriteNode(0...8)( - [MultiWriteNode(0...1)( - [SplatNode(0...1)((0...1), nil)], - nil, - nil, - nil, - nil - ), - LocalVariableTargetNode(3...4)(:a, 0)], + MultiTargetNode(0...4)( + [MultiTargetNode(0...1)([SplatNode(0...1)((0...1), nil)], nil, nil), + LocalVariableTargetNode(3...4)(:a, 0)], + nil, + nil + ), (5...6), - CallNode(7...8)(nil, nil, (7...8), nil, nil, nil, nil, 2, "b"), - nil, - nil + CallNode(7...8)(nil, nil, (7...8), nil, nil, nil, nil, 2, "b") )] ) ) diff --git a/test/yarp/snapshots/seattlerb/masgn_arg_colon_arg.txt b/test/yarp/snapshots/seattlerb/masgn_arg_colon_arg.txt index 1a8275332e534b..a13a84f116dd8f 100644 --- a/test/yarp/snapshots/seattlerb/masgn_arg_colon_arg.txt +++ b/test/yarp/snapshots/seattlerb/masgn_arg_colon_arg.txt @@ -2,22 +2,24 @@ ProgramNode(0...11)( [:a], StatementsNode(0...11)( [MultiWriteNode(0...11)( - [LocalVariableTargetNode(0...1)(:a, 0), - CallNode(3...7)( - CallNode(3...4)(nil, nil, (3...4), nil, nil, nil, nil, 2, "b"), - (4...6), - (6...7), - nil, - nil, - nil, - nil, - 0, - "c=" - )], + MultiTargetNode(0...7)( + [LocalVariableTargetNode(0...1)(:a, 0), + CallNode(3...7)( + CallNode(3...4)(nil, nil, (3...4), nil, nil, nil, nil, 2, "b"), + (4...6), + (6...7), + nil, + nil, + nil, + nil, + 0, + "c=" + )], + nil, + nil + ), (8...9), - CallNode(10...11)(nil, nil, (10...11), nil, nil, nil, nil, 2, "d"), - nil, - nil + CallNode(10...11)(nil, nil, (10...11), nil, nil, nil, nil, 2, "d") )] ) ) diff --git a/test/yarp/snapshots/seattlerb/masgn_arg_ident.txt b/test/yarp/snapshots/seattlerb/masgn_arg_ident.txt index da590680c034a3..53d5be38d60df4 100644 --- a/test/yarp/snapshots/seattlerb/masgn_arg_ident.txt +++ b/test/yarp/snapshots/seattlerb/masgn_arg_ident.txt @@ -2,22 +2,24 @@ ProgramNode(0...10)( [:a], StatementsNode(0...10)( [MultiWriteNode(0...10)( - [LocalVariableTargetNode(0...1)(:a, 0), - CallNode(3...6)( - CallNode(3...4)(nil, nil, (3...4), nil, nil, nil, nil, 2, "b"), - (4...5), - (5...6), - nil, - nil, - nil, - nil, - 0, - "C=" - )], + MultiTargetNode(0...6)( + [LocalVariableTargetNode(0...1)(:a, 0), + CallNode(3...6)( + CallNode(3...4)(nil, nil, (3...4), nil, nil, nil, nil, 2, "b"), + (4...5), + (5...6), + nil, + nil, + nil, + nil, + 0, + "C=" + )], + nil, + nil + ), (7...8), - CallNode(9...10)(nil, nil, (9...10), nil, nil, nil, nil, 2, "d"), - nil, - nil + CallNode(9...10)(nil, nil, (9...10), nil, nil, nil, nil, 2, "d") )] ) ) diff --git a/test/yarp/snapshots/seattlerb/masgn_arg_splat_arg.txt b/test/yarp/snapshots/seattlerb/masgn_arg_splat_arg.txt index c22781a5d01f29..52fd5f6317b940 100644 --- a/test/yarp/snapshots/seattlerb/masgn_arg_splat_arg.txt +++ b/test/yarp/snapshots/seattlerb/masgn_arg_splat_arg.txt @@ -2,13 +2,15 @@ ProgramNode(0...12)( [:a, :b, :c], StatementsNode(0...12)( [MultiWriteNode(0...12)( - [LocalVariableTargetNode(0...1)(:a, 0), - SplatNode(3...5)((3...4), LocalVariableTargetNode(4...5)(:b, 0)), - LocalVariableTargetNode(7...8)(:c, 0)], + MultiTargetNode(0...8)( + [LocalVariableTargetNode(0...1)(:a, 0), + SplatNode(3...5)((3...4), LocalVariableTargetNode(4...5)(:b, 0)), + LocalVariableTargetNode(7...8)(:c, 0)], + nil, + nil + ), (9...10), - CallNode(11...12)(nil, nil, (11...12), nil, nil, nil, nil, 2, "d"), - nil, - nil + CallNode(11...12)(nil, nil, (11...12), nil, nil, nil, nil, 2, "d") )] ) ) diff --git a/test/yarp/snapshots/seattlerb/masgn_colon2.txt b/test/yarp/snapshots/seattlerb/masgn_colon2.txt index cf85e7d1ed0540..d2eca1dc3235b1 100644 --- a/test/yarp/snapshots/seattlerb/masgn_colon2.txt +++ b/test/yarp/snapshots/seattlerb/masgn_colon2.txt @@ -2,20 +2,22 @@ ProgramNode(0...14)( [:a], StatementsNode(0...14)( [MultiWriteNode(0...14)( - [LocalVariableTargetNode(0...1)(:a, 0), - ConstantPathTargetNode(3...7)( - CallNode(3...4)(nil, nil, (3...4), nil, nil, nil, nil, 2, "b"), - ConstantReadNode(6...7)(:C), - (4...6) - )], + MultiTargetNode(0...7)( + [LocalVariableTargetNode(0...1)(:a, 0), + ConstantPathTargetNode(3...7)( + CallNode(3...4)(nil, nil, (3...4), nil, nil, nil, nil, 2, "b"), + ConstantReadNode(6...7)(:C), + (4...6) + )], + nil, + nil + ), (8...9), ArrayNode(10...14)( [IntegerNode(10...11)(), IntegerNode(13...14)()], nil, nil - ), - nil, - nil + ) )] ) ) diff --git a/test/yarp/snapshots/seattlerb/masgn_colon3.txt b/test/yarp/snapshots/seattlerb/masgn_colon3.txt index 9dab8dc0484108..7446135fdce0c6 100644 --- a/test/yarp/snapshots/seattlerb/masgn_colon3.txt +++ b/test/yarp/snapshots/seattlerb/masgn_colon3.txt @@ -2,24 +2,26 @@ ProgramNode(0...15)( [], StatementsNode(0...15)( [MultiWriteNode(0...15)( - [ConstantPathTargetNode(0...3)( - nil, - ConstantReadNode(2...3)(:A), - (0...2) - ), - ConstantPathTargetNode(5...8)( - nil, - ConstantReadNode(7...8)(:B), - (5...7) - )], + MultiTargetNode(0...8)( + [ConstantPathTargetNode(0...3)( + nil, + ConstantReadNode(2...3)(:A), + (0...2) + ), + ConstantPathTargetNode(5...8)( + nil, + ConstantReadNode(7...8)(:B), + (5...7) + )], + nil, + nil + ), (9...10), ArrayNode(11...15)( [IntegerNode(11...12)(), IntegerNode(14...15)()], nil, nil - ), - nil, - nil + ) )] ) ) diff --git a/test/yarp/snapshots/seattlerb/masgn_command_call.txt b/test/yarp/snapshots/seattlerb/masgn_command_call.txt index edb11e8dc07c49..39cf7446d49ca8 100644 --- a/test/yarp/snapshots/seattlerb/masgn_command_call.txt +++ b/test/yarp/snapshots/seattlerb/masgn_command_call.txt @@ -2,7 +2,12 @@ ProgramNode(0...10)( [:a], StatementsNode(0...10)( [MultiWriteNode(0...10)( - [LocalVariableTargetNode(0...1)(:a, 0), SplatNode(1...2)((1...2), nil)], + MultiTargetNode(0...2)( + [LocalVariableTargetNode(0...1)(:a, 0), + SplatNode(1...2)((1...2), nil)], + nil, + nil + ), (3...4), CallNode(5...10)( CallNode(5...6)(nil, nil, (5...6), nil, nil, nil, nil, 2, "b"), @@ -14,9 +19,7 @@ ProgramNode(0...10)( nil, 0, "c" - ), - nil, - nil + ) )] ) ) diff --git a/test/yarp/snapshots/seattlerb/masgn_double_paren.txt b/test/yarp/snapshots/seattlerb/masgn_double_paren.txt index 3d0c2cf7ab6fbd..eaadbbc2c7722f 100644 --- a/test/yarp/snapshots/seattlerb/masgn_double_paren.txt +++ b/test/yarp/snapshots/seattlerb/masgn_double_paren.txt @@ -1,19 +1,19 @@ -ProgramNode(0...9)( +ProgramNode(1...9)( [:a, :b], - StatementsNode(0...9)( - [MultiWriteNode(0...9)( - [MultiWriteNode(1...6)( - [LocalVariableTargetNode(2...3)(:a, 0), - LocalVariableTargetNode(4...5)(:b, 0)], - nil, - nil, - (1...2), - (5...6) - )], + StatementsNode(1...9)( + [MultiWriteNode(1...9)( + MultiTargetNode(1...6)( + [MultiTargetNode(1...6)( + [LocalVariableTargetNode(2...3)(:a, 0), + LocalVariableTargetNode(4...5)(:b, 0)], + (1...2), + (5...6) + )], + nil, + nil + ), (7...8), - CallNode(8...9)(nil, nil, (8...9), nil, nil, nil, nil, 2, "c"), - (0...1), - (6...7) + CallNode(8...9)(nil, nil, (8...9), nil, nil, nil, nil, 2, "c") )] ) ) diff --git a/test/yarp/snapshots/seattlerb/masgn_lhs_splat.txt b/test/yarp/snapshots/seattlerb/masgn_lhs_splat.txt index 0fe5b400fae43b..04418018dd7e00 100644 --- a/test/yarp/snapshots/seattlerb/masgn_lhs_splat.txt +++ b/test/yarp/snapshots/seattlerb/masgn_lhs_splat.txt @@ -2,15 +2,17 @@ ProgramNode(0...12)( [:a], StatementsNode(0...12)( [MultiWriteNode(0...12)( - [SplatNode(0...2)((0...1), LocalVariableTargetNode(1...2)(:a, 0))], + MultiTargetNode(0...2)( + [SplatNode(0...2)((0...1), LocalVariableTargetNode(1...2)(:a, 0))], + nil, + nil + ), (3...4), ArrayNode(5...12)( [IntegerNode(5...6)(), IntegerNode(8...9)(), IntegerNode(11...12)()], nil, nil - ), - nil, - nil + ) )] ) ) diff --git a/test/yarp/snapshots/seattlerb/masgn_paren.txt b/test/yarp/snapshots/seattlerb/masgn_paren.txt index 91dd386d8c4a35..e8e0d72a88db27 100644 --- a/test/yarp/snapshots/seattlerb/masgn_paren.txt +++ b/test/yarp/snapshots/seattlerb/masgn_paren.txt @@ -2,8 +2,12 @@ ProgramNode(0...12)( [:a, :b], StatementsNode(0...12)( [MultiWriteNode(0...12)( - [LocalVariableTargetNode(1...2)(:a, 0), - LocalVariableTargetNode(4...5)(:b, 0)], + MultiTargetNode(0...6)( + [LocalVariableTargetNode(1...2)(:a, 0), + LocalVariableTargetNode(4...5)(:b, 0)], + (0...1), + (5...6) + ), (7...8), CallNode(9...12)( CallNode(9...10)(nil, nil, (9...10), nil, nil, nil, nil, 2, "c"), @@ -15,9 +19,7 @@ ProgramNode(0...12)( nil, 0, "d" - ), - (0...1), - (5...6) + ) )] ) ) diff --git a/test/yarp/snapshots/seattlerb/masgn_splat_arg.txt b/test/yarp/snapshots/seattlerb/masgn_splat_arg.txt index 2832f367da1d7f..a93904b9e026f1 100644 --- a/test/yarp/snapshots/seattlerb/masgn_splat_arg.txt +++ b/test/yarp/snapshots/seattlerb/masgn_splat_arg.txt @@ -2,18 +2,18 @@ ProgramNode(0...9)( [:a, :b], StatementsNode(0...9)( [MultiWriteNode(0...9)( - [MultiWriteNode(0...2)( - [SplatNode(0...2)((0...1), LocalVariableTargetNode(1...2)(:a, 0))], - nil, - nil, - nil, - nil - ), - LocalVariableTargetNode(4...5)(:b, 0)], + MultiTargetNode(0...5)( + [MultiTargetNode(0...2)( + [SplatNode(0...2)((0...1), LocalVariableTargetNode(1...2)(:a, 0))], + nil, + nil + ), + LocalVariableTargetNode(4...5)(:b, 0)], + nil, + nil + ), (6...7), - CallNode(8...9)(nil, nil, (8...9), nil, nil, nil, nil, 2, "c"), - nil, - nil + CallNode(8...9)(nil, nil, (8...9), nil, nil, nil, nil, 2, "c") )] ) ) diff --git a/test/yarp/snapshots/seattlerb/masgn_splat_arg_arg.txt b/test/yarp/snapshots/seattlerb/masgn_splat_arg_arg.txt index 9046d08d2bb091..5f95091cf744b1 100644 --- a/test/yarp/snapshots/seattlerb/masgn_splat_arg_arg.txt +++ b/test/yarp/snapshots/seattlerb/masgn_splat_arg_arg.txt @@ -2,19 +2,19 @@ ProgramNode(0...12)( [:a, :b, :c], StatementsNode(0...12)( [MultiWriteNode(0...12)( - [MultiWriteNode(0...2)( - [SplatNode(0...2)((0...1), LocalVariableTargetNode(1...2)(:a, 0))], - nil, - nil, - nil, - nil - ), - LocalVariableTargetNode(4...5)(:b, 0), - LocalVariableTargetNode(7...8)(:c, 0)], + MultiTargetNode(0...8)( + [MultiTargetNode(0...2)( + [SplatNode(0...2)((0...1), LocalVariableTargetNode(1...2)(:a, 0))], + nil, + nil + ), + LocalVariableTargetNode(4...5)(:b, 0), + LocalVariableTargetNode(7...8)(:c, 0)], + nil, + nil + ), (9...10), - CallNode(11...12)(nil, nil, (11...12), nil, nil, nil, nil, 2, "d"), - nil, - nil + CallNode(11...12)(nil, nil, (11...12), nil, nil, nil, nil, 2, "d") )] ) ) diff --git a/test/yarp/snapshots/seattlerb/masgn_star.txt b/test/yarp/snapshots/seattlerb/masgn_star.txt index 8b7cb8e266e96e..23c162c8395c1b 100644 --- a/test/yarp/snapshots/seattlerb/masgn_star.txt +++ b/test/yarp/snapshots/seattlerb/masgn_star.txt @@ -2,11 +2,9 @@ ProgramNode(0...5)( [], StatementsNode(0...5)( [MultiWriteNode(0...5)( - [SplatNode(0...1)((0...1), nil)], + MultiTargetNode(0...1)([SplatNode(0...1)((0...1), nil)], nil, nil), (2...3), - IntegerNode(4...5)(), - nil, - nil + IntegerNode(4...5)() )] ) ) diff --git a/test/yarp/snapshots/seattlerb/masgn_var_star_var.txt b/test/yarp/snapshots/seattlerb/masgn_var_star_var.txt index 64d21d637316be..59bb88d1edd4f7 100644 --- a/test/yarp/snapshots/seattlerb/masgn_var_star_var.txt +++ b/test/yarp/snapshots/seattlerb/masgn_var_star_var.txt @@ -2,13 +2,15 @@ ProgramNode(0...11)( [:a, :b], StatementsNode(0...11)( [MultiWriteNode(0...11)( - [LocalVariableTargetNode(0...1)(:a, 0), - SplatNode(3...4)((3...4), nil), - LocalVariableTargetNode(6...7)(:b, 0)], + MultiTargetNode(0...7)( + [LocalVariableTargetNode(0...1)(:a, 0), + SplatNode(3...4)((3...4), nil), + LocalVariableTargetNode(6...7)(:b, 0)], + nil, + nil + ), (8...9), - CallNode(10...11)(nil, nil, (10...11), nil, nil, nil, nil, 2, "c"), - nil, - nil + CallNode(10...11)(nil, nil, (10...11), nil, nil, nil, nil, 2, "c") )] ) ) diff --git a/test/yarp/snapshots/seattlerb/mlhs_back_anonsplat.txt b/test/yarp/snapshots/seattlerb/mlhs_back_anonsplat.txt index ba484f89b0374a..1243734429f6e1 100644 --- a/test/yarp/snapshots/seattlerb/mlhs_back_anonsplat.txt +++ b/test/yarp/snapshots/seattlerb/mlhs_back_anonsplat.txt @@ -2,14 +2,16 @@ ProgramNode(0...14)( [:a, :b, :c], StatementsNode(0...14)( [MultiWriteNode(0...14)( - [LocalVariableTargetNode(0...1)(:a, 0), - LocalVariableTargetNode(3...4)(:b, 0), - LocalVariableTargetNode(6...7)(:c, 0), - SplatNode(9...10)((9...10), nil)], + MultiTargetNode(0...10)( + [LocalVariableTargetNode(0...1)(:a, 0), + LocalVariableTargetNode(3...4)(:b, 0), + LocalVariableTargetNode(6...7)(:c, 0), + SplatNode(9...10)((9...10), nil)], + nil, + nil + ), (11...12), - CallNode(13...14)(nil, nil, (13...14), nil, nil, nil, nil, 2, "f"), - nil, - nil + CallNode(13...14)(nil, nil, (13...14), nil, nil, nil, nil, 2, "f") )] ) ) diff --git a/test/yarp/snapshots/seattlerb/mlhs_back_splat.txt b/test/yarp/snapshots/seattlerb/mlhs_back_splat.txt index 9578258257e340..05ff01d1bc5d46 100644 --- a/test/yarp/snapshots/seattlerb/mlhs_back_splat.txt +++ b/test/yarp/snapshots/seattlerb/mlhs_back_splat.txt @@ -2,14 +2,19 @@ ProgramNode(0...15)( [:a, :b, :c, :s], StatementsNode(0...15)( [MultiWriteNode(0...15)( - [LocalVariableTargetNode(0...1)(:a, 0), - LocalVariableTargetNode(3...4)(:b, 0), - LocalVariableTargetNode(6...7)(:c, 0), - SplatNode(9...11)((9...10), LocalVariableTargetNode(10...11)(:s, 0))], + MultiTargetNode(0...11)( + [LocalVariableTargetNode(0...1)(:a, 0), + LocalVariableTargetNode(3...4)(:b, 0), + LocalVariableTargetNode(6...7)(:c, 0), + SplatNode(9...11)( + (9...10), + LocalVariableTargetNode(10...11)(:s, 0) + )], + nil, + nil + ), (12...13), - CallNode(14...15)(nil, nil, (14...15), nil, nil, nil, nil, 2, "f"), - nil, - nil + CallNode(14...15)(nil, nil, (14...15), nil, nil, nil, nil, 2, "f") )] ) ) diff --git a/test/yarp/snapshots/seattlerb/mlhs_front_anonsplat.txt b/test/yarp/snapshots/seattlerb/mlhs_front_anonsplat.txt index 8ed6e38ebdac89..0655ff46bd4149 100644 --- a/test/yarp/snapshots/seattlerb/mlhs_front_anonsplat.txt +++ b/test/yarp/snapshots/seattlerb/mlhs_front_anonsplat.txt @@ -2,20 +2,16 @@ ProgramNode(0...14)( [:x, :y, :z], StatementsNode(0...14)( [MultiWriteNode(0...14)( - [MultiWriteNode(0...1)( - [SplatNode(0...1)((0...1), nil)], - nil, - nil, - nil, - nil - ), - LocalVariableTargetNode(3...4)(:x, 0), - LocalVariableTargetNode(6...7)(:y, 0), - LocalVariableTargetNode(9...10)(:z, 0)], + MultiTargetNode(0...10)( + [MultiTargetNode(0...1)([SplatNode(0...1)((0...1), nil)], nil, nil), + LocalVariableTargetNode(3...4)(:x, 0), + LocalVariableTargetNode(6...7)(:y, 0), + LocalVariableTargetNode(9...10)(:z, 0)], + nil, + nil + ), (11...12), - CallNode(13...14)(nil, nil, (13...14), nil, nil, nil, nil, 2, "f"), - nil, - nil + CallNode(13...14)(nil, nil, (13...14), nil, nil, nil, nil, 2, "f") )] ) ) diff --git a/test/yarp/snapshots/seattlerb/mlhs_front_splat.txt b/test/yarp/snapshots/seattlerb/mlhs_front_splat.txt index 07866df9edc139..4e8082cbaffa9e 100644 --- a/test/yarp/snapshots/seattlerb/mlhs_front_splat.txt +++ b/test/yarp/snapshots/seattlerb/mlhs_front_splat.txt @@ -2,20 +2,20 @@ ProgramNode(0...15)( [:s, :x, :y, :z], StatementsNode(0...15)( [MultiWriteNode(0...15)( - [MultiWriteNode(0...2)( - [SplatNode(0...2)((0...1), LocalVariableTargetNode(1...2)(:s, 0))], - nil, - nil, - nil, - nil - ), - LocalVariableTargetNode(4...5)(:x, 0), - LocalVariableTargetNode(7...8)(:y, 0), - LocalVariableTargetNode(10...11)(:z, 0)], + MultiTargetNode(0...11)( + [MultiTargetNode(0...2)( + [SplatNode(0...2)((0...1), LocalVariableTargetNode(1...2)(:s, 0))], + nil, + nil + ), + LocalVariableTargetNode(4...5)(:x, 0), + LocalVariableTargetNode(7...8)(:y, 0), + LocalVariableTargetNode(10...11)(:z, 0)], + nil, + nil + ), (12...13), - CallNode(14...15)(nil, nil, (14...15), nil, nil, nil, nil, 2, "f"), - nil, - nil + CallNode(14...15)(nil, nil, (14...15), nil, nil, nil, nil, 2, "f") )] ) ) diff --git a/test/yarp/snapshots/seattlerb/mlhs_mid_anonsplat.txt b/test/yarp/snapshots/seattlerb/mlhs_mid_anonsplat.txt index ce114d05287340..1e4f4bb53baa67 100644 --- a/test/yarp/snapshots/seattlerb/mlhs_mid_anonsplat.txt +++ b/test/yarp/snapshots/seattlerb/mlhs_mid_anonsplat.txt @@ -2,17 +2,19 @@ ProgramNode(0...23)( [:a, :b, :c, :x, :y, :z], StatementsNode(0...23)( [MultiWriteNode(0...23)( - [LocalVariableTargetNode(0...1)(:a, 0), - LocalVariableTargetNode(3...4)(:b, 0), - LocalVariableTargetNode(6...7)(:c, 0), - SplatNode(9...10)((9...10), nil), - LocalVariableTargetNode(12...13)(:x, 0), - LocalVariableTargetNode(15...16)(:y, 0), - LocalVariableTargetNode(18...19)(:z, 0)], + MultiTargetNode(0...19)( + [LocalVariableTargetNode(0...1)(:a, 0), + LocalVariableTargetNode(3...4)(:b, 0), + LocalVariableTargetNode(6...7)(:c, 0), + SplatNode(9...10)((9...10), nil), + LocalVariableTargetNode(12...13)(:x, 0), + LocalVariableTargetNode(15...16)(:y, 0), + LocalVariableTargetNode(18...19)(:z, 0)], + nil, + nil + ), (20...21), - CallNode(22...23)(nil, nil, (22...23), nil, nil, nil, nil, 2, "f"), - nil, - nil + CallNode(22...23)(nil, nil, (22...23), nil, nil, nil, nil, 2, "f") )] ) ) diff --git a/test/yarp/snapshots/seattlerb/mlhs_mid_splat.txt b/test/yarp/snapshots/seattlerb/mlhs_mid_splat.txt index 672de03089e4be..8fd7b6f3aac0dc 100644 --- a/test/yarp/snapshots/seattlerb/mlhs_mid_splat.txt +++ b/test/yarp/snapshots/seattlerb/mlhs_mid_splat.txt @@ -2,17 +2,19 @@ ProgramNode(0...24)( [:a, :b, :c, :s, :x, :y, :z], StatementsNode(0...24)( [MultiWriteNode(0...24)( - [LocalVariableTargetNode(0...1)(:a, 0), - LocalVariableTargetNode(3...4)(:b, 0), - LocalVariableTargetNode(6...7)(:c, 0), - SplatNode(9...11)((9...10), LocalVariableTargetNode(10...11)(:s, 0)), - LocalVariableTargetNode(13...14)(:x, 0), - LocalVariableTargetNode(16...17)(:y, 0), - LocalVariableTargetNode(19...20)(:z, 0)], + MultiTargetNode(0...20)( + [LocalVariableTargetNode(0...1)(:a, 0), + LocalVariableTargetNode(3...4)(:b, 0), + LocalVariableTargetNode(6...7)(:c, 0), + SplatNode(9...11)((9...10), LocalVariableTargetNode(10...11)(:s, 0)), + LocalVariableTargetNode(13...14)(:x, 0), + LocalVariableTargetNode(16...17)(:y, 0), + LocalVariableTargetNode(19...20)(:z, 0)], + nil, + nil + ), (21...22), - CallNode(23...24)(nil, nil, (23...24), nil, nil, nil, nil, 2, "f"), - nil, - nil + CallNode(23...24)(nil, nil, (23...24), nil, nil, nil, nil, 2, "f") )] ) ) diff --git a/test/yarp/snapshots/seattlerb/mlhs_rescue.txt b/test/yarp/snapshots/seattlerb/mlhs_rescue.txt index 3e1cd57291d87b..8d39772c8daad1 100644 --- a/test/yarp/snapshots/seattlerb/mlhs_rescue.txt +++ b/test/yarp/snapshots/seattlerb/mlhs_rescue.txt @@ -2,16 +2,18 @@ ProgramNode(0...18)( [:a, :b], StatementsNode(0...18)( [MultiWriteNode(0...18)( - [LocalVariableTargetNode(0...1)(:a, 0), - LocalVariableTargetNode(3...4)(:b, 0)], + MultiTargetNode(0...4)( + [LocalVariableTargetNode(0...1)(:a, 0), + LocalVariableTargetNode(3...4)(:b, 0)], + nil, + nil + ), (5...6), RescueModifierNode(7...18)( CallNode(7...8)(nil, nil, (7...8), nil, nil, nil, nil, 2, "f"), (9...15), IntegerNode(16...18)() - ), - nil, - nil + ) )] ) ) diff --git a/test/yarp/snapshots/seattlerb/parse_line_to_ary.txt b/test/yarp/snapshots/seattlerb/parse_line_to_ary.txt index 7f0a75913c6395..39afa6816b69c8 100644 --- a/test/yarp/snapshots/seattlerb/parse_line_to_ary.txt +++ b/test/yarp/snapshots/seattlerb/parse_line_to_ary.txt @@ -2,12 +2,14 @@ ProgramNode(0...10)( [:a, :b], StatementsNode(0...10)( [MultiWriteNode(0...8)( - [LocalVariableTargetNode(0...1)(:a, 0), - LocalVariableTargetNode(3...4)(:b, 0)], + MultiTargetNode(0...4)( + [LocalVariableTargetNode(0...1)(:a, 0), + LocalVariableTargetNode(3...4)(:b, 0)], + nil, + nil + ), (5...6), - CallNode(7...8)(nil, nil, (7...8), nil, nil, nil, nil, 2, "c"), - nil, - nil + CallNode(7...8)(nil, nil, (7...8), nil, nil, nil, nil, 2, "c") ), CallNode(9...10)(nil, nil, (9...10), nil, nil, nil, nil, 2, "d")] ) diff --git a/test/yarp/snapshots/unparser/corpus/literal/assignment.txt b/test/yarp/snapshots/unparser/corpus/literal/assignment.txt index 38c06a29bc928c..658cb37c5cc1c9 100644 --- a/test/yarp/snapshots/unparser/corpus/literal/assignment.txt +++ b/test/yarp/snapshots/unparser/corpus/literal/assignment.txt @@ -8,90 +8,102 @@ ProgramNode(0...704)( (3...4) ), MultiWriteNode(7...24)( - [GlobalVariableTargetNode(8...10)(:$a), - GlobalVariableTargetNode(12...14)(:$b)], + MultiTargetNode(7...15)( + [GlobalVariableTargetNode(8...10)(:$a), + GlobalVariableTargetNode(12...14)(:$b)], + (7...8), + (14...15) + ), (16...17), ArrayNode(18...24)( [IntegerNode(19...20)(), IntegerNode(22...23)()], (18...19), (23...24) - ), - (7...8), - (14...15) + ) ), MultiWriteNode(25...38)( - [MultiWriteNode(26...30)( - [LocalVariableTargetNode(27...28)(:a, 0), - SplatNode(28...29)((28...29), nil)], - nil, - nil, - (26...27), - (29...30) - ), - LocalVariableTargetNode(32...33)(:b, 0)], + MultiTargetNode(25...34)( + [MultiTargetNode(26...30)( + [LocalVariableTargetNode(27...28)(:a, 0), + SplatNode(28...29)((28...29), nil)], + (26...27), + (29...30) + ), + LocalVariableTargetNode(32...33)(:b, 0)], + (25...26), + (33...34) + ), (35...36), - IntegerNode(37...38)(), - (25...26), - (33...34) + IntegerNode(37...38)() ), MultiWriteNode(39...48)( - [SplatNode(40...42)( - (40...41), - LocalVariableTargetNode(41...42)(:a, 0) - )], + MultiTargetNode(39...43)( + [SplatNode(40...42)( + (40...41), + LocalVariableTargetNode(41...42)(:a, 0) + )], + (39...40), + (42...43) + ), (44...45), - ArrayNode(46...48)([], (46...47), (47...48)), - (39...40), - (42...43) + ArrayNode(46...48)([], (46...47), (47...48)) ), MultiWriteNode(49...64)( - [SplatNode(50...54)( - (50...51), - LocalVariableTargetNode(51...54)(:foo, 0) - )], + MultiTargetNode(49...55)( + [SplatNode(50...54)( + (50...51), + LocalVariableTargetNode(51...54)(:foo, 0) + )], + (49...50), + (54...55) + ), (56...57), ArrayNode(58...64)( [IntegerNode(59...60)(), IntegerNode(62...63)()], (58...59), (63...64) - ), - (49...50), - (54...55) + ) ), MultiWriteNode(65...84)( - [ClassVariableTargetNode(66...69)(:@@a), - ClassVariableTargetNode(71...74)(:@@b)], + MultiTargetNode(65...75)( + [ClassVariableTargetNode(66...69)(:@@a), + ClassVariableTargetNode(71...74)(:@@b)], + (65...66), + (74...75) + ), (76...77), ArrayNode(78...84)( [IntegerNode(79...80)(), IntegerNode(82...83)()], (78...79), (83...84) - ), - (65...66), - (74...75) + ) ), MultiWriteNode(85...102)( - [InstanceVariableTargetNode(86...88)(:@a), - InstanceVariableTargetNode(90...92)(:@b)], + MultiTargetNode(85...93)( + [InstanceVariableTargetNode(86...88)(:@a), + InstanceVariableTargetNode(90...92)(:@b)], + (85...86), + (92...93) + ), (94...95), ArrayNode(96...102)( [IntegerNode(97...98)(), IntegerNode(100...101)()], (96...97), (101...102) - ), - (85...86), - (92...93) + ) ), MultiWriteNode(103...128)( - [LocalVariableTargetNode(104...105)(:a, 0), - MultiWriteNode(107...113)( - [LocalVariableTargetNode(108...109)(:b, 0), - LocalVariableTargetNode(111...112)(:c, 0)], - nil, - nil, - (107...108), - (112...113) - )], + MultiTargetNode(103...114)( + [LocalVariableTargetNode(104...105)(:a, 0), + MultiTargetNode(107...113)( + [LocalVariableTargetNode(108...109)(:b, 0), + LocalVariableTargetNode(111...112)(:c, 0)], + (107...108), + (112...113) + )], + (103...104), + (113...114) + ), (115...116), ArrayNode(117...128)( [IntegerNode(118...119)(), @@ -102,185 +114,201 @@ ProgramNode(0...704)( )], (117...118), (127...128) - ), - (103...104), - (113...114) + ) ), MultiWriteNode(129...144)( - [LocalVariableTargetNode(130...131)(:a, 0), - SplatNode(133...134)((133...134), nil)], + MultiTargetNode(129...135)( + [LocalVariableTargetNode(130...131)(:a, 0), + SplatNode(133...134)((133...134), nil)], + (129...130), + (134...135) + ), (136...137), ArrayNode(138...144)( [IntegerNode(139...140)(), IntegerNode(142...143)()], (138...139), (143...144) - ), - (129...130), - (134...135) + ) ), MultiWriteNode(145...163)( - [LocalVariableTargetNode(146...147)(:a, 0), - SplatNode(149...153)( - (149...150), - LocalVariableTargetNode(150...153)(:foo, 0) - )], + MultiTargetNode(145...154)( + [LocalVariableTargetNode(146...147)(:a, 0), + SplatNode(149...153)( + (149...150), + LocalVariableTargetNode(150...153)(:foo, 0) + )], + (145...146), + (153...154) + ), (155...156), ArrayNode(157...163)( [IntegerNode(158...159)(), IntegerNode(161...162)()], (157...158), (162...163) - ), - (145...146), - (153...154) + ) ), MultiWriteNode(164...179)( - [LocalVariableTargetNode(165...166)(:a, 0), - LocalVariableTargetNode(168...169)(:b, 0)], + MultiTargetNode(164...170)( + [LocalVariableTargetNode(165...166)(:a, 0), + LocalVariableTargetNode(168...169)(:b, 0)], + (164...165), + (169...170) + ), (171...172), ArrayNode(173...179)( [IntegerNode(174...175)(), IntegerNode(177...178)()], (173...174), (178...179) - ), - (164...165), - (169...170) + ) ), MultiWriteNode(180...192)( - [LocalVariableTargetNode(181...182)(:a, 0), - LocalVariableTargetNode(184...185)(:b, 0)], + MultiTargetNode(180...186)( + [LocalVariableTargetNode(181...182)(:a, 0), + LocalVariableTargetNode(184...185)(:b, 0)], + (180...181), + (185...186) + ), (187...188), - LocalVariableReadNode(189...192)(:foo, 0), - (180...181), - (185...186) + LocalVariableReadNode(189...192)(:foo, 0) ), MultiWriteNode(193...203)( - [LocalVariableTargetNode(194...195)(:a, 0), - SplatNode(195...196)((195...196), nil)], + MultiTargetNode(193...197)( + [LocalVariableTargetNode(194...195)(:a, 0), + SplatNode(195...196)((195...196), nil)], + (193...194), + (196...197) + ), (198...199), - LocalVariableReadNode(200...203)(:foo, 0), - (193...194), - (196...197) + LocalVariableReadNode(200...203)(:foo, 0) ), MultiWriteNode(204...227)( - [CallNode(205...210)( - LocalVariableReadNode(205...206)(:a, 0), - (206...207), - (207...210), - nil, - nil, - nil, - nil, - 0, - "foo=" - ), - CallNode(212...217)( - LocalVariableReadNode(212...213)(:a, 0), - (213...214), - (214...217), - nil, - nil, - nil, - nil, - 0, - "bar=" - )], + MultiTargetNode(204...218)( + [CallNode(205...210)( + LocalVariableReadNode(205...206)(:a, 0), + (206...207), + (207...210), + nil, + nil, + nil, + nil, + 0, + "foo=" + ), + CallNode(212...217)( + LocalVariableReadNode(212...213)(:a, 0), + (213...214), + (214...217), + nil, + nil, + nil, + nil, + 0, + "bar=" + )], + (204...205), + (217...218) + ), (219...220), ArrayNode(221...227)( [IntegerNode(222...223)(), IntegerNode(225...226)()], (221...222), (226...227) - ), - (204...205), - (217...218) + ) ), MultiWriteNode(228...252)( - [CallNode(229...236)( - LocalVariableReadNode(229...230)(:a, 0), - nil, - (230...236), - (230...231), - ArgumentsNode(231...235)( - [SplatNode(231...235)( - (231...232), - LocalVariableReadNode(232...235)(:foo, 0) - )] + MultiTargetNode(228...243)( + [CallNode(229...236)( + LocalVariableReadNode(229...230)(:a, 0), + nil, + (230...236), + (230...231), + ArgumentsNode(231...235)( + [SplatNode(231...235)( + (231...232), + LocalVariableReadNode(232...235)(:foo, 0) + )] + ), + (235...236), + nil, + 0, + "[]=" ), - (235...236), - nil, - 0, - "[]=" - ), - CallNode(238...242)( - LocalVariableReadNode(238...239)(:a, 0), - nil, - (239...242), - (239...240), - ArgumentsNode(240...241)([IntegerNode(240...241)()]), - (241...242), - nil, - 0, - "[]=" - )], + CallNode(238...242)( + LocalVariableReadNode(238...239)(:a, 0), + nil, + (239...242), + (239...240), + ArgumentsNode(240...241)([IntegerNode(240...241)()]), + (241...242), + nil, + 0, + "[]=" + )], + (228...229), + (242...243) + ), (244...245), ArrayNode(246...252)( [IntegerNode(247...248)(), IntegerNode(250...251)()], (246...247), (251...252) - ), - (228...229), - (242...243) + ) ), MultiWriteNode(253...274)( - [CallNode(254...258)( - LocalVariableReadNode(254...255)(:a, 0), - nil, - (255...258), - (255...256), - ArgumentsNode(256...257)([IntegerNode(256...257)()]), - (257...258), - nil, - 0, - "[]=" - ), - CallNode(260...264)( - LocalVariableReadNode(260...261)(:a, 0), - nil, - (261...264), - (261...262), - ArgumentsNode(262...263)([IntegerNode(262...263)()]), - (263...264), - nil, - 0, - "[]=" - )], + MultiTargetNode(253...265)( + [CallNode(254...258)( + LocalVariableReadNode(254...255)(:a, 0), + nil, + (255...258), + (255...256), + ArgumentsNode(256...257)([IntegerNode(256...257)()]), + (257...258), + nil, + 0, + "[]=" + ), + CallNode(260...264)( + LocalVariableReadNode(260...261)(:a, 0), + nil, + (261...264), + (261...262), + ArgumentsNode(262...263)([IntegerNode(262...263)()]), + (263...264), + nil, + 0, + "[]=" + )], + (253...254), + (264...265) + ), (266...267), ArrayNode(268...274)( [IntegerNode(269...270)(), IntegerNode(272...273)()], (268...269), (273...274) - ), - (253...254), - (264...265) + ) ), MultiWriteNode(275...287)( - [SplatNode(276...282)( - (276...277), - CallNode(277...282)( - LocalVariableReadNode(277...278)(:c, 0), - (278...279), - (279...282), - nil, - nil, - nil, - nil, - 0, - "foo=" - ) - )], + MultiTargetNode(275...283)( + [SplatNode(276...282)( + (276...277), + CallNode(277...282)( + LocalVariableReadNode(277...278)(:c, 0), + (278...279), + (279...282), + nil, + nil, + nil, + nil, + 0, + "foo=" + ) + )], + (275...276), + (282...283) + ), (284...285), - IntegerNode(286...287)(), - (275...276), - (282...283) + IntegerNode(286...287)() ), ConstantPathWriteNode(288...301)( ConstantPathNode(288...293)( @@ -333,12 +361,14 @@ ProgramNode(0...704)( ParenthesesNode(355...367)( StatementsNode(356...366)( [MultiWriteNode(356...366)( - [LocalVariableTargetNode(357...358)(:b, 0), - LocalVariableTargetNode(360...361)(:c, 0)], + MultiTargetNode(356...362)( + [LocalVariableTargetNode(357...358)(:b, 0), + LocalVariableTargetNode(360...361)(:c, 0)], + (356...357), + (361...362) + ), (363...364), - IntegerNode(365...366)(), - (356...357), - (361...362) + IntegerNode(365...366)() )] ), (355...356), diff --git a/test/yarp/snapshots/unparser/corpus/literal/defined.txt b/test/yarp/snapshots/unparser/corpus/literal/defined.txt index 8e77e8e5df9a68..84167e14d4c4c5 100644 --- a/test/yarp/snapshots/unparser/corpus/literal/defined.txt +++ b/test/yarp/snapshots/unparser/corpus/literal/defined.txt @@ -18,16 +18,18 @@ ProgramNode(0...56)( ParenthesesNode(38...55)( StatementsNode(39...54)( [MultiWriteNode(39...54)( - [LocalVariableTargetNode(40...41)(:a, 0), - LocalVariableTargetNode(43...44)(:b, 0)], + MultiTargetNode(39...45)( + [LocalVariableTargetNode(40...41)(:a, 0), + LocalVariableTargetNode(43...44)(:b, 0)], + (39...40), + (44...45) + ), (46...47), ArrayNode(48...54)( [IntegerNode(49...50)(), IntegerNode(52...53)()], (48...49), (53...54) - ), - (39...40), - (44...45) + ) )] ), (38...39), diff --git a/test/yarp/snapshots/unparser/corpus/literal/for.txt b/test/yarp/snapshots/unparser/corpus/literal/for.txt index d7a916867674f3..7ede529a814716 100644 --- a/test/yarp/snapshots/unparser/corpus/literal/for.txt +++ b/test/yarp/snapshots/unparser/corpus/literal/for.txt @@ -8,11 +8,9 @@ ProgramNode(0...119)( (3...4), ArgumentsNode(4...29)( [ForNode(4...29)( - MultiWriteNode(8...9)( + MultiTargetNode(8...9)( [LocalVariableTargetNode(8...9)(:a, 0)], nil, - nil, - nil, nil ), CallNode(13...16)( @@ -51,11 +49,9 @@ ProgramNode(0...119)( "bar" ), ForNode(31...56)( - MultiWriteNode(35...36)( + MultiTargetNode(35...36)( [LocalVariableTargetNode(35...36)(:a, 0)], nil, - nil, - nil, nil ), CallNode(40...43)(nil, nil, (40...43), nil, nil, nil, nil, 2, "bar"), @@ -68,14 +64,12 @@ ProgramNode(0...119)( (53...56) ), ForNode(57...88)( - MultiWriteNode(61...68)( + MultiTargetNode(61...68)( [LocalVariableTargetNode(62...63)(:a, 0), SplatNode(65...67)( (65...66), LocalVariableTargetNode(66...67)(:b, 0) )], - nil, - nil, (61...62), (67...68) ), @@ -89,11 +83,9 @@ ProgramNode(0...119)( (85...88) ), ForNode(89...119)( - MultiWriteNode(93...99)( + MultiTargetNode(93...99)( [LocalVariableTargetNode(94...95)(:a, 0), LocalVariableTargetNode(97...98)(:b, 0)], - nil, - nil, (93...94), (98...99) ), diff --git a/test/yarp/snapshots/unparser/corpus/literal/send.txt b/test/yarp/snapshots/unparser/corpus/literal/send.txt index 67f3222a0e7eac..0cc45c949b0bd7 100644 --- a/test/yarp/snapshots/unparser/corpus/literal/send.txt +++ b/test/yarp/snapshots/unparser/corpus/literal/send.txt @@ -12,8 +12,12 @@ ProgramNode(0...999)( ParenthesesNode(19...31)( StatementsNode(20...30)( [MultiWriteNode(20...30)( - [LocalVariableTargetNode(21...22)(:a, 0), - LocalVariableTargetNode(24...25)(:_, 0)], + MultiTargetNode(20...26)( + [LocalVariableTargetNode(21...22)(:a, 0), + LocalVariableTargetNode(24...25)(:_, 0)], + (20...21), + (25...26) + ), (27...28), CallNode(29...30)( nil, @@ -25,9 +29,7 @@ ProgramNode(0...999)( nil, 2, "b" - ), - (20...21), - (25...26) + ) )] ), (19...20), diff --git a/test/yarp/snapshots/variables.txt b/test/yarp/snapshots/variables.txt index 4d50fa0db398d2..74691a2ae66323 100644 --- a/test/yarp/snapshots/variables.txt +++ b/test/yarp/snapshots/variables.txt @@ -9,12 +9,14 @@ ProgramNode(0...293)( (13...14) ), MultiWriteNode(18...34)( - [ClassVariableTargetNode(18...23)(:@@foo), - ClassVariableTargetNode(25...30)(:@@bar)], + MultiTargetNode(18...30)( + [ClassVariableTargetNode(18...23)(:@@foo), + ClassVariableTargetNode(25...30)(:@@bar)], + nil, + nil + ), (31...32), - IntegerNode(33...34)(), - nil, - nil + IntegerNode(33...34)() ), ClassVariableWriteNode(36...48)( :@@foo, @@ -49,12 +51,14 @@ ProgramNode(0...293)( (89...90) ), MultiWriteNode(94...108)( - [GlobalVariableTargetNode(94...98)(:$foo), - GlobalVariableTargetNode(100...104)(:$bar)], + MultiTargetNode(94...104)( + [GlobalVariableTargetNode(94...98)(:$foo), + GlobalVariableTargetNode(100...104)(:$bar)], + nil, + nil + ), (105...106), - IntegerNode(107...108)(), - nil, - nil + IntegerNode(107...108)() ), GlobalVariableWriteNode(110...121)( :$foo, @@ -67,12 +71,14 @@ ProgramNode(0...293)( (115...116) ), MultiWriteNode(123...137)( - [InstanceVariableTargetNode(123...127)(:@foo), - InstanceVariableTargetNode(129...133)(:@bar)], + MultiTargetNode(123...133)( + [InstanceVariableTargetNode(123...127)(:@foo), + InstanceVariableTargetNode(129...133)(:@bar)], + nil, + nil + ), (134...135), - IntegerNode(136...137)(), - nil, - nil + IntegerNode(136...137)() ), InstanceVariableWriteNode(139...150)( :@foo, @@ -114,54 +120,62 @@ ProgramNode(0...293)( (177...178) ), MultiWriteNode(185...198)( - [LocalVariableTargetNode(185...188)(:foo, 0), - SplatNode(190...191)((190...191), nil)], + MultiTargetNode(185...191)( + [LocalVariableTargetNode(185...188)(:foo, 0), + SplatNode(190...191)((190...191), nil)], + nil, + nil + ), (192...193), ArrayNode(194...198)( [IntegerNode(194...195)(), IntegerNode(197...198)()], nil, nil - ), - nil, - nil + ) ), MultiWriteNode(200...211)( - [LocalVariableTargetNode(200...203)(:foo, 0), - SplatNode(203...204)((203...204), nil)], + MultiTargetNode(200...204)( + [LocalVariableTargetNode(200...203)(:foo, 0), + SplatNode(203...204)((203...204), nil)], + nil, + nil + ), (205...206), ArrayNode(207...211)( [IntegerNode(207...208)(), IntegerNode(210...211)()], nil, nil - ), - nil, - nil + ) ), MultiWriteNode(213...229)( - [LocalVariableTargetNode(213...216)(:foo, 0), - SplatNode(218...222)( - (218...219), - LocalVariableTargetNode(219...222)(:bar, 0) - )], + MultiTargetNode(213...222)( + [LocalVariableTargetNode(213...216)(:foo, 0), + SplatNode(218...222)( + (218...219), + LocalVariableTargetNode(219...222)(:bar, 0) + )], + nil, + nil + ), (223...224), ArrayNode(225...229)( [IntegerNode(225...226)(), IntegerNode(228...229)()], nil, nil - ), - nil, - nil + ) ), MultiWriteNode(231...258)( - [LocalVariableTargetNode(231...234)(:foo, 0), - MultiWriteNode(236...246)( - [LocalVariableTargetNode(237...240)(:bar, 0), - LocalVariableTargetNode(242...245)(:baz, 0)], - nil, - nil, - (236...237), - (245...246) - )], + MultiTargetNode(231...246)( + [LocalVariableTargetNode(231...234)(:foo, 0), + MultiTargetNode(236...246)( + [LocalVariableTargetNode(237...240)(:bar, 0), + LocalVariableTargetNode(242...245)(:baz, 0)], + (236...237), + (245...246) + )], + nil, + nil + ), (247...248), ArrayNode(249...258)( [IntegerNode(249...250)(), @@ -172,9 +186,7 @@ ProgramNode(0...293)( )], nil, nil - ), - nil, - nil + ) ), LocalVariableWriteNode(260...270)( :foo, diff --git a/test/yarp/snapshots/whitequark/and_or_masgn.txt b/test/yarp/snapshots/whitequark/and_or_masgn.txt index bc64788ca43665..9ba221facd6d68 100644 --- a/test/yarp/snapshots/whitequark/and_or_masgn.txt +++ b/test/yarp/snapshots/whitequark/and_or_masgn.txt @@ -6,8 +6,12 @@ ProgramNode(0...40)( ParenthesesNode(7...19)( StatementsNode(8...18)( [MultiWriteNode(8...18)( - [LocalVariableTargetNode(8...9)(:a, 0), - LocalVariableTargetNode(11...12)(:b, 0)], + MultiTargetNode(8...12)( + [LocalVariableTargetNode(8...9)(:a, 0), + LocalVariableTargetNode(11...12)(:b, 0)], + nil, + nil + ), (13...14), CallNode(15...18)( nil, @@ -19,9 +23,7 @@ ProgramNode(0...40)( nil, 2, "bar" - ), - nil, - nil + ) )] ), (7...8), @@ -34,8 +36,12 @@ ProgramNode(0...40)( ParenthesesNode(28...40)( StatementsNode(29...39)( [MultiWriteNode(29...39)( - [LocalVariableTargetNode(29...30)(:a, 0), - LocalVariableTargetNode(32...33)(:b, 0)], + MultiTargetNode(29...33)( + [LocalVariableTargetNode(29...30)(:a, 0), + LocalVariableTargetNode(32...33)(:b, 0)], + nil, + nil + ), (34...35), CallNode(36...39)( nil, @@ -47,9 +53,7 @@ ProgramNode(0...40)( nil, 2, "bar" - ), - nil, - nil + ) )] ), (28...29), diff --git a/test/yarp/snapshots/whitequark/cond_begin_masgn.txt b/test/yarp/snapshots/whitequark/cond_begin_masgn.txt index 8114bd1cb4491d..a84f7b5154cb24 100644 --- a/test/yarp/snapshots/whitequark/cond_begin_masgn.txt +++ b/test/yarp/snapshots/whitequark/cond_begin_masgn.txt @@ -7,8 +7,12 @@ ProgramNode(0...25)( StatementsNode(4...19)( [CallNode(4...7)(nil, nil, (4...7), nil, nil, nil, nil, 2, "bar"), MultiWriteNode(9...19)( - [LocalVariableTargetNode(9...10)(:a, 0), - LocalVariableTargetNode(12...13)(:b, 0)], + MultiTargetNode(9...13)( + [LocalVariableTargetNode(9...10)(:a, 0), + LocalVariableTargetNode(12...13)(:b, 0)], + nil, + nil + ), (14...15), CallNode(16...19)( nil, @@ -20,9 +24,7 @@ ProgramNode(0...25)( nil, 2, "foo" - ), - nil, - nil + ) )] ), (3...4), diff --git a/test/yarp/snapshots/whitequark/for.txt b/test/yarp/snapshots/whitequark/for.txt index 1250760a01f976..67c75dcc928b5f 100644 --- a/test/yarp/snapshots/whitequark/for.txt +++ b/test/yarp/snapshots/whitequark/for.txt @@ -2,11 +2,9 @@ ProgramNode(0...48)( [:a], StatementsNode(0...48)( [ForNode(0...24)( - MultiWriteNode(4...5)( + MultiTargetNode(4...5)( [LocalVariableTargetNode(4...5)(:a, 0)], nil, - nil, - nil, nil ), CallNode(9...12)(nil, nil, (9...12), nil, nil, nil, nil, 2, "foo"), @@ -29,11 +27,9 @@ ProgramNode(0...48)( (21...24) ), ForNode(26...48)( - MultiWriteNode(30...31)( + MultiTargetNode(30...31)( [LocalVariableTargetNode(30...31)(:a, 0)], nil, - nil, - nil, nil ), CallNode(35...38)(nil, nil, (35...38), nil, nil, nil, nil, 2, "foo"), diff --git a/test/yarp/snapshots/whitequark/for_mlhs.txt b/test/yarp/snapshots/whitequark/for_mlhs.txt index fecaeb10caf949..74b8f52e2c7e4a 100644 --- a/test/yarp/snapshots/whitequark/for_mlhs.txt +++ b/test/yarp/snapshots/whitequark/for_mlhs.txt @@ -2,12 +2,10 @@ ProgramNode(0...28)( [:a, :b], StatementsNode(0...28)( [ForNode(0...28)( - MultiWriteNode(4...8)( + MultiTargetNode(4...8)( [LocalVariableTargetNode(4...5)(:a, 0), LocalVariableTargetNode(7...8)(:b, 0)], nil, - nil, - nil, nil ), CallNode(12...15)(nil, nil, (12...15), nil, nil, nil, nil, 2, "foo"), diff --git a/test/yarp/snapshots/whitequark/if_masgn__24.txt b/test/yarp/snapshots/whitequark/if_masgn__24.txt index 24c9ef784ddc58..b1ecd82868db8b 100644 --- a/test/yarp/snapshots/whitequark/if_masgn__24.txt +++ b/test/yarp/snapshots/whitequark/if_masgn__24.txt @@ -6,8 +6,12 @@ ProgramNode(0...20)( ParenthesesNode(3...15)( StatementsNode(4...14)( [MultiWriteNode(4...14)( - [LocalVariableTargetNode(4...5)(:a, 0), - LocalVariableTargetNode(7...8)(:b, 0)], + MultiTargetNode(4...8)( + [LocalVariableTargetNode(4...5)(:a, 0), + LocalVariableTargetNode(7...8)(:b, 0)], + nil, + nil + ), (9...10), CallNode(11...14)( nil, @@ -19,9 +23,7 @@ ProgramNode(0...20)( nil, 2, "foo" - ), - nil, - nil + ) )] ), (3...4), diff --git a/test/yarp/snapshots/whitequark/masgn.txt b/test/yarp/snapshots/whitequark/masgn.txt index 69667e1a38b5a9..aee61e4791c7c6 100644 --- a/test/yarp/snapshots/whitequark/masgn.txt +++ b/test/yarp/snapshots/whitequark/masgn.txt @@ -2,41 +2,47 @@ ProgramNode(0...56)( [:foo, :bar, :baz], StatementsNode(0...56)( [MultiWriteNode(0...17)( - [LocalVariableTargetNode(1...4)(:foo, 0), - LocalVariableTargetNode(6...9)(:bar, 0)], + MultiTargetNode(0...10)( + [LocalVariableTargetNode(1...4)(:foo, 0), + LocalVariableTargetNode(6...9)(:bar, 0)], + (0...1), + (9...10) + ), (11...12), ArrayNode(13...17)( [IntegerNode(13...14)(), IntegerNode(16...17)()], nil, nil - ), - (0...1), - (9...10) + ) ), MultiWriteNode(19...34)( - [LocalVariableTargetNode(19...22)(:foo, 0), - LocalVariableTargetNode(24...27)(:bar, 0)], + MultiTargetNode(19...27)( + [LocalVariableTargetNode(19...22)(:foo, 0), + LocalVariableTargetNode(24...27)(:bar, 0)], + nil, + nil + ), (28...29), ArrayNode(30...34)( [IntegerNode(30...31)(), IntegerNode(33...34)()], nil, nil - ), - nil, - nil + ) ), MultiWriteNode(36...56)( - [LocalVariableTargetNode(36...39)(:foo, 0), - LocalVariableTargetNode(41...44)(:bar, 0), - LocalVariableTargetNode(46...49)(:baz, 0)], + MultiTargetNode(36...49)( + [LocalVariableTargetNode(36...39)(:foo, 0), + LocalVariableTargetNode(41...44)(:bar, 0), + LocalVariableTargetNode(46...49)(:baz, 0)], + nil, + nil + ), (50...51), ArrayNode(52...56)( [IntegerNode(52...53)(), IntegerNode(55...56)()], nil, nil - ), - nil, - nil + ) )] ) ) diff --git a/test/yarp/snapshots/whitequark/masgn_attr.txt b/test/yarp/snapshots/whitequark/masgn_attr.txt index 1c71499f78f448..0c8af75356ff00 100644 --- a/test/yarp/snapshots/whitequark/masgn_attr.txt +++ b/test/yarp/snapshots/whitequark/masgn_attr.txt @@ -2,70 +2,76 @@ ProgramNode(0...63)( [:foo], StatementsNode(0...63)( [MultiWriteNode(0...17)( - [CallNode(0...6)( - SelfNode(0...4)(), - (4...5), - (5...6), - nil, - nil, - nil, - nil, - 0, - "A=" - ), - LocalVariableTargetNode(8...11)(:foo, 0)], + MultiTargetNode(0...11)( + [CallNode(0...6)( + SelfNode(0...4)(), + (4...5), + (5...6), + nil, + nil, + nil, + nil, + 0, + "A=" + ), + LocalVariableTargetNode(8...11)(:foo, 0)], + nil, + nil + ), (12...13), - LocalVariableReadNode(14...17)(:foo, 0), - nil, - nil + LocalVariableReadNode(14...17)(:foo, 0) ), MultiWriteNode(19...43)( - [CallNode(19...25)( - SelfNode(19...23)(), - (23...24), - (24...25), - nil, - nil, - nil, - nil, - 0, - "a=" - ), - CallNode(27...37)( - SelfNode(27...31)(), - nil, - (31...37), - (31...32), - ArgumentsNode(32...36)( - [IntegerNode(32...33)(), IntegerNode(35...36)()] + MultiTargetNode(19...37)( + [CallNode(19...25)( + SelfNode(19...23)(), + (23...24), + (24...25), + nil, + nil, + nil, + nil, + 0, + "a=" ), - (36...37), - nil, - 0, - "[]=" - )], + CallNode(27...37)( + SelfNode(27...31)(), + nil, + (31...37), + (31...32), + ArgumentsNode(32...36)( + [IntegerNode(32...33)(), IntegerNode(35...36)()] + ), + (36...37), + nil, + 0, + "[]=" + )], + nil, + nil + ), (38...39), - LocalVariableReadNode(40...43)(:foo, 0), - nil, - nil + LocalVariableReadNode(40...43)(:foo, 0) ), MultiWriteNode(45...63)( - [CallNode(45...52)( - SelfNode(45...49)(), - (49...51), - (51...52), - nil, - nil, - nil, - nil, - 0, - "a=" - ), - LocalVariableTargetNode(54...57)(:foo, 0)], + MultiTargetNode(45...57)( + [CallNode(45...52)( + SelfNode(45...49)(), + (49...51), + (51...52), + nil, + nil, + nil, + nil, + 0, + "a=" + ), + LocalVariableTargetNode(54...57)(:foo, 0)], + nil, + nil + ), (58...59), - LocalVariableReadNode(60...63)(:foo, 0), - nil, - nil + LocalVariableReadNode(60...63)(:foo, 0) )] ) ) diff --git a/test/yarp/snapshots/whitequark/masgn_cmd.txt b/test/yarp/snapshots/whitequark/masgn_cmd.txt index 14d81d79bcf2b3..ab403e2f12b723 100644 --- a/test/yarp/snapshots/whitequark/masgn_cmd.txt +++ b/test/yarp/snapshots/whitequark/masgn_cmd.txt @@ -2,8 +2,12 @@ ProgramNode(0...16)( [:foo, :bar], StatementsNode(0...16)( [MultiWriteNode(0...16)( - [LocalVariableTargetNode(0...3)(:foo, 0), - LocalVariableTargetNode(5...8)(:bar, 0)], + MultiTargetNode(0...8)( + [LocalVariableTargetNode(0...3)(:foo, 0), + LocalVariableTargetNode(5...8)(:bar, 0)], + nil, + nil + ), (9...10), CallNode(11...16)( nil, @@ -15,9 +19,7 @@ ProgramNode(0...16)( nil, 0, "m" - ), - nil, - nil + ) )] ) ) diff --git a/test/yarp/snapshots/whitequark/masgn_const.txt b/test/yarp/snapshots/whitequark/masgn_const.txt index 51f44f4d2bf7a5..8ed2ec62a09813 100644 --- a/test/yarp/snapshots/whitequark/masgn_const.txt +++ b/test/yarp/snapshots/whitequark/masgn_const.txt @@ -2,28 +2,32 @@ ProgramNode(0...34)( [:foo], StatementsNode(0...34)( [MultiWriteNode(0...14)( - [ConstantPathTargetNode(0...3)( - nil, - ConstantReadNode(2...3)(:A), - (0...2) - ), - LocalVariableTargetNode(5...8)(:foo, 0)], + MultiTargetNode(0...8)( + [ConstantPathTargetNode(0...3)( + nil, + ConstantReadNode(2...3)(:A), + (0...2) + ), + LocalVariableTargetNode(5...8)(:foo, 0)], + nil, + nil + ), (9...10), - LocalVariableReadNode(11...14)(:foo, 0), - nil, - nil + LocalVariableReadNode(11...14)(:foo, 0) ), MultiWriteNode(16...34)( - [ConstantPathTargetNode(16...23)( - SelfNode(16...20)(), - ConstantReadNode(22...23)(:A), - (20...22) - ), - LocalVariableTargetNode(25...28)(:foo, 0)], + MultiTargetNode(16...28)( + [ConstantPathTargetNode(16...23)( + SelfNode(16...20)(), + ConstantReadNode(22...23)(:A), + (20...22) + ), + LocalVariableTargetNode(25...28)(:foo, 0)], + nil, + nil + ), (29...30), - LocalVariableReadNode(31...34)(:foo, 0), - nil, - nil + LocalVariableReadNode(31...34)(:foo, 0) )] ) ) diff --git a/test/yarp/snapshots/whitequark/masgn_nested.txt b/test/yarp/snapshots/whitequark/masgn_nested.txt index b1601b8aa7436a..3dd9fd696a9d24 100644 --- a/test/yarp/snapshots/whitequark/masgn_nested.txt +++ b/test/yarp/snapshots/whitequark/masgn_nested.txt @@ -1,34 +1,34 @@ -ProgramNode(0...30)( +ProgramNode(1...30)( [:b, :a, :c], - StatementsNode(0...30)( - [MultiWriteNode(0...13)( - [MultiWriteNode(1...6)( - [LocalVariableTargetNode(2...3)(:b, 0), - SplatNode(3...4)((3...4), nil)], - nil, - nil, - (1...2), - (5...6) - )], + StatementsNode(1...30)( + [MultiWriteNode(1...13)( + MultiTargetNode(1...6)( + [MultiTargetNode(1...6)( + [LocalVariableTargetNode(2...3)(:b, 0), + SplatNode(3...4)((3...4), nil)], + (1...2), + (5...6) + )], + nil, + nil + ), (8...9), - CallNode(10...13)(nil, nil, (10...13), nil, nil, nil, nil, 2, "foo"), - (0...1), - (6...7) + CallNode(10...13)(nil, nil, (10...13), nil, nil, nil, nil, 2, "foo") ), MultiWriteNode(15...30)( - [LocalVariableTargetNode(15...16)(:a, 0), - MultiWriteNode(18...24)( - [LocalVariableTargetNode(19...20)(:b, 0), - LocalVariableTargetNode(22...23)(:c, 0)], - nil, - nil, - (18...19), - (23...24) - )], + MultiTargetNode(15...24)( + [LocalVariableTargetNode(15...16)(:a, 0), + MultiTargetNode(18...24)( + [LocalVariableTargetNode(19...20)(:b, 0), + LocalVariableTargetNode(22...23)(:c, 0)], + (18...19), + (23...24) + )], + nil, + nil + ), (25...26), - CallNode(27...30)(nil, nil, (27...30), nil, nil, nil, nil, 2, "foo"), - nil, - nil + CallNode(27...30)(nil, nil, (27...30), nil, nil, nil, nil, 2, "foo") )] ) ) diff --git a/test/yarp/snapshots/whitequark/masgn_splat.txt b/test/yarp/snapshots/whitequark/masgn_splat.txt index d21760a65b3921..f7a2050506298f 100644 --- a/test/yarp/snapshots/whitequark/masgn_splat.txt +++ b/test/yarp/snapshots/whitequark/masgn_splat.txt @@ -2,57 +2,61 @@ ProgramNode(0...139)( [:c, :d, :b, :a], StatementsNode(0...139)( [MultiWriteNode(0...7)( - [SplatNode(0...1)((0...1), nil)], + MultiTargetNode(0...1)([SplatNode(0...1)((0...1), nil)], nil, nil), (2...3), - CallNode(4...7)(nil, nil, (4...7), nil, nil, nil, nil, 2, "bar"), - nil, - nil + CallNode(4...7)(nil, nil, (4...7), nil, nil, nil, nil, 2, "bar") ), MultiWriteNode(9...22)( - [MultiWriteNode(9...10)( - [SplatNode(9...10)((9...10), nil)], - nil, - nil, - nil, - nil - ), - LocalVariableTargetNode(12...13)(:c, 0), - LocalVariableTargetNode(15...16)(:d, 0)], + MultiTargetNode(9...16)( + [MultiTargetNode(9...10)( + [SplatNode(9...10)((9...10), nil)], + nil, + nil + ), + LocalVariableTargetNode(12...13)(:c, 0), + LocalVariableTargetNode(15...16)(:d, 0)], + nil, + nil + ), (17...18), - CallNode(19...22)(nil, nil, (19...22), nil, nil, nil, nil, 2, "bar"), - nil, - nil + CallNode(19...22)(nil, nil, (19...22), nil, nil, nil, nil, 2, "bar") ), MultiWriteNode(24...32)( - [SplatNode(24...26)( - (24...25), - LocalVariableTargetNode(25...26)(:b, 0) - )], + MultiTargetNode(24...26)( + [SplatNode(24...26)( + (24...25), + LocalVariableTargetNode(25...26)(:b, 0) + )], + nil, + nil + ), (27...28), - CallNode(29...32)(nil, nil, (29...32), nil, nil, nil, nil, 2, "bar"), - nil, - nil + CallNode(29...32)(nil, nil, (29...32), nil, nil, nil, nil, 2, "bar") ), MultiWriteNode(34...45)( - [MultiWriteNode(34...36)( - [SplatNode(34...36)( - (34...35), - LocalVariableTargetNode(35...36)(:b, 0) - )], - nil, - nil, - nil, - nil - ), - LocalVariableTargetNode(38...39)(:c, 0)], + MultiTargetNode(34...39)( + [MultiTargetNode(34...36)( + [SplatNode(34...36)( + (34...35), + LocalVariableTargetNode(35...36)(:b, 0) + )], + nil, + nil + ), + LocalVariableTargetNode(38...39)(:c, 0)], + nil, + nil + ), (40...41), - CallNode(42...45)(nil, nil, (42...45), nil, nil, nil, nil, 2, "bar"), - nil, - nil + CallNode(42...45)(nil, nil, (42...45), nil, nil, nil, nil, 2, "bar") ), MultiWriteNode(47...65)( - [InstanceVariableTargetNode(47...51)(:@foo), - ClassVariableTargetNode(53...58)(:@@bar)], + MultiTargetNode(47...58)( + [InstanceVariableTargetNode(47...51)(:@foo), + ClassVariableTargetNode(53...58)(:@@bar)], + nil, + nil + ), (59...60), ArrayNode(61...65)( [SplatNode(61...65)( @@ -71,73 +75,63 @@ ProgramNode(0...139)( )], nil, nil - ), - nil, - nil + ) ), MultiWriteNode(67...77)( - [LocalVariableTargetNode(67...68)(:a, 0), - SplatNode(70...71)((70...71), nil)], + MultiTargetNode(67...71)( + [LocalVariableTargetNode(67...68)(:a, 0), + SplatNode(70...71)((70...71), nil)], + nil, + nil + ), (72...73), - CallNode(74...77)(nil, nil, (74...77), nil, nil, nil, nil, 2, "bar"), - nil, - nil + CallNode(74...77)(nil, nil, (74...77), nil, nil, nil, nil, 2, "bar") ), MultiWriteNode(79...92)( - [LocalVariableTargetNode(79...80)(:a, 0), - SplatNode(82...83)((82...83), nil), - LocalVariableTargetNode(85...86)(:c, 0)], + MultiTargetNode(79...86)( + [LocalVariableTargetNode(79...80)(:a, 0), + SplatNode(82...83)((82...83), nil), + LocalVariableTargetNode(85...86)(:c, 0)], + nil, + nil + ), (87...88), - CallNode(89...92)(nil, nil, (89...92), nil, nil, nil, nil, 2, "bar"), - nil, - nil + CallNode(89...92)(nil, nil, (89...92), nil, nil, nil, nil, 2, "bar") ), MultiWriteNode(94...105)( - [LocalVariableTargetNode(94...95)(:a, 0), - SplatNode(97...99)( - (97...98), - LocalVariableTargetNode(98...99)(:b, 0) - )], - (100...101), - CallNode(102...105)( - nil, - nil, - (102...105), - nil, - nil, - nil, + MultiTargetNode(94...99)( + [LocalVariableTargetNode(94...95)(:a, 0), + SplatNode(97...99)( + (97...98), + LocalVariableTargetNode(98...99)(:b, 0) + )], nil, - 2, - "bar" + nil ), - nil, - nil + (100...101), + CallNode(102...105)(nil, nil, (102...105), nil, nil, nil, nil, 2, "bar") ), MultiWriteNode(107...121)( - [LocalVariableTargetNode(107...108)(:a, 0), - SplatNode(110...112)( - (110...111), - LocalVariableTargetNode(111...112)(:b, 0) - ), - LocalVariableTargetNode(114...115)(:c, 0)], - (116...117), - CallNode(118...121)( - nil, - nil, - (118...121), - nil, - nil, - nil, + MultiTargetNode(107...115)( + [LocalVariableTargetNode(107...108)(:a, 0), + SplatNode(110...112)( + (110...111), + LocalVariableTargetNode(111...112)(:b, 0) + ), + LocalVariableTargetNode(114...115)(:c, 0)], nil, - 2, - "bar" + nil ), - nil, - nil + (116...117), + CallNode(118...121)(nil, nil, (118...121), nil, nil, nil, nil, 2, "bar") ), MultiWriteNode(123...139)( - [LocalVariableTargetNode(123...124)(:a, 0), - LocalVariableTargetNode(126...127)(:b, 0)], + MultiTargetNode(123...127)( + [LocalVariableTargetNode(123...124)(:a, 0), + LocalVariableTargetNode(126...127)(:b, 0)], + nil, + nil + ), (128...129), ArrayNode(130...139)( [SplatNode(130...134)( @@ -167,9 +161,7 @@ ProgramNode(0...139)( )], nil, nil - ), - nil, - nil + ) )] ) ) diff --git a/test/yarp/snapshots/whitequark/not_masgn__24.txt b/test/yarp/snapshots/whitequark/not_masgn__24.txt index 47895d8c462466..5233c25ba587e2 100644 --- a/test/yarp/snapshots/whitequark/not_masgn__24.txt +++ b/test/yarp/snapshots/whitequark/not_masgn__24.txt @@ -5,8 +5,12 @@ ProgramNode(0...13)( ParenthesesNode(1...13)( StatementsNode(2...12)( [MultiWriteNode(2...12)( - [LocalVariableTargetNode(2...3)(:a, 0), - LocalVariableTargetNode(5...6)(:b, 0)], + MultiTargetNode(2...6)( + [LocalVariableTargetNode(2...3)(:a, 0), + LocalVariableTargetNode(5...6)(:b, 0)], + nil, + nil + ), (7...8), CallNode(9...12)( nil, @@ -18,9 +22,7 @@ ProgramNode(0...13)( nil, 2, "foo" - ), - nil, - nil + ) )] ), (1...2), diff --git a/test/yarp/snapshots/whitequark/rescue_mod_masgn.txt b/test/yarp/snapshots/whitequark/rescue_mod_masgn.txt index 13023afc175e47..990312e3657dd2 100644 --- a/test/yarp/snapshots/whitequark/rescue_mod_masgn.txt +++ b/test/yarp/snapshots/whitequark/rescue_mod_masgn.txt @@ -2,8 +2,12 @@ ProgramNode(0...29)( [:foo, :bar], StatementsNode(0...29)( [MultiWriteNode(0...29)( - [LocalVariableTargetNode(0...3)(:foo, 0), - LocalVariableTargetNode(5...8)(:bar, 0)], + MultiTargetNode(0...8)( + [LocalVariableTargetNode(0...3)(:foo, 0), + LocalVariableTargetNode(5...8)(:bar, 0)], + nil, + nil + ), (9...10), RescueModifierNode(11...29)( CallNode(11...15)(nil, nil, (11...15), nil, nil, nil, nil, 2, "meth"), @@ -13,9 +17,7 @@ ProgramNode(0...29)( (23...24), (28...29) ) - ), - nil, - nil + ) )] ) ) diff --git a/yarp/config.yml b/yarp/config.yml index 2808a0310d58ad..3161006bf374d4 100644 --- a/yarp/config.yml +++ b/yarp/config.yml @@ -1751,14 +1751,10 @@ nodes: module Foo end ^^^^^^^^^^^^^^ - - name: MultiWriteNode + - name: MultiTargetNode fields: - name: targets type: node[] - - name: operator_loc - type: location? - - name: value - type: node? - name: lparen_loc type: location? - name: rparen_loc @@ -1766,6 +1762,20 @@ nodes: comment: | Represents a multi-target expression. + a, b, c = 1, 2, 3 + ^^^^^^^ + - name: MultiWriteNode + fields: + - name: target + type: node + kind: MultiTargetNode + - name: operator_loc + type: location + - name: value + type: node + comment: | + Represents a write to a multi-target expression. + a, b, c = 1, 2, 3 ^^^^^^^^^^^^^^^^^ - name: NextNode diff --git a/yarp/yarp.c b/yarp/yarp.c index ba3e821e359df9..7c1df2343da0f9 100644 --- a/yarp/yarp.c +++ b/yarp/yarp.c @@ -3320,32 +3320,27 @@ yp_module_node_create(yp_parser_t *parser, yp_constant_id_list_t *locals, const return node; } -// Allocate a new MultiWriteNode node. -static yp_multi_write_node_t * -yp_multi_write_node_create(yp_parser_t *parser, const yp_token_t *operator, yp_node_t *value, const yp_location_t *lparen_loc, const yp_location_t *rparen_loc) { - yp_multi_write_node_t *node = YP_ALLOC_NODE(parser, yp_multi_write_node_t); +// Allocate and initialize new MultiTargetNode node. +static yp_multi_target_node_t * +yp_multi_target_node_create(yp_parser_t *parser) { + yp_multi_target_node_t *node = YP_ALLOC_NODE(parser, yp_multi_target_node_t); - *node = (yp_multi_write_node_t) { + *node = (yp_multi_target_node_t) { { - .type = YP_MULTI_WRITE_NODE, - .location = { - .start = lparen_loc->start, - .end = value == NULL ? rparen_loc->end : value->location.end - }, + .type = YP_MULTI_TARGET_NODE, + .location = { .start = NULL, .end = NULL } }, - .operator_loc = YP_OPTIONAL_LOCATION_TOKEN_VALUE(operator), - .value = value, - .lparen_loc = *lparen_loc, - .rparen_loc = *rparen_loc, - .targets = YP_EMPTY_NODE_LIST + .targets = YP_EMPTY_NODE_LIST, + .lparen_loc = YP_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE, + .rparen_loc = YP_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE }; return node; } -// Append a target to a MultiWriteNode node. +// Append a target to a MultiTargetNode node. static void -yp_multi_write_node_targets_append(yp_multi_write_node_t *node, yp_node_t *target) { +yp_multi_target_node_targets_append(yp_multi_target_node_t *node, yp_node_t *target) { yp_node_list_append(&node->targets, target); if (node->base.location.start == NULL || (node->base.location.start > target->location.start)) { @@ -3357,9 +3352,25 @@ yp_multi_write_node_targets_append(yp_multi_write_node_t *node, yp_node_t *targe } } -static inline void -yp_multi_write_node_operator_loc_set(yp_multi_write_node_t *node, const yp_token_t *operator) { - node->operator_loc = YP_OPTIONAL_LOCATION_TOKEN_VALUE(operator); +// Allocate a new MultiWriteNode node. +static yp_multi_write_node_t * +yp_multi_write_node_create(yp_parser_t *parser, yp_multi_target_node_t *target, const yp_token_t *operator, yp_node_t *value) { + yp_multi_write_node_t *node = YP_ALLOC_NODE(parser, yp_multi_write_node_t); + + *node = (yp_multi_write_node_t) { + { + .type = YP_MULTI_WRITE_NODE, + .location = { + .start = target->base.location.start, + .end = value->location.end + } + }, + .target = target, + .operator_loc = YP_LOCATION_TOKEN_VALUE(operator), + .value = value + }; + + return node; } // Allocate and initialize a new NextNode node. @@ -8080,7 +8091,7 @@ parse_target(yp_parser_t *parser, yp_node_t *target) { assert(sizeof(yp_instance_variable_target_node_t) == sizeof(yp_instance_variable_read_node_t)); target->type = YP_INSTANCE_VARIABLE_TARGET_NODE; return target; - case YP_MULTI_WRITE_NODE: + case YP_MULTI_TARGET_NODE: return target; case YP_SPLAT_NODE: { yp_splat_node_t *splat = (yp_splat_node_t *) target; @@ -8089,13 +8100,10 @@ parse_target(yp_parser_t *parser, yp_node_t *target) { splat->expression = parse_target(parser, splat->expression); } - yp_token_t operator = not_provided(parser); - yp_location_t location = YP_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE; + yp_multi_target_node_t *multi_target = yp_multi_target_node_create(parser); + yp_multi_target_node_targets_append(multi_target, (yp_node_t *) splat); - yp_multi_write_node_t *multi_write = yp_multi_write_node_create(parser, &operator, NULL, &location, &location); - yp_multi_write_node_targets_append(multi_write, (yp_node_t *) splat); - - return (yp_node_t *) multi_write; + return (yp_node_t *) multi_target; } case YP_CALL_NODE: { yp_call_node_t *call = (yp_call_node_t *) target; @@ -8221,14 +8229,8 @@ parse_write(yp_parser_t *parser, yp_node_t *target, yp_token_t *operator, yp_nod yp_node_destroy(parser, target); return write_node; } - case YP_MULTI_WRITE_NODE: { - yp_multi_write_node_t *multi_write = (yp_multi_write_node_t *) target; - yp_multi_write_node_operator_loc_set(multi_write, operator); - - multi_write->value = value; - multi_write->base.location.end = value->location.end; - return (yp_node_t *) multi_write; - } + case YP_MULTI_TARGET_NODE: + return (yp_node_t *) yp_multi_write_node_create(parser, (yp_multi_target_node_t *) target, operator, value); case YP_SPLAT_NODE: { yp_splat_node_t *splat = (yp_splat_node_t *) target; @@ -8236,11 +8238,10 @@ parse_write(yp_parser_t *parser, yp_node_t *target, yp_token_t *operator, yp_nod splat->expression = parse_write(parser, splat->expression, operator, value); } - yp_location_t location = YP_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE; - yp_multi_write_node_t *multi_write = yp_multi_write_node_create(parser, operator, value, &location, &location); - yp_multi_write_node_targets_append(multi_write, (yp_node_t *) splat); + yp_multi_target_node_t *multi_target = yp_multi_target_node_create(parser); + yp_multi_target_node_targets_append(multi_target, (yp_node_t *) splat); - return (yp_node_t *) multi_write; + return (yp_node_t *) yp_multi_write_node_create(parser, multi_target, operator, value); } case YP_CALL_NODE: { yp_call_node_t *call = (yp_call_node_t *) target; @@ -8371,11 +8372,9 @@ parse_targets(yp_parser_t *parser, yp_node_t *first_target, yp_binding_power_t b } } - yp_location_t lparen_loc = YP_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE; - yp_multi_write_node_t *result = yp_multi_write_node_create(parser, &operator, NULL, &lparen_loc, &lparen_loc); - + yp_multi_target_node_t *result = yp_multi_target_node_create(parser); if (first_target != NULL) { - yp_multi_write_node_targets_append(result, first_target); + yp_multi_target_node_targets_append(result, first_target); } bool has_splat = false; @@ -8400,7 +8399,7 @@ parse_targets(yp_parser_t *parser, yp_node_t *first_target, yp_binding_power_t b } yp_node_t *splat = (yp_node_t *) yp_splat_node_create(parser, &star_operator, name); - yp_multi_write_node_targets_append(result, splat); + yp_multi_target_node_targets_append(result, splat); has_splat = true; } else if (accept(parser, YP_TOKEN_PARENTHESIS_LEFT)) { // Here we have a parenthesized list of targets. We'll recurse down into @@ -8414,39 +8413,29 @@ parse_targets(yp_parser_t *parser, yp_node_t *first_target, yp_binding_power_t b expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, YP_ERR_EXPECT_RPAREN_AFTER_MULTI); yp_token_t rparen = parser->previous; - if (YP_NODE_TYPE_P(child_target, YP_MULTI_WRITE_NODE) && first_target == NULL && result->targets.size == 0) { + if (YP_NODE_TYPE_P(child_target, YP_MULTI_TARGET_NODE) && first_target == NULL && result->targets.size == 0) { yp_node_destroy(parser, (yp_node_t *) result); - result = (yp_multi_write_node_t *) child_target; + result = (yp_multi_target_node_t *) child_target; result->base.location.start = lparen.start; result->base.location.end = rparen.end; result->lparen_loc = YP_LOCATION_TOKEN_VALUE(&lparen); result->rparen_loc = YP_LOCATION_TOKEN_VALUE(&rparen); } else { - yp_multi_write_node_t *target; - - if (YP_NODE_TYPE_P(child_target, YP_MULTI_WRITE_NODE)) { - target = (yp_multi_write_node_t *) child_target; - target->base.location.start = lparen.start; - target->base.location.end = rparen.end; - target->lparen_loc = YP_LOCATION_TOKEN_VALUE(&lparen); - target->rparen_loc = YP_LOCATION_TOKEN_VALUE(&rparen); - } else { - yp_token_t operator = not_provided(parser); - - target = yp_multi_write_node_create( - parser, - &operator, - NULL, - &YP_LOCATION_TOKEN_VALUE(&lparen), - &YP_LOCATION_TOKEN_VALUE(&rparen) - ); + yp_multi_target_node_t *target; - yp_multi_write_node_targets_append(target, child_target); + if (YP_NODE_TYPE_P(child_target, YP_MULTI_TARGET_NODE)) { + target = (yp_multi_target_node_t *) child_target; + } else { + target = yp_multi_target_node_create(parser); + yp_multi_target_node_targets_append(target, child_target); } target->base.location.start = lparen.start; target->base.location.end = rparen.end; - yp_multi_write_node_targets_append(result, (yp_node_t *) target); + target->lparen_loc = YP_LOCATION_TOKEN_VALUE(&lparen); + target->rparen_loc = YP_LOCATION_TOKEN_VALUE(&rparen); + + yp_multi_target_node_targets_append(result, (yp_node_t *) target); } } else { if (!token_begins_expression_p(parser->current.type) && !match_type_p(parser, YP_TOKEN_USTAR)) { @@ -8462,14 +8451,14 @@ parse_targets(yp_parser_t *parser, yp_node_t *first_target, yp_binding_power_t b // We need to indicate this somehow in the tree, so we'll add an // anonymous splat. yp_node_t *splat = (yp_node_t *) yp_splat_node_create(parser, &parser->previous, NULL); - yp_multi_write_node_targets_append(result, splat); + yp_multi_target_node_targets_append(result, splat); return (yp_node_t *) result; } yp_node_t *target = parse_expression(parser, binding_power, YP_ERR_EXPECT_EXPRESSION_AFTER_COMMA); target = parse_target(parser, target); - yp_multi_write_node_targets_append(result, target); + yp_multi_target_node_targets_append(result, target); } } while (accept(parser, YP_TOKEN_COMMA)); } @@ -9681,7 +9670,7 @@ parse_conditional(yp_parser_t *parser, yp_context_t context) { // can be transformed into write targets. #define YP_CASE_WRITABLE YP_CLASS_VARIABLE_READ_NODE: case YP_CONSTANT_PATH_NODE: \ case YP_CONSTANT_READ_NODE: case YP_GLOBAL_VARIABLE_READ_NODE: case YP_LOCAL_VARIABLE_READ_NODE: \ - case YP_INSTANCE_VARIABLE_READ_NODE: case YP_MULTI_WRITE_NODE: case YP_BACK_REFERENCE_READ_NODE: \ + case YP_INSTANCE_VARIABLE_READ_NODE: case YP_MULTI_TARGET_NODE: case YP_BACK_REFERENCE_READ_NODE: \ case YP_NUMBERED_REFERENCE_READ_NODE // Parse a node that is part of a string. If the subsequent tokens cannot be @@ -10956,29 +10945,27 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { yp_accepts_block_stack_pop(parser); // If we have a single statement and are ending on a right parenthesis, - // then we need to check if this is possibly a multiple assignment node. - if (binding_power == YP_BINDING_POWER_STATEMENT && YP_NODE_TYPE_P(statement, YP_MULTI_WRITE_NODE)) { - yp_multi_write_node_t *multi_statement = (yp_multi_write_node_t *) statement; - - if (multi_statement->value == NULL) { - yp_location_t lparen_loc = YP_LOCATION_TOKEN_VALUE(&opening); - yp_location_t rparen_loc = YP_LOCATION_TOKEN_VALUE(&parser->previous); - yp_multi_write_node_t *multi_write; - - if (multi_statement->lparen_loc.start == NULL) { - multi_write = (yp_multi_write_node_t *) statement; - multi_write->base.location.start = lparen_loc.start; - multi_write->base.location.end = rparen_loc.end; - multi_write->lparen_loc = lparen_loc; - multi_write->rparen_loc = rparen_loc; - } else { - yp_token_t operator = not_provided(parser); - multi_write = yp_multi_write_node_create(parser, &operator, NULL, &lparen_loc, &rparen_loc); - yp_multi_write_node_targets_append(multi_write, statement); - } - - return parse_targets(parser, (yp_node_t *) multi_write, YP_BINDING_POWER_INDEX); + // then we need to check if this is possibly a multiple target node. + if (binding_power == YP_BINDING_POWER_STATEMENT && YP_NODE_TYPE_P(statement, YP_MULTI_TARGET_NODE)) { + yp_node_t *target; + yp_multi_target_node_t *multi_target = (yp_multi_target_node_t *) statement; + + yp_location_t lparen_loc = YP_LOCATION_TOKEN_VALUE(&opening); + yp_location_t rparen_loc = YP_LOCATION_TOKEN_VALUE(&parser->previous); + + if (multi_target->lparen_loc.start == NULL) { + multi_target->base.location.start = lparen_loc.start; + multi_target->base.location.end = rparen_loc.end; + multi_target->lparen_loc = lparen_loc; + multi_target->rparen_loc = rparen_loc; + target = (yp_node_t *) multi_target; + } else { + yp_multi_target_node_t *parent_target = yp_multi_target_node_create(parser); + yp_multi_target_node_targets_append(parent_target, (yp_node_t *) multi_target); + target = (yp_node_t *) parent_target; } + + return parse_targets(parser, target, YP_BINDING_POWER_INDEX); } // If we have a single statement and are ending on a right parenthesis From c7d61181d068b3471386749b6899dc7d3005273c Mon Sep 17 00:00:00 2001 From: Kevin Newton Date: Thu, 7 Sep 2023 14:20:18 -0400 Subject: [PATCH 35/46] [ruby/yarp] Flatten multitarget into multiwrite https://github.com/ruby/yarp/commit/1021dac372 --- test/yarp/location_test.rb | 16 +- test/yarp/snapshots/arrays.txt | 80 ++-- test/yarp/snapshots/method_calls.txt | 72 ++-- .../seattlerb/masgn_anon_splat_arg.txt | 10 +- .../seattlerb/masgn_arg_colon_arg.txt | 30 +- .../snapshots/seattlerb/masgn_arg_ident.txt | 30 +- .../seattlerb/masgn_arg_splat_arg.txt | 12 +- .../yarp/snapshots/seattlerb/masgn_colon2.txt | 18 +- .../yarp/snapshots/seattlerb/masgn_colon3.txt | 26 +- .../seattlerb/masgn_command_call.txt | 9 +- .../seattlerb/masgn_double_paren.txt | 18 +- .../snapshots/seattlerb/masgn_lhs_splat.txt | 8 +- test/yarp/snapshots/seattlerb/masgn_paren.txt | 10 +- .../snapshots/seattlerb/masgn_splat_arg.txt | 18 +- .../seattlerb/masgn_splat_arg_arg.txt | 20 +- test/yarp/snapshots/seattlerb/masgn_star.txt | 4 +- .../seattlerb/masgn_var_star_var.txt | 12 +- .../seattlerb/mlhs_back_anonsplat.txt | 14 +- .../snapshots/seattlerb/mlhs_back_splat.txt | 17 +- .../seattlerb/mlhs_front_anonsplat.txt | 14 +- .../snapshots/seattlerb/mlhs_front_splat.txt | 22 +- .../seattlerb/mlhs_mid_anonsplat.txt | 20 +- .../snapshots/seattlerb/mlhs_mid_splat.txt | 20 +- test/yarp/snapshots/seattlerb/mlhs_rescue.txt | 10 +- .../snapshots/seattlerb/parse_line_to_ary.txt | 10 +- .../unparser/corpus/literal/assignment.txt | 356 ++++++++---------- .../unparser/corpus/literal/defined.txt | 10 +- .../unparser/corpus/literal/send.txt | 10 +- test/yarp/snapshots/variables.txt | 86 ++--- .../snapshots/whitequark/and_or_masgn.txt | 20 +- .../snapshots/whitequark/cond_begin_masgn.txt | 10 +- .../snapshots/whitequark/if_masgn__24.txt | 10 +- test/yarp/snapshots/whitequark/masgn.txt | 32 +- test/yarp/snapshots/whitequark/masgn_attr.txt | 112 +++--- test/yarp/snapshots/whitequark/masgn_cmd.txt | 10 +- .../yarp/snapshots/whitequark/masgn_const.txt | 36 +- .../snapshots/whitequark/masgn_nested.txt | 38 +- .../yarp/snapshots/whitequark/masgn_splat.txt | 134 +++---- .../snapshots/whitequark/not_masgn__24.txt | 10 +- .../snapshots/whitequark/rescue_mod_masgn.txt | 10 +- yarp/config.yml | 9 +- yarp/yarp.c | 8 +- 42 files changed, 638 insertions(+), 783 deletions(-) diff --git a/test/yarp/location_test.rb b/test/yarp/location_test.rb index 386177122da92e..6b219a0b3664c3 100644 --- a/test/yarp/location_test.rb +++ b/test/yarp/location_test.rb @@ -223,7 +223,7 @@ def test_ClassVariableReadNode def test_ClassVariableTargetNode assert_location(ClassVariableTargetNode, "@@foo, @@bar = baz", 0...5) do |node| - node.target.targets.first + node.targets.first end end @@ -251,7 +251,7 @@ def test_ConstantPathOrWriteNode def test_ConstantPathTargetNode assert_location(ConstantPathTargetNode, "::Foo, ::Bar = baz", 0...5) do |node| - node.target.targets.first + node.targets.first end end @@ -280,7 +280,7 @@ def test_ConstantReadNode def test_ConstantTargetNode assert_location(ConstantTargetNode, "Foo, Bar = baz", 0...3) do |node| - node.target.targets.first + node.targets.first end end @@ -378,7 +378,7 @@ def test_GlobalVariableReadNode def test_GlobalVariableTargetNode assert_location(GlobalVariableTargetNode, "$foo, $bar = baz", 0...4) do |node| - node.target.targets.first + node.targets.first end end @@ -430,7 +430,7 @@ def test_InstanceVariableReadNode def test_InstanceVariableTargetNode assert_location(InstanceVariableTargetNode, "@foo, @bar = baz", 0...4) do |node| - node.target.targets.first + node.targets.first end end @@ -517,7 +517,7 @@ def test_LocalVariableReadNode def test_LocalVariableTargetNode assert_location(LocalVariableTargetNode, "foo, bar = baz", 0...3) do |node| - node.target.targets.first + node.targets.first end end @@ -539,7 +539,7 @@ def test_ModuleNode def test_MultiTargetNode assert_location(MultiTargetNode, "for foo, bar in baz do end", 4...12, &:index) - assert_location(MultiTargetNode, "foo, bar = baz", 0...8, &:target) + assert_location(MultiTargetNode, "foo, (bar, baz) = qux", 5...15) { |node| node.targets.last } end def test_MultiWriteNode @@ -695,7 +695,7 @@ def test_SourceLineNode end def test_SplatNode - assert_location(SplatNode, "*foo = bar", 0...4) { |node| node.target.targets.first } + assert_location(SplatNode, "*foo = bar", 0...4) { |node| node.targets.first } end def test_StatementsNode diff --git a/test/yarp/snapshots/arrays.txt b/test/yarp/snapshots/arrays.txt index b8f87295b45fb4..a29cbeecb56433 100644 --- a/test/yarp/snapshots/arrays.txt +++ b/test/yarp/snapshots/arrays.txt @@ -317,52 +317,50 @@ ProgramNode(0...511)( "[]=" ), MultiWriteNode(191...212)( - MultiTargetNode(191...205)( - [CallNode(191...197)( - CallNode(191...194)( - nil, - nil, - (191...194), - nil, - nil, - nil, - nil, - 2, - "foo" - ), + [CallNode(191...197)( + CallNode(191...194)( nil, - (194...197), - (194...195), - ArgumentsNode(195...196)([IntegerNode(195...196)()]), - (196...197), nil, - 0, - "[]=" + (191...194), + nil, + nil, + nil, + nil, + 2, + "foo" ), - CallNode(199...205)( - CallNode(199...202)( - nil, - nil, - (199...202), - nil, - nil, - nil, - nil, - 2, - "bar" - ), + nil, + (194...197), + (194...195), + ArgumentsNode(195...196)([IntegerNode(195...196)()]), + (196...197), + nil, + 0, + "[]=" + ), + CallNode(199...205)( + CallNode(199...202)( nil, - (202...205), - (202...203), - ArgumentsNode(203...204)([IntegerNode(203...204)()]), - (204...205), nil, - 0, - "[]=" - )], - nil, - nil - ), + (199...202), + nil, + nil, + nil, + nil, + 2, + "bar" + ), + nil, + (202...205), + (202...203), + ArgumentsNode(203...204)([IntegerNode(203...204)()]), + (204...205), + nil, + 0, + "[]=" + )], + nil, + nil, (206...207), ArrayNode(208...212)( [IntegerNode(208...209)(), IntegerNode(211...212)()], diff --git a/test/yarp/snapshots/method_calls.txt b/test/yarp/snapshots/method_calls.txt index 7ab43d0a844ed7..37f03ef25f572c 100644 --- a/test/yarp/snapshots/method_calls.txt +++ b/test/yarp/snapshots/method_calls.txt @@ -348,52 +348,50 @@ ProgramNode(0...1237)( "b" ), MultiWriteNode(181...204)( - MultiTargetNode(181...197)( - [CallNode(181...188)( - CallNode(181...184)( - nil, - nil, - (181...184), - nil, - nil, - nil, - nil, - 2, - "foo" - ), - (184...185), - (185...188), + [CallNode(181...188)( + CallNode(181...184)( nil, nil, + (181...184), nil, nil, - 0, - "foo=" + nil, + nil, + 2, + "foo" ), - CallNode(190...197)( - CallNode(190...193)( - nil, - nil, - (190...193), - nil, - nil, - nil, - nil, - 2, - "bar" - ), - (193...194), - (194...197), + (184...185), + (185...188), + nil, + nil, + nil, + nil, + 0, + "foo=" + ), + CallNode(190...197)( + CallNode(190...193)( nil, nil, + (190...193), nil, nil, - 0, - "bar=" - )], - nil, - nil - ), + nil, + nil, + 2, + "bar" + ), + (193...194), + (194...197), + nil, + nil, + nil, + nil, + 0, + "bar=" + )], + nil, + nil, (198...199), ArrayNode(200...204)( [IntegerNode(200...201)(), IntegerNode(203...204)()], diff --git a/test/yarp/snapshots/seattlerb/masgn_anon_splat_arg.txt b/test/yarp/snapshots/seattlerb/masgn_anon_splat_arg.txt index e52928eb916264..2fb68f7b6db4ea 100644 --- a/test/yarp/snapshots/seattlerb/masgn_anon_splat_arg.txt +++ b/test/yarp/snapshots/seattlerb/masgn_anon_splat_arg.txt @@ -2,12 +2,10 @@ ProgramNode(0...8)( [:a], StatementsNode(0...8)( [MultiWriteNode(0...8)( - MultiTargetNode(0...4)( - [MultiTargetNode(0...1)([SplatNode(0...1)((0...1), nil)], nil, nil), - LocalVariableTargetNode(3...4)(:a, 0)], - nil, - nil - ), + [MultiTargetNode(0...1)([SplatNode(0...1)((0...1), nil)], nil, nil), + LocalVariableTargetNode(3...4)(:a, 0)], + nil, + nil, (5...6), CallNode(7...8)(nil, nil, (7...8), nil, nil, nil, nil, 2, "b") )] diff --git a/test/yarp/snapshots/seattlerb/masgn_arg_colon_arg.txt b/test/yarp/snapshots/seattlerb/masgn_arg_colon_arg.txt index a13a84f116dd8f..fd2eeb213aa871 100644 --- a/test/yarp/snapshots/seattlerb/masgn_arg_colon_arg.txt +++ b/test/yarp/snapshots/seattlerb/masgn_arg_colon_arg.txt @@ -2,22 +2,20 @@ ProgramNode(0...11)( [:a], StatementsNode(0...11)( [MultiWriteNode(0...11)( - MultiTargetNode(0...7)( - [LocalVariableTargetNode(0...1)(:a, 0), - CallNode(3...7)( - CallNode(3...4)(nil, nil, (3...4), nil, nil, nil, nil, 2, "b"), - (4...6), - (6...7), - nil, - nil, - nil, - nil, - 0, - "c=" - )], - nil, - nil - ), + [LocalVariableTargetNode(0...1)(:a, 0), + CallNode(3...7)( + CallNode(3...4)(nil, nil, (3...4), nil, nil, nil, nil, 2, "b"), + (4...6), + (6...7), + nil, + nil, + nil, + nil, + 0, + "c=" + )], + nil, + nil, (8...9), CallNode(10...11)(nil, nil, (10...11), nil, nil, nil, nil, 2, "d") )] diff --git a/test/yarp/snapshots/seattlerb/masgn_arg_ident.txt b/test/yarp/snapshots/seattlerb/masgn_arg_ident.txt index 53d5be38d60df4..a8b17ce70710c1 100644 --- a/test/yarp/snapshots/seattlerb/masgn_arg_ident.txt +++ b/test/yarp/snapshots/seattlerb/masgn_arg_ident.txt @@ -2,22 +2,20 @@ ProgramNode(0...10)( [:a], StatementsNode(0...10)( [MultiWriteNode(0...10)( - MultiTargetNode(0...6)( - [LocalVariableTargetNode(0...1)(:a, 0), - CallNode(3...6)( - CallNode(3...4)(nil, nil, (3...4), nil, nil, nil, nil, 2, "b"), - (4...5), - (5...6), - nil, - nil, - nil, - nil, - 0, - "C=" - )], - nil, - nil - ), + [LocalVariableTargetNode(0...1)(:a, 0), + CallNode(3...6)( + CallNode(3...4)(nil, nil, (3...4), nil, nil, nil, nil, 2, "b"), + (4...5), + (5...6), + nil, + nil, + nil, + nil, + 0, + "C=" + )], + nil, + nil, (7...8), CallNode(9...10)(nil, nil, (9...10), nil, nil, nil, nil, 2, "d") )] diff --git a/test/yarp/snapshots/seattlerb/masgn_arg_splat_arg.txt b/test/yarp/snapshots/seattlerb/masgn_arg_splat_arg.txt index 52fd5f6317b940..e922b3b5e8737e 100644 --- a/test/yarp/snapshots/seattlerb/masgn_arg_splat_arg.txt +++ b/test/yarp/snapshots/seattlerb/masgn_arg_splat_arg.txt @@ -2,13 +2,11 @@ ProgramNode(0...12)( [:a, :b, :c], StatementsNode(0...12)( [MultiWriteNode(0...12)( - MultiTargetNode(0...8)( - [LocalVariableTargetNode(0...1)(:a, 0), - SplatNode(3...5)((3...4), LocalVariableTargetNode(4...5)(:b, 0)), - LocalVariableTargetNode(7...8)(:c, 0)], - nil, - nil - ), + [LocalVariableTargetNode(0...1)(:a, 0), + SplatNode(3...5)((3...4), LocalVariableTargetNode(4...5)(:b, 0)), + LocalVariableTargetNode(7...8)(:c, 0)], + nil, + nil, (9...10), CallNode(11...12)(nil, nil, (11...12), nil, nil, nil, nil, 2, "d") )] diff --git a/test/yarp/snapshots/seattlerb/masgn_colon2.txt b/test/yarp/snapshots/seattlerb/masgn_colon2.txt index d2eca1dc3235b1..d9a2744466fb45 100644 --- a/test/yarp/snapshots/seattlerb/masgn_colon2.txt +++ b/test/yarp/snapshots/seattlerb/masgn_colon2.txt @@ -2,16 +2,14 @@ ProgramNode(0...14)( [:a], StatementsNode(0...14)( [MultiWriteNode(0...14)( - MultiTargetNode(0...7)( - [LocalVariableTargetNode(0...1)(:a, 0), - ConstantPathTargetNode(3...7)( - CallNode(3...4)(nil, nil, (3...4), nil, nil, nil, nil, 2, "b"), - ConstantReadNode(6...7)(:C), - (4...6) - )], - nil, - nil - ), + [LocalVariableTargetNode(0...1)(:a, 0), + ConstantPathTargetNode(3...7)( + CallNode(3...4)(nil, nil, (3...4), nil, nil, nil, nil, 2, "b"), + ConstantReadNode(6...7)(:C), + (4...6) + )], + nil, + nil, (8...9), ArrayNode(10...14)( [IntegerNode(10...11)(), IntegerNode(13...14)()], diff --git a/test/yarp/snapshots/seattlerb/masgn_colon3.txt b/test/yarp/snapshots/seattlerb/masgn_colon3.txt index 7446135fdce0c6..355f40f1cfb8fd 100644 --- a/test/yarp/snapshots/seattlerb/masgn_colon3.txt +++ b/test/yarp/snapshots/seattlerb/masgn_colon3.txt @@ -2,20 +2,18 @@ ProgramNode(0...15)( [], StatementsNode(0...15)( [MultiWriteNode(0...15)( - MultiTargetNode(0...8)( - [ConstantPathTargetNode(0...3)( - nil, - ConstantReadNode(2...3)(:A), - (0...2) - ), - ConstantPathTargetNode(5...8)( - nil, - ConstantReadNode(7...8)(:B), - (5...7) - )], - nil, - nil - ), + [ConstantPathTargetNode(0...3)( + nil, + ConstantReadNode(2...3)(:A), + (0...2) + ), + ConstantPathTargetNode(5...8)( + nil, + ConstantReadNode(7...8)(:B), + (5...7) + )], + nil, + nil, (9...10), ArrayNode(11...15)( [IntegerNode(11...12)(), IntegerNode(14...15)()], diff --git a/test/yarp/snapshots/seattlerb/masgn_command_call.txt b/test/yarp/snapshots/seattlerb/masgn_command_call.txt index 39cf7446d49ca8..4563136c2f2bc8 100644 --- a/test/yarp/snapshots/seattlerb/masgn_command_call.txt +++ b/test/yarp/snapshots/seattlerb/masgn_command_call.txt @@ -2,12 +2,9 @@ ProgramNode(0...10)( [:a], StatementsNode(0...10)( [MultiWriteNode(0...10)( - MultiTargetNode(0...2)( - [LocalVariableTargetNode(0...1)(:a, 0), - SplatNode(1...2)((1...2), nil)], - nil, - nil - ), + [LocalVariableTargetNode(0...1)(:a, 0), SplatNode(1...2)((1...2), nil)], + nil, + nil, (3...4), CallNode(5...10)( CallNode(5...6)(nil, nil, (5...6), nil, nil, nil, nil, 2, "b"), diff --git a/test/yarp/snapshots/seattlerb/masgn_double_paren.txt b/test/yarp/snapshots/seattlerb/masgn_double_paren.txt index eaadbbc2c7722f..107be851e3a907 100644 --- a/test/yarp/snapshots/seattlerb/masgn_double_paren.txt +++ b/test/yarp/snapshots/seattlerb/masgn_double_paren.txt @@ -2,16 +2,14 @@ ProgramNode(1...9)( [:a, :b], StatementsNode(1...9)( [MultiWriteNode(1...9)( - MultiTargetNode(1...6)( - [MultiTargetNode(1...6)( - [LocalVariableTargetNode(2...3)(:a, 0), - LocalVariableTargetNode(4...5)(:b, 0)], - (1...2), - (5...6) - )], - nil, - nil - ), + [MultiTargetNode(1...6)( + [LocalVariableTargetNode(2...3)(:a, 0), + LocalVariableTargetNode(4...5)(:b, 0)], + (1...2), + (5...6) + )], + nil, + nil, (7...8), CallNode(8...9)(nil, nil, (8...9), nil, nil, nil, nil, 2, "c") )] diff --git a/test/yarp/snapshots/seattlerb/masgn_lhs_splat.txt b/test/yarp/snapshots/seattlerb/masgn_lhs_splat.txt index 04418018dd7e00..4730ed961825b7 100644 --- a/test/yarp/snapshots/seattlerb/masgn_lhs_splat.txt +++ b/test/yarp/snapshots/seattlerb/masgn_lhs_splat.txt @@ -2,11 +2,9 @@ ProgramNode(0...12)( [:a], StatementsNode(0...12)( [MultiWriteNode(0...12)( - MultiTargetNode(0...2)( - [SplatNode(0...2)((0...1), LocalVariableTargetNode(1...2)(:a, 0))], - nil, - nil - ), + [SplatNode(0...2)((0...1), LocalVariableTargetNode(1...2)(:a, 0))], + nil, + nil, (3...4), ArrayNode(5...12)( [IntegerNode(5...6)(), IntegerNode(8...9)(), IntegerNode(11...12)()], diff --git a/test/yarp/snapshots/seattlerb/masgn_paren.txt b/test/yarp/snapshots/seattlerb/masgn_paren.txt index e8e0d72a88db27..32b4fc2989b576 100644 --- a/test/yarp/snapshots/seattlerb/masgn_paren.txt +++ b/test/yarp/snapshots/seattlerb/masgn_paren.txt @@ -2,12 +2,10 @@ ProgramNode(0...12)( [:a, :b], StatementsNode(0...12)( [MultiWriteNode(0...12)( - MultiTargetNode(0...6)( - [LocalVariableTargetNode(1...2)(:a, 0), - LocalVariableTargetNode(4...5)(:b, 0)], - (0...1), - (5...6) - ), + [LocalVariableTargetNode(1...2)(:a, 0), + LocalVariableTargetNode(4...5)(:b, 0)], + (0...1), + (5...6), (7...8), CallNode(9...12)( CallNode(9...10)(nil, nil, (9...10), nil, nil, nil, nil, 2, "c"), diff --git a/test/yarp/snapshots/seattlerb/masgn_splat_arg.txt b/test/yarp/snapshots/seattlerb/masgn_splat_arg.txt index a93904b9e026f1..e2729a861dc8f1 100644 --- a/test/yarp/snapshots/seattlerb/masgn_splat_arg.txt +++ b/test/yarp/snapshots/seattlerb/masgn_splat_arg.txt @@ -2,16 +2,14 @@ ProgramNode(0...9)( [:a, :b], StatementsNode(0...9)( [MultiWriteNode(0...9)( - MultiTargetNode(0...5)( - [MultiTargetNode(0...2)( - [SplatNode(0...2)((0...1), LocalVariableTargetNode(1...2)(:a, 0))], - nil, - nil - ), - LocalVariableTargetNode(4...5)(:b, 0)], - nil, - nil - ), + [MultiTargetNode(0...2)( + [SplatNode(0...2)((0...1), LocalVariableTargetNode(1...2)(:a, 0))], + nil, + nil + ), + LocalVariableTargetNode(4...5)(:b, 0)], + nil, + nil, (6...7), CallNode(8...9)(nil, nil, (8...9), nil, nil, nil, nil, 2, "c") )] diff --git a/test/yarp/snapshots/seattlerb/masgn_splat_arg_arg.txt b/test/yarp/snapshots/seattlerb/masgn_splat_arg_arg.txt index 5f95091cf744b1..bd6a51261480a3 100644 --- a/test/yarp/snapshots/seattlerb/masgn_splat_arg_arg.txt +++ b/test/yarp/snapshots/seattlerb/masgn_splat_arg_arg.txt @@ -2,17 +2,15 @@ ProgramNode(0...12)( [:a, :b, :c], StatementsNode(0...12)( [MultiWriteNode(0...12)( - MultiTargetNode(0...8)( - [MultiTargetNode(0...2)( - [SplatNode(0...2)((0...1), LocalVariableTargetNode(1...2)(:a, 0))], - nil, - nil - ), - LocalVariableTargetNode(4...5)(:b, 0), - LocalVariableTargetNode(7...8)(:c, 0)], - nil, - nil - ), + [MultiTargetNode(0...2)( + [SplatNode(0...2)((0...1), LocalVariableTargetNode(1...2)(:a, 0))], + nil, + nil + ), + LocalVariableTargetNode(4...5)(:b, 0), + LocalVariableTargetNode(7...8)(:c, 0)], + nil, + nil, (9...10), CallNode(11...12)(nil, nil, (11...12), nil, nil, nil, nil, 2, "d") )] diff --git a/test/yarp/snapshots/seattlerb/masgn_star.txt b/test/yarp/snapshots/seattlerb/masgn_star.txt index 23c162c8395c1b..015e5edcc9cbcd 100644 --- a/test/yarp/snapshots/seattlerb/masgn_star.txt +++ b/test/yarp/snapshots/seattlerb/masgn_star.txt @@ -2,7 +2,9 @@ ProgramNode(0...5)( [], StatementsNode(0...5)( [MultiWriteNode(0...5)( - MultiTargetNode(0...1)([SplatNode(0...1)((0...1), nil)], nil, nil), + [SplatNode(0...1)((0...1), nil)], + nil, + nil, (2...3), IntegerNode(4...5)() )] diff --git a/test/yarp/snapshots/seattlerb/masgn_var_star_var.txt b/test/yarp/snapshots/seattlerb/masgn_var_star_var.txt index 59bb88d1edd4f7..f6d0136d99ffee 100644 --- a/test/yarp/snapshots/seattlerb/masgn_var_star_var.txt +++ b/test/yarp/snapshots/seattlerb/masgn_var_star_var.txt @@ -2,13 +2,11 @@ ProgramNode(0...11)( [:a, :b], StatementsNode(0...11)( [MultiWriteNode(0...11)( - MultiTargetNode(0...7)( - [LocalVariableTargetNode(0...1)(:a, 0), - SplatNode(3...4)((3...4), nil), - LocalVariableTargetNode(6...7)(:b, 0)], - nil, - nil - ), + [LocalVariableTargetNode(0...1)(:a, 0), + SplatNode(3...4)((3...4), nil), + LocalVariableTargetNode(6...7)(:b, 0)], + nil, + nil, (8...9), CallNode(10...11)(nil, nil, (10...11), nil, nil, nil, nil, 2, "c") )] diff --git a/test/yarp/snapshots/seattlerb/mlhs_back_anonsplat.txt b/test/yarp/snapshots/seattlerb/mlhs_back_anonsplat.txt index 1243734429f6e1..59e954706b19ea 100644 --- a/test/yarp/snapshots/seattlerb/mlhs_back_anonsplat.txt +++ b/test/yarp/snapshots/seattlerb/mlhs_back_anonsplat.txt @@ -2,14 +2,12 @@ ProgramNode(0...14)( [:a, :b, :c], StatementsNode(0...14)( [MultiWriteNode(0...14)( - MultiTargetNode(0...10)( - [LocalVariableTargetNode(0...1)(:a, 0), - LocalVariableTargetNode(3...4)(:b, 0), - LocalVariableTargetNode(6...7)(:c, 0), - SplatNode(9...10)((9...10), nil)], - nil, - nil - ), + [LocalVariableTargetNode(0...1)(:a, 0), + LocalVariableTargetNode(3...4)(:b, 0), + LocalVariableTargetNode(6...7)(:c, 0), + SplatNode(9...10)((9...10), nil)], + nil, + nil, (11...12), CallNode(13...14)(nil, nil, (13...14), nil, nil, nil, nil, 2, "f") )] diff --git a/test/yarp/snapshots/seattlerb/mlhs_back_splat.txt b/test/yarp/snapshots/seattlerb/mlhs_back_splat.txt index 05ff01d1bc5d46..8014663bd34ffa 100644 --- a/test/yarp/snapshots/seattlerb/mlhs_back_splat.txt +++ b/test/yarp/snapshots/seattlerb/mlhs_back_splat.txt @@ -2,17 +2,12 @@ ProgramNode(0...15)( [:a, :b, :c, :s], StatementsNode(0...15)( [MultiWriteNode(0...15)( - MultiTargetNode(0...11)( - [LocalVariableTargetNode(0...1)(:a, 0), - LocalVariableTargetNode(3...4)(:b, 0), - LocalVariableTargetNode(6...7)(:c, 0), - SplatNode(9...11)( - (9...10), - LocalVariableTargetNode(10...11)(:s, 0) - )], - nil, - nil - ), + [LocalVariableTargetNode(0...1)(:a, 0), + LocalVariableTargetNode(3...4)(:b, 0), + LocalVariableTargetNode(6...7)(:c, 0), + SplatNode(9...11)((9...10), LocalVariableTargetNode(10...11)(:s, 0))], + nil, + nil, (12...13), CallNode(14...15)(nil, nil, (14...15), nil, nil, nil, nil, 2, "f") )] diff --git a/test/yarp/snapshots/seattlerb/mlhs_front_anonsplat.txt b/test/yarp/snapshots/seattlerb/mlhs_front_anonsplat.txt index 0655ff46bd4149..74a63d328bfe58 100644 --- a/test/yarp/snapshots/seattlerb/mlhs_front_anonsplat.txt +++ b/test/yarp/snapshots/seattlerb/mlhs_front_anonsplat.txt @@ -2,14 +2,12 @@ ProgramNode(0...14)( [:x, :y, :z], StatementsNode(0...14)( [MultiWriteNode(0...14)( - MultiTargetNode(0...10)( - [MultiTargetNode(0...1)([SplatNode(0...1)((0...1), nil)], nil, nil), - LocalVariableTargetNode(3...4)(:x, 0), - LocalVariableTargetNode(6...7)(:y, 0), - LocalVariableTargetNode(9...10)(:z, 0)], - nil, - nil - ), + [MultiTargetNode(0...1)([SplatNode(0...1)((0...1), nil)], nil, nil), + LocalVariableTargetNode(3...4)(:x, 0), + LocalVariableTargetNode(6...7)(:y, 0), + LocalVariableTargetNode(9...10)(:z, 0)], + nil, + nil, (11...12), CallNode(13...14)(nil, nil, (13...14), nil, nil, nil, nil, 2, "f") )] diff --git a/test/yarp/snapshots/seattlerb/mlhs_front_splat.txt b/test/yarp/snapshots/seattlerb/mlhs_front_splat.txt index 4e8082cbaffa9e..f3110882cc1133 100644 --- a/test/yarp/snapshots/seattlerb/mlhs_front_splat.txt +++ b/test/yarp/snapshots/seattlerb/mlhs_front_splat.txt @@ -2,18 +2,16 @@ ProgramNode(0...15)( [:s, :x, :y, :z], StatementsNode(0...15)( [MultiWriteNode(0...15)( - MultiTargetNode(0...11)( - [MultiTargetNode(0...2)( - [SplatNode(0...2)((0...1), LocalVariableTargetNode(1...2)(:s, 0))], - nil, - nil - ), - LocalVariableTargetNode(4...5)(:x, 0), - LocalVariableTargetNode(7...8)(:y, 0), - LocalVariableTargetNode(10...11)(:z, 0)], - nil, - nil - ), + [MultiTargetNode(0...2)( + [SplatNode(0...2)((0...1), LocalVariableTargetNode(1...2)(:s, 0))], + nil, + nil + ), + LocalVariableTargetNode(4...5)(:x, 0), + LocalVariableTargetNode(7...8)(:y, 0), + LocalVariableTargetNode(10...11)(:z, 0)], + nil, + nil, (12...13), CallNode(14...15)(nil, nil, (14...15), nil, nil, nil, nil, 2, "f") )] diff --git a/test/yarp/snapshots/seattlerb/mlhs_mid_anonsplat.txt b/test/yarp/snapshots/seattlerb/mlhs_mid_anonsplat.txt index 1e4f4bb53baa67..c0e3acc145169f 100644 --- a/test/yarp/snapshots/seattlerb/mlhs_mid_anonsplat.txt +++ b/test/yarp/snapshots/seattlerb/mlhs_mid_anonsplat.txt @@ -2,17 +2,15 @@ ProgramNode(0...23)( [:a, :b, :c, :x, :y, :z], StatementsNode(0...23)( [MultiWriteNode(0...23)( - MultiTargetNode(0...19)( - [LocalVariableTargetNode(0...1)(:a, 0), - LocalVariableTargetNode(3...4)(:b, 0), - LocalVariableTargetNode(6...7)(:c, 0), - SplatNode(9...10)((9...10), nil), - LocalVariableTargetNode(12...13)(:x, 0), - LocalVariableTargetNode(15...16)(:y, 0), - LocalVariableTargetNode(18...19)(:z, 0)], - nil, - nil - ), + [LocalVariableTargetNode(0...1)(:a, 0), + LocalVariableTargetNode(3...4)(:b, 0), + LocalVariableTargetNode(6...7)(:c, 0), + SplatNode(9...10)((9...10), nil), + LocalVariableTargetNode(12...13)(:x, 0), + LocalVariableTargetNode(15...16)(:y, 0), + LocalVariableTargetNode(18...19)(:z, 0)], + nil, + nil, (20...21), CallNode(22...23)(nil, nil, (22...23), nil, nil, nil, nil, 2, "f") )] diff --git a/test/yarp/snapshots/seattlerb/mlhs_mid_splat.txt b/test/yarp/snapshots/seattlerb/mlhs_mid_splat.txt index 8fd7b6f3aac0dc..46d81adf646bb7 100644 --- a/test/yarp/snapshots/seattlerb/mlhs_mid_splat.txt +++ b/test/yarp/snapshots/seattlerb/mlhs_mid_splat.txt @@ -2,17 +2,15 @@ ProgramNode(0...24)( [:a, :b, :c, :s, :x, :y, :z], StatementsNode(0...24)( [MultiWriteNode(0...24)( - MultiTargetNode(0...20)( - [LocalVariableTargetNode(0...1)(:a, 0), - LocalVariableTargetNode(3...4)(:b, 0), - LocalVariableTargetNode(6...7)(:c, 0), - SplatNode(9...11)((9...10), LocalVariableTargetNode(10...11)(:s, 0)), - LocalVariableTargetNode(13...14)(:x, 0), - LocalVariableTargetNode(16...17)(:y, 0), - LocalVariableTargetNode(19...20)(:z, 0)], - nil, - nil - ), + [LocalVariableTargetNode(0...1)(:a, 0), + LocalVariableTargetNode(3...4)(:b, 0), + LocalVariableTargetNode(6...7)(:c, 0), + SplatNode(9...11)((9...10), LocalVariableTargetNode(10...11)(:s, 0)), + LocalVariableTargetNode(13...14)(:x, 0), + LocalVariableTargetNode(16...17)(:y, 0), + LocalVariableTargetNode(19...20)(:z, 0)], + nil, + nil, (21...22), CallNode(23...24)(nil, nil, (23...24), nil, nil, nil, nil, 2, "f") )] diff --git a/test/yarp/snapshots/seattlerb/mlhs_rescue.txt b/test/yarp/snapshots/seattlerb/mlhs_rescue.txt index 8d39772c8daad1..427c56dfea2b4a 100644 --- a/test/yarp/snapshots/seattlerb/mlhs_rescue.txt +++ b/test/yarp/snapshots/seattlerb/mlhs_rescue.txt @@ -2,12 +2,10 @@ ProgramNode(0...18)( [:a, :b], StatementsNode(0...18)( [MultiWriteNode(0...18)( - MultiTargetNode(0...4)( - [LocalVariableTargetNode(0...1)(:a, 0), - LocalVariableTargetNode(3...4)(:b, 0)], - nil, - nil - ), + [LocalVariableTargetNode(0...1)(:a, 0), + LocalVariableTargetNode(3...4)(:b, 0)], + nil, + nil, (5...6), RescueModifierNode(7...18)( CallNode(7...8)(nil, nil, (7...8), nil, nil, nil, nil, 2, "f"), diff --git a/test/yarp/snapshots/seattlerb/parse_line_to_ary.txt b/test/yarp/snapshots/seattlerb/parse_line_to_ary.txt index 39afa6816b69c8..e8736976c78a9c 100644 --- a/test/yarp/snapshots/seattlerb/parse_line_to_ary.txt +++ b/test/yarp/snapshots/seattlerb/parse_line_to_ary.txt @@ -2,12 +2,10 @@ ProgramNode(0...10)( [:a, :b], StatementsNode(0...10)( [MultiWriteNode(0...8)( - MultiTargetNode(0...4)( - [LocalVariableTargetNode(0...1)(:a, 0), - LocalVariableTargetNode(3...4)(:b, 0)], - nil, - nil - ), + [LocalVariableTargetNode(0...1)(:a, 0), + LocalVariableTargetNode(3...4)(:b, 0)], + nil, + nil, (5...6), CallNode(7...8)(nil, nil, (7...8), nil, nil, nil, nil, 2, "c") ), diff --git a/test/yarp/snapshots/unparser/corpus/literal/assignment.txt b/test/yarp/snapshots/unparser/corpus/literal/assignment.txt index 658cb37c5cc1c9..3f82c3a8e40bac 100644 --- a/test/yarp/snapshots/unparser/corpus/literal/assignment.txt +++ b/test/yarp/snapshots/unparser/corpus/literal/assignment.txt @@ -8,12 +8,10 @@ ProgramNode(0...704)( (3...4) ), MultiWriteNode(7...24)( - MultiTargetNode(7...15)( - [GlobalVariableTargetNode(8...10)(:$a), - GlobalVariableTargetNode(12...14)(:$b)], - (7...8), - (14...15) - ), + [GlobalVariableTargetNode(8...10)(:$a), + GlobalVariableTargetNode(12...14)(:$b)], + (7...8), + (14...15), (16...17), ArrayNode(18...24)( [IntegerNode(19...20)(), IntegerNode(22...23)()], @@ -22,41 +20,35 @@ ProgramNode(0...704)( ) ), MultiWriteNode(25...38)( - MultiTargetNode(25...34)( - [MultiTargetNode(26...30)( - [LocalVariableTargetNode(27...28)(:a, 0), - SplatNode(28...29)((28...29), nil)], - (26...27), - (29...30) - ), - LocalVariableTargetNode(32...33)(:b, 0)], - (25...26), - (33...34) - ), + [MultiTargetNode(26...30)( + [LocalVariableTargetNode(27...28)(:a, 0), + SplatNode(28...29)((28...29), nil)], + (26...27), + (29...30) + ), + LocalVariableTargetNode(32...33)(:b, 0)], + (25...26), + (33...34), (35...36), IntegerNode(37...38)() ), MultiWriteNode(39...48)( - MultiTargetNode(39...43)( - [SplatNode(40...42)( - (40...41), - LocalVariableTargetNode(41...42)(:a, 0) - )], - (39...40), - (42...43) - ), + [SplatNode(40...42)( + (40...41), + LocalVariableTargetNode(41...42)(:a, 0) + )], + (39...40), + (42...43), (44...45), ArrayNode(46...48)([], (46...47), (47...48)) ), MultiWriteNode(49...64)( - MultiTargetNode(49...55)( - [SplatNode(50...54)( - (50...51), - LocalVariableTargetNode(51...54)(:foo, 0) - )], - (49...50), - (54...55) - ), + [SplatNode(50...54)( + (50...51), + LocalVariableTargetNode(51...54)(:foo, 0) + )], + (49...50), + (54...55), (56...57), ArrayNode(58...64)( [IntegerNode(59...60)(), IntegerNode(62...63)()], @@ -65,12 +57,10 @@ ProgramNode(0...704)( ) ), MultiWriteNode(65...84)( - MultiTargetNode(65...75)( - [ClassVariableTargetNode(66...69)(:@@a), - ClassVariableTargetNode(71...74)(:@@b)], - (65...66), - (74...75) - ), + [ClassVariableTargetNode(66...69)(:@@a), + ClassVariableTargetNode(71...74)(:@@b)], + (65...66), + (74...75), (76...77), ArrayNode(78...84)( [IntegerNode(79...80)(), IntegerNode(82...83)()], @@ -79,12 +69,10 @@ ProgramNode(0...704)( ) ), MultiWriteNode(85...102)( - MultiTargetNode(85...93)( - [InstanceVariableTargetNode(86...88)(:@a), - InstanceVariableTargetNode(90...92)(:@b)], - (85...86), - (92...93) - ), + [InstanceVariableTargetNode(86...88)(:@a), + InstanceVariableTargetNode(90...92)(:@b)], + (85...86), + (92...93), (94...95), ArrayNode(96...102)( [IntegerNode(97...98)(), IntegerNode(100...101)()], @@ -93,17 +81,15 @@ ProgramNode(0...704)( ) ), MultiWriteNode(103...128)( - MultiTargetNode(103...114)( - [LocalVariableTargetNode(104...105)(:a, 0), - MultiTargetNode(107...113)( - [LocalVariableTargetNode(108...109)(:b, 0), - LocalVariableTargetNode(111...112)(:c, 0)], - (107...108), - (112...113) - )], - (103...104), - (113...114) - ), + [LocalVariableTargetNode(104...105)(:a, 0), + MultiTargetNode(107...113)( + [LocalVariableTargetNode(108...109)(:b, 0), + LocalVariableTargetNode(111...112)(:c, 0)], + (107...108), + (112...113) + )], + (103...104), + (113...114), (115...116), ArrayNode(117...128)( [IntegerNode(118...119)(), @@ -117,12 +103,10 @@ ProgramNode(0...704)( ) ), MultiWriteNode(129...144)( - MultiTargetNode(129...135)( - [LocalVariableTargetNode(130...131)(:a, 0), - SplatNode(133...134)((133...134), nil)], - (129...130), - (134...135) - ), + [LocalVariableTargetNode(130...131)(:a, 0), + SplatNode(133...134)((133...134), nil)], + (129...130), + (134...135), (136...137), ArrayNode(138...144)( [IntegerNode(139...140)(), IntegerNode(142...143)()], @@ -131,15 +115,13 @@ ProgramNode(0...704)( ) ), MultiWriteNode(145...163)( - MultiTargetNode(145...154)( - [LocalVariableTargetNode(146...147)(:a, 0), - SplatNode(149...153)( - (149...150), - LocalVariableTargetNode(150...153)(:foo, 0) - )], - (145...146), - (153...154) - ), + [LocalVariableTargetNode(146...147)(:a, 0), + SplatNode(149...153)( + (149...150), + LocalVariableTargetNode(150...153)(:foo, 0) + )], + (145...146), + (153...154), (155...156), ArrayNode(157...163)( [IntegerNode(158...159)(), IntegerNode(161...162)()], @@ -148,12 +130,10 @@ ProgramNode(0...704)( ) ), MultiWriteNode(164...179)( - MultiTargetNode(164...170)( - [LocalVariableTargetNode(165...166)(:a, 0), - LocalVariableTargetNode(168...169)(:b, 0)], - (164...165), - (169...170) - ), + [LocalVariableTargetNode(165...166)(:a, 0), + LocalVariableTargetNode(168...169)(:b, 0)], + (164...165), + (169...170), (171...172), ArrayNode(173...179)( [IntegerNode(174...175)(), IntegerNode(177...178)()], @@ -162,52 +142,46 @@ ProgramNode(0...704)( ) ), MultiWriteNode(180...192)( - MultiTargetNode(180...186)( - [LocalVariableTargetNode(181...182)(:a, 0), - LocalVariableTargetNode(184...185)(:b, 0)], - (180...181), - (185...186) - ), + [LocalVariableTargetNode(181...182)(:a, 0), + LocalVariableTargetNode(184...185)(:b, 0)], + (180...181), + (185...186), (187...188), LocalVariableReadNode(189...192)(:foo, 0) ), MultiWriteNode(193...203)( - MultiTargetNode(193...197)( - [LocalVariableTargetNode(194...195)(:a, 0), - SplatNode(195...196)((195...196), nil)], - (193...194), - (196...197) - ), + [LocalVariableTargetNode(194...195)(:a, 0), + SplatNode(195...196)((195...196), nil)], + (193...194), + (196...197), (198...199), LocalVariableReadNode(200...203)(:foo, 0) ), MultiWriteNode(204...227)( - MultiTargetNode(204...218)( - [CallNode(205...210)( - LocalVariableReadNode(205...206)(:a, 0), - (206...207), - (207...210), - nil, - nil, - nil, - nil, - 0, - "foo=" - ), - CallNode(212...217)( - LocalVariableReadNode(212...213)(:a, 0), - (213...214), - (214...217), - nil, - nil, - nil, - nil, - 0, - "bar=" - )], - (204...205), - (217...218) - ), + [CallNode(205...210)( + LocalVariableReadNode(205...206)(:a, 0), + (206...207), + (207...210), + nil, + nil, + nil, + nil, + 0, + "foo=" + ), + CallNode(212...217)( + LocalVariableReadNode(212...213)(:a, 0), + (213...214), + (214...217), + nil, + nil, + nil, + nil, + 0, + "bar=" + )], + (204...205), + (217...218), (219...220), ArrayNode(221...227)( [IntegerNode(222...223)(), IntegerNode(225...226)()], @@ -216,37 +190,35 @@ ProgramNode(0...704)( ) ), MultiWriteNode(228...252)( - MultiTargetNode(228...243)( - [CallNode(229...236)( - LocalVariableReadNode(229...230)(:a, 0), - nil, - (230...236), - (230...231), - ArgumentsNode(231...235)( - [SplatNode(231...235)( - (231...232), - LocalVariableReadNode(232...235)(:foo, 0) - )] - ), - (235...236), - nil, - 0, - "[]=" + [CallNode(229...236)( + LocalVariableReadNode(229...230)(:a, 0), + nil, + (230...236), + (230...231), + ArgumentsNode(231...235)( + [SplatNode(231...235)( + (231...232), + LocalVariableReadNode(232...235)(:foo, 0) + )] ), - CallNode(238...242)( - LocalVariableReadNode(238...239)(:a, 0), - nil, - (239...242), - (239...240), - ArgumentsNode(240...241)([IntegerNode(240...241)()]), - (241...242), - nil, - 0, - "[]=" - )], - (228...229), - (242...243) - ), + (235...236), + nil, + 0, + "[]=" + ), + CallNode(238...242)( + LocalVariableReadNode(238...239)(:a, 0), + nil, + (239...242), + (239...240), + ArgumentsNode(240...241)([IntegerNode(240...241)()]), + (241...242), + nil, + 0, + "[]=" + )], + (228...229), + (242...243), (244...245), ArrayNode(246...252)( [IntegerNode(247...248)(), IntegerNode(250...251)()], @@ -255,32 +227,30 @@ ProgramNode(0...704)( ) ), MultiWriteNode(253...274)( - MultiTargetNode(253...265)( - [CallNode(254...258)( - LocalVariableReadNode(254...255)(:a, 0), - nil, - (255...258), - (255...256), - ArgumentsNode(256...257)([IntegerNode(256...257)()]), - (257...258), - nil, - 0, - "[]=" - ), - CallNode(260...264)( - LocalVariableReadNode(260...261)(:a, 0), - nil, - (261...264), - (261...262), - ArgumentsNode(262...263)([IntegerNode(262...263)()]), - (263...264), - nil, - 0, - "[]=" - )], - (253...254), - (264...265) - ), + [CallNode(254...258)( + LocalVariableReadNode(254...255)(:a, 0), + nil, + (255...258), + (255...256), + ArgumentsNode(256...257)([IntegerNode(256...257)()]), + (257...258), + nil, + 0, + "[]=" + ), + CallNode(260...264)( + LocalVariableReadNode(260...261)(:a, 0), + nil, + (261...264), + (261...262), + ArgumentsNode(262...263)([IntegerNode(262...263)()]), + (263...264), + nil, + 0, + "[]=" + )], + (253...254), + (264...265), (266...267), ArrayNode(268...274)( [IntegerNode(269...270)(), IntegerNode(272...273)()], @@ -289,24 +259,22 @@ ProgramNode(0...704)( ) ), MultiWriteNode(275...287)( - MultiTargetNode(275...283)( - [SplatNode(276...282)( - (276...277), - CallNode(277...282)( - LocalVariableReadNode(277...278)(:c, 0), - (278...279), - (279...282), - nil, - nil, - nil, - nil, - 0, - "foo=" - ) - )], - (275...276), - (282...283) - ), + [SplatNode(276...282)( + (276...277), + CallNode(277...282)( + LocalVariableReadNode(277...278)(:c, 0), + (278...279), + (279...282), + nil, + nil, + nil, + nil, + 0, + "foo=" + ) + )], + (275...276), + (282...283), (284...285), IntegerNode(286...287)() ), @@ -361,12 +329,10 @@ ProgramNode(0...704)( ParenthesesNode(355...367)( StatementsNode(356...366)( [MultiWriteNode(356...366)( - MultiTargetNode(356...362)( - [LocalVariableTargetNode(357...358)(:b, 0), - LocalVariableTargetNode(360...361)(:c, 0)], - (356...357), - (361...362) - ), + [LocalVariableTargetNode(357...358)(:b, 0), + LocalVariableTargetNode(360...361)(:c, 0)], + (356...357), + (361...362), (363...364), IntegerNode(365...366)() )] diff --git a/test/yarp/snapshots/unparser/corpus/literal/defined.txt b/test/yarp/snapshots/unparser/corpus/literal/defined.txt index 84167e14d4c4c5..58816ee742a8fd 100644 --- a/test/yarp/snapshots/unparser/corpus/literal/defined.txt +++ b/test/yarp/snapshots/unparser/corpus/literal/defined.txt @@ -18,12 +18,10 @@ ProgramNode(0...56)( ParenthesesNode(38...55)( StatementsNode(39...54)( [MultiWriteNode(39...54)( - MultiTargetNode(39...45)( - [LocalVariableTargetNode(40...41)(:a, 0), - LocalVariableTargetNode(43...44)(:b, 0)], - (39...40), - (44...45) - ), + [LocalVariableTargetNode(40...41)(:a, 0), + LocalVariableTargetNode(43...44)(:b, 0)], + (39...40), + (44...45), (46...47), ArrayNode(48...54)( [IntegerNode(49...50)(), IntegerNode(52...53)()], diff --git a/test/yarp/snapshots/unparser/corpus/literal/send.txt b/test/yarp/snapshots/unparser/corpus/literal/send.txt index 0cc45c949b0bd7..858101f5a3a2c8 100644 --- a/test/yarp/snapshots/unparser/corpus/literal/send.txt +++ b/test/yarp/snapshots/unparser/corpus/literal/send.txt @@ -12,12 +12,10 @@ ProgramNode(0...999)( ParenthesesNode(19...31)( StatementsNode(20...30)( [MultiWriteNode(20...30)( - MultiTargetNode(20...26)( - [LocalVariableTargetNode(21...22)(:a, 0), - LocalVariableTargetNode(24...25)(:_, 0)], - (20...21), - (25...26) - ), + [LocalVariableTargetNode(21...22)(:a, 0), + LocalVariableTargetNode(24...25)(:_, 0)], + (20...21), + (25...26), (27...28), CallNode(29...30)( nil, diff --git a/test/yarp/snapshots/variables.txt b/test/yarp/snapshots/variables.txt index 74691a2ae66323..29f5e44817e5b9 100644 --- a/test/yarp/snapshots/variables.txt +++ b/test/yarp/snapshots/variables.txt @@ -9,12 +9,10 @@ ProgramNode(0...293)( (13...14) ), MultiWriteNode(18...34)( - MultiTargetNode(18...30)( - [ClassVariableTargetNode(18...23)(:@@foo), - ClassVariableTargetNode(25...30)(:@@bar)], - nil, - nil - ), + [ClassVariableTargetNode(18...23)(:@@foo), + ClassVariableTargetNode(25...30)(:@@bar)], + nil, + nil, (31...32), IntegerNode(33...34)() ), @@ -51,12 +49,10 @@ ProgramNode(0...293)( (89...90) ), MultiWriteNode(94...108)( - MultiTargetNode(94...104)( - [GlobalVariableTargetNode(94...98)(:$foo), - GlobalVariableTargetNode(100...104)(:$bar)], - nil, - nil - ), + [GlobalVariableTargetNode(94...98)(:$foo), + GlobalVariableTargetNode(100...104)(:$bar)], + nil, + nil, (105...106), IntegerNode(107...108)() ), @@ -71,12 +67,10 @@ ProgramNode(0...293)( (115...116) ), MultiWriteNode(123...137)( - MultiTargetNode(123...133)( - [InstanceVariableTargetNode(123...127)(:@foo), - InstanceVariableTargetNode(129...133)(:@bar)], - nil, - nil - ), + [InstanceVariableTargetNode(123...127)(:@foo), + InstanceVariableTargetNode(129...133)(:@bar)], + nil, + nil, (134...135), IntegerNode(136...137)() ), @@ -120,12 +114,10 @@ ProgramNode(0...293)( (177...178) ), MultiWriteNode(185...198)( - MultiTargetNode(185...191)( - [LocalVariableTargetNode(185...188)(:foo, 0), - SplatNode(190...191)((190...191), nil)], - nil, - nil - ), + [LocalVariableTargetNode(185...188)(:foo, 0), + SplatNode(190...191)((190...191), nil)], + nil, + nil, (192...193), ArrayNode(194...198)( [IntegerNode(194...195)(), IntegerNode(197...198)()], @@ -134,12 +126,10 @@ ProgramNode(0...293)( ) ), MultiWriteNode(200...211)( - MultiTargetNode(200...204)( - [LocalVariableTargetNode(200...203)(:foo, 0), - SplatNode(203...204)((203...204), nil)], - nil, - nil - ), + [LocalVariableTargetNode(200...203)(:foo, 0), + SplatNode(203...204)((203...204), nil)], + nil, + nil, (205...206), ArrayNode(207...211)( [IntegerNode(207...208)(), IntegerNode(210...211)()], @@ -148,15 +138,13 @@ ProgramNode(0...293)( ) ), MultiWriteNode(213...229)( - MultiTargetNode(213...222)( - [LocalVariableTargetNode(213...216)(:foo, 0), - SplatNode(218...222)( - (218...219), - LocalVariableTargetNode(219...222)(:bar, 0) - )], - nil, - nil - ), + [LocalVariableTargetNode(213...216)(:foo, 0), + SplatNode(218...222)( + (218...219), + LocalVariableTargetNode(219...222)(:bar, 0) + )], + nil, + nil, (223...224), ArrayNode(225...229)( [IntegerNode(225...226)(), IntegerNode(228...229)()], @@ -165,17 +153,15 @@ ProgramNode(0...293)( ) ), MultiWriteNode(231...258)( - MultiTargetNode(231...246)( - [LocalVariableTargetNode(231...234)(:foo, 0), - MultiTargetNode(236...246)( - [LocalVariableTargetNode(237...240)(:bar, 0), - LocalVariableTargetNode(242...245)(:baz, 0)], - (236...237), - (245...246) - )], - nil, - nil - ), + [LocalVariableTargetNode(231...234)(:foo, 0), + MultiTargetNode(236...246)( + [LocalVariableTargetNode(237...240)(:bar, 0), + LocalVariableTargetNode(242...245)(:baz, 0)], + (236...237), + (245...246) + )], + nil, + nil, (247...248), ArrayNode(249...258)( [IntegerNode(249...250)(), diff --git a/test/yarp/snapshots/whitequark/and_or_masgn.txt b/test/yarp/snapshots/whitequark/and_or_masgn.txt index 9ba221facd6d68..e34c3e19ee09ee 100644 --- a/test/yarp/snapshots/whitequark/and_or_masgn.txt +++ b/test/yarp/snapshots/whitequark/and_or_masgn.txt @@ -6,12 +6,10 @@ ProgramNode(0...40)( ParenthesesNode(7...19)( StatementsNode(8...18)( [MultiWriteNode(8...18)( - MultiTargetNode(8...12)( - [LocalVariableTargetNode(8...9)(:a, 0), - LocalVariableTargetNode(11...12)(:b, 0)], - nil, - nil - ), + [LocalVariableTargetNode(8...9)(:a, 0), + LocalVariableTargetNode(11...12)(:b, 0)], + nil, + nil, (13...14), CallNode(15...18)( nil, @@ -36,12 +34,10 @@ ProgramNode(0...40)( ParenthesesNode(28...40)( StatementsNode(29...39)( [MultiWriteNode(29...39)( - MultiTargetNode(29...33)( - [LocalVariableTargetNode(29...30)(:a, 0), - LocalVariableTargetNode(32...33)(:b, 0)], - nil, - nil - ), + [LocalVariableTargetNode(29...30)(:a, 0), + LocalVariableTargetNode(32...33)(:b, 0)], + nil, + nil, (34...35), CallNode(36...39)( nil, diff --git a/test/yarp/snapshots/whitequark/cond_begin_masgn.txt b/test/yarp/snapshots/whitequark/cond_begin_masgn.txt index a84f7b5154cb24..9a5e51bd10a57c 100644 --- a/test/yarp/snapshots/whitequark/cond_begin_masgn.txt +++ b/test/yarp/snapshots/whitequark/cond_begin_masgn.txt @@ -7,12 +7,10 @@ ProgramNode(0...25)( StatementsNode(4...19)( [CallNode(4...7)(nil, nil, (4...7), nil, nil, nil, nil, 2, "bar"), MultiWriteNode(9...19)( - MultiTargetNode(9...13)( - [LocalVariableTargetNode(9...10)(:a, 0), - LocalVariableTargetNode(12...13)(:b, 0)], - nil, - nil - ), + [LocalVariableTargetNode(9...10)(:a, 0), + LocalVariableTargetNode(12...13)(:b, 0)], + nil, + nil, (14...15), CallNode(16...19)( nil, diff --git a/test/yarp/snapshots/whitequark/if_masgn__24.txt b/test/yarp/snapshots/whitequark/if_masgn__24.txt index b1ecd82868db8b..1bdfd7bff69715 100644 --- a/test/yarp/snapshots/whitequark/if_masgn__24.txt +++ b/test/yarp/snapshots/whitequark/if_masgn__24.txt @@ -6,12 +6,10 @@ ProgramNode(0...20)( ParenthesesNode(3...15)( StatementsNode(4...14)( [MultiWriteNode(4...14)( - MultiTargetNode(4...8)( - [LocalVariableTargetNode(4...5)(:a, 0), - LocalVariableTargetNode(7...8)(:b, 0)], - nil, - nil - ), + [LocalVariableTargetNode(4...5)(:a, 0), + LocalVariableTargetNode(7...8)(:b, 0)], + nil, + nil, (9...10), CallNode(11...14)( nil, diff --git a/test/yarp/snapshots/whitequark/masgn.txt b/test/yarp/snapshots/whitequark/masgn.txt index aee61e4791c7c6..419d68ee7b4c69 100644 --- a/test/yarp/snapshots/whitequark/masgn.txt +++ b/test/yarp/snapshots/whitequark/masgn.txt @@ -2,12 +2,10 @@ ProgramNode(0...56)( [:foo, :bar, :baz], StatementsNode(0...56)( [MultiWriteNode(0...17)( - MultiTargetNode(0...10)( - [LocalVariableTargetNode(1...4)(:foo, 0), - LocalVariableTargetNode(6...9)(:bar, 0)], - (0...1), - (9...10) - ), + [LocalVariableTargetNode(1...4)(:foo, 0), + LocalVariableTargetNode(6...9)(:bar, 0)], + (0...1), + (9...10), (11...12), ArrayNode(13...17)( [IntegerNode(13...14)(), IntegerNode(16...17)()], @@ -16,12 +14,10 @@ ProgramNode(0...56)( ) ), MultiWriteNode(19...34)( - MultiTargetNode(19...27)( - [LocalVariableTargetNode(19...22)(:foo, 0), - LocalVariableTargetNode(24...27)(:bar, 0)], - nil, - nil - ), + [LocalVariableTargetNode(19...22)(:foo, 0), + LocalVariableTargetNode(24...27)(:bar, 0)], + nil, + nil, (28...29), ArrayNode(30...34)( [IntegerNode(30...31)(), IntegerNode(33...34)()], @@ -30,13 +26,11 @@ ProgramNode(0...56)( ) ), MultiWriteNode(36...56)( - MultiTargetNode(36...49)( - [LocalVariableTargetNode(36...39)(:foo, 0), - LocalVariableTargetNode(41...44)(:bar, 0), - LocalVariableTargetNode(46...49)(:baz, 0)], - nil, - nil - ), + [LocalVariableTargetNode(36...39)(:foo, 0), + LocalVariableTargetNode(41...44)(:bar, 0), + LocalVariableTargetNode(46...49)(:baz, 0)], + nil, + nil, (50...51), ArrayNode(52...56)( [IntegerNode(52...53)(), IntegerNode(55...56)()], diff --git a/test/yarp/snapshots/whitequark/masgn_attr.txt b/test/yarp/snapshots/whitequark/masgn_attr.txt index 0c8af75356ff00..5ad893c96dd0cb 100644 --- a/test/yarp/snapshots/whitequark/masgn_attr.txt +++ b/test/yarp/snapshots/whitequark/masgn_attr.txt @@ -2,74 +2,68 @@ ProgramNode(0...63)( [:foo], StatementsNode(0...63)( [MultiWriteNode(0...17)( - MultiTargetNode(0...11)( - [CallNode(0...6)( - SelfNode(0...4)(), - (4...5), - (5...6), - nil, - nil, - nil, - nil, - 0, - "A=" - ), - LocalVariableTargetNode(8...11)(:foo, 0)], - nil, - nil - ), + [CallNode(0...6)( + SelfNode(0...4)(), + (4...5), + (5...6), + nil, + nil, + nil, + nil, + 0, + "A=" + ), + LocalVariableTargetNode(8...11)(:foo, 0)], + nil, + nil, (12...13), LocalVariableReadNode(14...17)(:foo, 0) ), MultiWriteNode(19...43)( - MultiTargetNode(19...37)( - [CallNode(19...25)( - SelfNode(19...23)(), - (23...24), - (24...25), - nil, - nil, - nil, - nil, - 0, - "a=" + [CallNode(19...25)( + SelfNode(19...23)(), + (23...24), + (24...25), + nil, + nil, + nil, + nil, + 0, + "a=" + ), + CallNode(27...37)( + SelfNode(27...31)(), + nil, + (31...37), + (31...32), + ArgumentsNode(32...36)( + [IntegerNode(32...33)(), IntegerNode(35...36)()] ), - CallNode(27...37)( - SelfNode(27...31)(), - nil, - (31...37), - (31...32), - ArgumentsNode(32...36)( - [IntegerNode(32...33)(), IntegerNode(35...36)()] - ), - (36...37), - nil, - 0, - "[]=" - )], - nil, - nil - ), + (36...37), + nil, + 0, + "[]=" + )], + nil, + nil, (38...39), LocalVariableReadNode(40...43)(:foo, 0) ), MultiWriteNode(45...63)( - MultiTargetNode(45...57)( - [CallNode(45...52)( - SelfNode(45...49)(), - (49...51), - (51...52), - nil, - nil, - nil, - nil, - 0, - "a=" - ), - LocalVariableTargetNode(54...57)(:foo, 0)], - nil, - nil - ), + [CallNode(45...52)( + SelfNode(45...49)(), + (49...51), + (51...52), + nil, + nil, + nil, + nil, + 0, + "a=" + ), + LocalVariableTargetNode(54...57)(:foo, 0)], + nil, + nil, (58...59), LocalVariableReadNode(60...63)(:foo, 0) )] diff --git a/test/yarp/snapshots/whitequark/masgn_cmd.txt b/test/yarp/snapshots/whitequark/masgn_cmd.txt index ab403e2f12b723..5b9b9b03cec9d9 100644 --- a/test/yarp/snapshots/whitequark/masgn_cmd.txt +++ b/test/yarp/snapshots/whitequark/masgn_cmd.txt @@ -2,12 +2,10 @@ ProgramNode(0...16)( [:foo, :bar], StatementsNode(0...16)( [MultiWriteNode(0...16)( - MultiTargetNode(0...8)( - [LocalVariableTargetNode(0...3)(:foo, 0), - LocalVariableTargetNode(5...8)(:bar, 0)], - nil, - nil - ), + [LocalVariableTargetNode(0...3)(:foo, 0), + LocalVariableTargetNode(5...8)(:bar, 0)], + nil, + nil, (9...10), CallNode(11...16)( nil, diff --git a/test/yarp/snapshots/whitequark/masgn_const.txt b/test/yarp/snapshots/whitequark/masgn_const.txt index 8ed2ec62a09813..85155526189cf6 100644 --- a/test/yarp/snapshots/whitequark/masgn_const.txt +++ b/test/yarp/snapshots/whitequark/masgn_const.txt @@ -2,30 +2,26 @@ ProgramNode(0...34)( [:foo], StatementsNode(0...34)( [MultiWriteNode(0...14)( - MultiTargetNode(0...8)( - [ConstantPathTargetNode(0...3)( - nil, - ConstantReadNode(2...3)(:A), - (0...2) - ), - LocalVariableTargetNode(5...8)(:foo, 0)], - nil, - nil - ), + [ConstantPathTargetNode(0...3)( + nil, + ConstantReadNode(2...3)(:A), + (0...2) + ), + LocalVariableTargetNode(5...8)(:foo, 0)], + nil, + nil, (9...10), LocalVariableReadNode(11...14)(:foo, 0) ), MultiWriteNode(16...34)( - MultiTargetNode(16...28)( - [ConstantPathTargetNode(16...23)( - SelfNode(16...20)(), - ConstantReadNode(22...23)(:A), - (20...22) - ), - LocalVariableTargetNode(25...28)(:foo, 0)], - nil, - nil - ), + [ConstantPathTargetNode(16...23)( + SelfNode(16...20)(), + ConstantReadNode(22...23)(:A), + (20...22) + ), + LocalVariableTargetNode(25...28)(:foo, 0)], + nil, + nil, (29...30), LocalVariableReadNode(31...34)(:foo, 0) )] diff --git a/test/yarp/snapshots/whitequark/masgn_nested.txt b/test/yarp/snapshots/whitequark/masgn_nested.txt index 3dd9fd696a9d24..00f4eb1ef40745 100644 --- a/test/yarp/snapshots/whitequark/masgn_nested.txt +++ b/test/yarp/snapshots/whitequark/masgn_nested.txt @@ -2,31 +2,27 @@ ProgramNode(1...30)( [:b, :a, :c], StatementsNode(1...30)( [MultiWriteNode(1...13)( - MultiTargetNode(1...6)( - [MultiTargetNode(1...6)( - [LocalVariableTargetNode(2...3)(:b, 0), - SplatNode(3...4)((3...4), nil)], - (1...2), - (5...6) - )], - nil, - nil - ), + [MultiTargetNode(1...6)( + [LocalVariableTargetNode(2...3)(:b, 0), + SplatNode(3...4)((3...4), nil)], + (1...2), + (5...6) + )], + nil, + nil, (8...9), CallNode(10...13)(nil, nil, (10...13), nil, nil, nil, nil, 2, "foo") ), MultiWriteNode(15...30)( - MultiTargetNode(15...24)( - [LocalVariableTargetNode(15...16)(:a, 0), - MultiTargetNode(18...24)( - [LocalVariableTargetNode(19...20)(:b, 0), - LocalVariableTargetNode(22...23)(:c, 0)], - (18...19), - (23...24) - )], - nil, - nil - ), + [LocalVariableTargetNode(15...16)(:a, 0), + MultiTargetNode(18...24)( + [LocalVariableTargetNode(19...20)(:b, 0), + LocalVariableTargetNode(22...23)(:c, 0)], + (18...19), + (23...24) + )], + nil, + nil, (25...26), CallNode(27...30)(nil, nil, (27...30), nil, nil, nil, nil, 2, "foo") )] diff --git a/test/yarp/snapshots/whitequark/masgn_splat.txt b/test/yarp/snapshots/whitequark/masgn_splat.txt index f7a2050506298f..c6cbe9ee70a3a0 100644 --- a/test/yarp/snapshots/whitequark/masgn_splat.txt +++ b/test/yarp/snapshots/whitequark/masgn_splat.txt @@ -2,61 +2,51 @@ ProgramNode(0...139)( [:c, :d, :b, :a], StatementsNode(0...139)( [MultiWriteNode(0...7)( - MultiTargetNode(0...1)([SplatNode(0...1)((0...1), nil)], nil, nil), + [SplatNode(0...1)((0...1), nil)], + nil, + nil, (2...3), CallNode(4...7)(nil, nil, (4...7), nil, nil, nil, nil, 2, "bar") ), MultiWriteNode(9...22)( - MultiTargetNode(9...16)( - [MultiTargetNode(9...10)( - [SplatNode(9...10)((9...10), nil)], - nil, - nil - ), - LocalVariableTargetNode(12...13)(:c, 0), - LocalVariableTargetNode(15...16)(:d, 0)], - nil, - nil - ), + [MultiTargetNode(9...10)([SplatNode(9...10)((9...10), nil)], nil, nil), + LocalVariableTargetNode(12...13)(:c, 0), + LocalVariableTargetNode(15...16)(:d, 0)], + nil, + nil, (17...18), CallNode(19...22)(nil, nil, (19...22), nil, nil, nil, nil, 2, "bar") ), MultiWriteNode(24...32)( - MultiTargetNode(24...26)( - [SplatNode(24...26)( - (24...25), - LocalVariableTargetNode(25...26)(:b, 0) - )], - nil, - nil - ), + [SplatNode(24...26)( + (24...25), + LocalVariableTargetNode(25...26)(:b, 0) + )], + nil, + nil, (27...28), CallNode(29...32)(nil, nil, (29...32), nil, nil, nil, nil, 2, "bar") ), MultiWriteNode(34...45)( - MultiTargetNode(34...39)( - [MultiTargetNode(34...36)( - [SplatNode(34...36)( - (34...35), - LocalVariableTargetNode(35...36)(:b, 0) - )], - nil, - nil - ), - LocalVariableTargetNode(38...39)(:c, 0)], - nil, - nil - ), + [MultiTargetNode(34...36)( + [SplatNode(34...36)( + (34...35), + LocalVariableTargetNode(35...36)(:b, 0) + )], + nil, + nil + ), + LocalVariableTargetNode(38...39)(:c, 0)], + nil, + nil, (40...41), CallNode(42...45)(nil, nil, (42...45), nil, nil, nil, nil, 2, "bar") ), MultiWriteNode(47...65)( - MultiTargetNode(47...58)( - [InstanceVariableTargetNode(47...51)(:@foo), - ClassVariableTargetNode(53...58)(:@@bar)], - nil, - nil - ), + [InstanceVariableTargetNode(47...51)(:@foo), + ClassVariableTargetNode(53...58)(:@@bar)], + nil, + nil, (59...60), ArrayNode(61...65)( [SplatNode(61...65)( @@ -78,60 +68,50 @@ ProgramNode(0...139)( ) ), MultiWriteNode(67...77)( - MultiTargetNode(67...71)( - [LocalVariableTargetNode(67...68)(:a, 0), - SplatNode(70...71)((70...71), nil)], - nil, - nil - ), + [LocalVariableTargetNode(67...68)(:a, 0), + SplatNode(70...71)((70...71), nil)], + nil, + nil, (72...73), CallNode(74...77)(nil, nil, (74...77), nil, nil, nil, nil, 2, "bar") ), MultiWriteNode(79...92)( - MultiTargetNode(79...86)( - [LocalVariableTargetNode(79...80)(:a, 0), - SplatNode(82...83)((82...83), nil), - LocalVariableTargetNode(85...86)(:c, 0)], - nil, - nil - ), + [LocalVariableTargetNode(79...80)(:a, 0), + SplatNode(82...83)((82...83), nil), + LocalVariableTargetNode(85...86)(:c, 0)], + nil, + nil, (87...88), CallNode(89...92)(nil, nil, (89...92), nil, nil, nil, nil, 2, "bar") ), MultiWriteNode(94...105)( - MultiTargetNode(94...99)( - [LocalVariableTargetNode(94...95)(:a, 0), - SplatNode(97...99)( - (97...98), - LocalVariableTargetNode(98...99)(:b, 0) - )], - nil, - nil - ), + [LocalVariableTargetNode(94...95)(:a, 0), + SplatNode(97...99)( + (97...98), + LocalVariableTargetNode(98...99)(:b, 0) + )], + nil, + nil, (100...101), CallNode(102...105)(nil, nil, (102...105), nil, nil, nil, nil, 2, "bar") ), MultiWriteNode(107...121)( - MultiTargetNode(107...115)( - [LocalVariableTargetNode(107...108)(:a, 0), - SplatNode(110...112)( - (110...111), - LocalVariableTargetNode(111...112)(:b, 0) - ), - LocalVariableTargetNode(114...115)(:c, 0)], - nil, - nil - ), + [LocalVariableTargetNode(107...108)(:a, 0), + SplatNode(110...112)( + (110...111), + LocalVariableTargetNode(111...112)(:b, 0) + ), + LocalVariableTargetNode(114...115)(:c, 0)], + nil, + nil, (116...117), CallNode(118...121)(nil, nil, (118...121), nil, nil, nil, nil, 2, "bar") ), MultiWriteNode(123...139)( - MultiTargetNode(123...127)( - [LocalVariableTargetNode(123...124)(:a, 0), - LocalVariableTargetNode(126...127)(:b, 0)], - nil, - nil - ), + [LocalVariableTargetNode(123...124)(:a, 0), + LocalVariableTargetNode(126...127)(:b, 0)], + nil, + nil, (128...129), ArrayNode(130...139)( [SplatNode(130...134)( diff --git a/test/yarp/snapshots/whitequark/not_masgn__24.txt b/test/yarp/snapshots/whitequark/not_masgn__24.txt index 5233c25ba587e2..c20896826318b2 100644 --- a/test/yarp/snapshots/whitequark/not_masgn__24.txt +++ b/test/yarp/snapshots/whitequark/not_masgn__24.txt @@ -5,12 +5,10 @@ ProgramNode(0...13)( ParenthesesNode(1...13)( StatementsNode(2...12)( [MultiWriteNode(2...12)( - MultiTargetNode(2...6)( - [LocalVariableTargetNode(2...3)(:a, 0), - LocalVariableTargetNode(5...6)(:b, 0)], - nil, - nil - ), + [LocalVariableTargetNode(2...3)(:a, 0), + LocalVariableTargetNode(5...6)(:b, 0)], + nil, + nil, (7...8), CallNode(9...12)( nil, diff --git a/test/yarp/snapshots/whitequark/rescue_mod_masgn.txt b/test/yarp/snapshots/whitequark/rescue_mod_masgn.txt index 990312e3657dd2..82b1220cd7a4d8 100644 --- a/test/yarp/snapshots/whitequark/rescue_mod_masgn.txt +++ b/test/yarp/snapshots/whitequark/rescue_mod_masgn.txt @@ -2,12 +2,10 @@ ProgramNode(0...29)( [:foo, :bar], StatementsNode(0...29)( [MultiWriteNode(0...29)( - MultiTargetNode(0...8)( - [LocalVariableTargetNode(0...3)(:foo, 0), - LocalVariableTargetNode(5...8)(:bar, 0)], - nil, - nil - ), + [LocalVariableTargetNode(0...3)(:foo, 0), + LocalVariableTargetNode(5...8)(:bar, 0)], + nil, + nil, (9...10), RescueModifierNode(11...29)( CallNode(11...15)(nil, nil, (11...15), nil, nil, nil, nil, 2, "meth"), diff --git a/yarp/config.yml b/yarp/config.yml index 3161006bf374d4..e63c2bb80216e3 100644 --- a/yarp/config.yml +++ b/yarp/config.yml @@ -1766,9 +1766,12 @@ nodes: ^^^^^^^ - name: MultiWriteNode fields: - - name: target - type: node - kind: MultiTargetNode + - name: targets + type: node[] + - name: lparen_loc + type: location? + - name: rparen_loc + type: location? - name: operator_loc type: location - name: value diff --git a/yarp/yarp.c b/yarp/yarp.c index 7c1df2343da0f9..820361e25a7c01 100644 --- a/yarp/yarp.c +++ b/yarp/yarp.c @@ -3365,11 +3365,17 @@ yp_multi_write_node_create(yp_parser_t *parser, yp_multi_target_node_t *target, .end = value->location.end } }, - .target = target, + .targets = target->targets, + .lparen_loc = target->lparen_loc, + .rparen_loc = target->rparen_loc, .operator_loc = YP_LOCATION_TOKEN_VALUE(operator), .value = value }; + // Explicitly do not call yp_node_destroy here because we want to keep + // around all of the information within the MultiWriteNode node. + free(target); + return node; } From 8807b0dc96cbb0d0b72cddae2f41dd163589b7cc Mon Sep 17 00:00:00 2001 From: Jemma Issroff Date: Fri, 8 Sep 2023 10:40:07 -0400 Subject: [PATCH 36/46] [YARP] Implement compilation for InterpolatedXStringNode (#8395) * [YARP] Implemented compilation for InterpolatedXStringNode * Extract common function for interpolated nodes --- test/yarp/compiler_test.rb | 5 ++ yarp/yarp_compiler.c | 96 +++++++++++++++++--------------------- 2 files changed, 49 insertions(+), 52 deletions(-) diff --git a/test/yarp/compiler_test.rb b/test/yarp/compiler_test.rb index 4f81138037a675..f7f8618ada18c3 100644 --- a/test/yarp/compiler_test.rb +++ b/test/yarp/compiler_test.rb @@ -178,6 +178,11 @@ def test_InterpolatedSymbolNode assert_equal :"1 3 1", compile(':"1 #{1 + 2} 1"') end + def test_InterpolatedXStringNode + assert_equal "1\n", compile('`echo #{1}`') + assert_equal "100", compile('`printf "100"`') + end + def test_StringConcatNode # assert_equal "YARP::CompilerTest", compile('"YARP" "::" "CompilerTest"') end diff --git a/yarp/yarp_compiler.c b/yarp/yarp_compiler.c index 4be8f2fa2c73da..058ca25e0b03b3 100644 --- a/yarp/yarp_compiler.c +++ b/yarp/yarp_compiler.c @@ -338,6 +338,35 @@ yp_compile_while(rb_iseq_t *iseq, int lineno, yp_node_flags_t flags, enum yp_nod return; } +static void +yp_interpolated_node_compile(yp_node_list_t parts, rb_iseq_t *iseq, NODE dummy_line_node, LINK_ANCHOR *const ret, const uint8_t *src, bool popped, yp_compile_context_t *compile_context) +{ + size_t parts_size = parts.size; + + if (parts_size > 0) { + for (size_t index = 0; index < parts_size; index++) { + yp_node_t *part = parts.nodes[index]; + + if (YP_NODE_TYPE_P(part, YP_NODE_STRING_NODE)) { + yp_string_node_t *string_node = (yp_string_node_t *) part; + ADD_INSN1(ret, &dummy_line_node, putobject, parse_string(&string_node->unescaped)); + } + else { + yp_compile_node(iseq, part, ret, src, popped, compile_context); + ADD_INSN(ret, &dummy_line_node, dup); + ADD_INSN1(ret, &dummy_line_node, objtostring, new_callinfo(iseq, idTo_s, 0, VM_CALL_FCALL | VM_CALL_ARGS_SIMPLE , NULL, FALSE)); + ADD_INSN(ret, &dummy_line_node, anytostring); + } + } + + if (parts_size > 1) { + ADD_INSN1(ret, &dummy_line_node, concatstrings, INT2FIX((int)(parts_size))); + } + } + else { + ADD_INSN(ret, &dummy_line_node, putnil); + } +} static int yp_lookup_local_index(rb_iseq_t *iseq, yp_compile_context_t *compile_context, yp_constant_id_t constant_id) { @@ -1270,61 +1299,13 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, return; } case YP_NODE_INTERPOLATED_STRING_NODE: { - yp_interpolated_string_node_t *interp_string_node= (yp_interpolated_string_node_t *) node; - size_t parts_size = interp_string_node->parts.size; - - if (parts_size > 0) { - for (size_t index = 0; index < parts_size; index++) { - yp_node_t *part = interp_string_node->parts.nodes[index]; - - switch (part->type) { - case YP_NODE_STRING_NODE: { - yp_string_node_t *string_node = (yp_string_node_t *) part; - ADD_INSN1(ret, &dummy_line_node, putobject,parse_string(&string_node->unescaped)); - break; - } - default: - yp_compile_node(iseq, part, ret, src, popped, compile_context); - ADD_INSN(ret, &dummy_line_node, dup); - ADD_INSN1(ret, &dummy_line_node, objtostring, new_callinfo(iseq, idTo_s, 0, VM_CALL_FCALL | VM_CALL_ARGS_SIMPLE , NULL, FALSE)); - ADD_INSN(ret, &dummy_line_node, anytostring); - break; - } - } - - if (parts_size > 1) { - ADD_INSN1(ret, &dummy_line_node, concatstrings, INT2FIX((int)(interp_string_node->parts.size))); - } - } - else { - ADD_INSN(ret, &dummy_line_node, putnil); - } + yp_interpolated_string_node_t *interp_string_node = (yp_interpolated_string_node_t *) node; + yp_interpolated_node_compile(interp_string_node->parts, iseq, dummy_line_node, ret, src, popped, compile_context); return; } case YP_NODE_INTERPOLATED_SYMBOL_NODE: { - yp_interpolated_symbol_node_t *interp_symbol_node= (yp_interpolated_symbol_node_t *) node; - - for (size_t index = 0; index < interp_symbol_node->parts.size; index++) { - yp_node_t *part = interp_symbol_node->parts.nodes[index]; - - switch (part->type) { - case YP_NODE_STRING_NODE: { - yp_string_node_t *string_node = (yp_string_node_t *) part; - ADD_INSN1(ret, &dummy_line_node, putobject, parse_string(&string_node->unescaped)); - break; - } - default: - yp_compile_node(iseq, part, ret, src, popped, compile_context); - ADD_INSN(ret, &dummy_line_node, dup); - ADD_INSN1(ret, &dummy_line_node, objtostring, new_callinfo(iseq, idTo_s, 0, VM_CALL_FCALL | VM_CALL_ARGS_SIMPLE, NULL, FALSE)); - ADD_INSN(ret, &dummy_line_node, anytostring); - break; - } - } - - if (interp_symbol_node->parts.size > 1) { - ADD_INSN1(ret, &dummy_line_node, concatstrings, INT2FIX((int)(interp_symbol_node->parts.size))); - } + yp_interpolated_symbol_node_t *interp_symbol_node = (yp_interpolated_symbol_node_t *) node; + yp_interpolated_node_compile(interp_symbol_node->parts, iseq, dummy_line_node, ret, src, popped, compile_context); if (!popped) { ADD_INSN(ret, &dummy_line_node, intern); @@ -1335,6 +1316,17 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, return; } + case YP_NODE_INTERPOLATED_X_STRING_NODE: { + yp_interpolated_x_string_node_t *interp_x_string_node = (yp_interpolated_x_string_node_t *) node; + ADD_INSN(ret, &dummy_line_node, putself); + yp_interpolated_node_compile(interp_x_string_node->parts, iseq, dummy_line_node, ret, src, false, compile_context); + + ADD_SEND_WITH_FLAG(ret, &dummy_line_node, rb_intern("`"), INT2NUM(1), INT2FIX(VM_CALL_FCALL | VM_CALL_ARGS_SIMPLE)); + if (popped) { + ADD_INSN(ret, &dummy_line_node, pop); + } + return; + } case YP_NODE_KEYWORD_HASH_NODE: { yp_keyword_hash_node_t *keyword_hash_node = (yp_keyword_hash_node_t *) node; yp_node_list_t elements = keyword_hash_node->elements; From af5df9ee5ea6ad6270be020f74f9fb208e2bfb57 Mon Sep 17 00:00:00 2001 From: Jemma Issroff Date: Fri, 8 Sep 2023 12:09:30 -0400 Subject: [PATCH 37/46] [YARP] Implement compilation for Regex / InterpolatedRegex (#8396) --- test/yarp/compiler_test.rb | 10 ++++++++++ yarp/yarp_compiler.c | 39 ++++++++++++++++++++++++++++++++++---- 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/test/yarp/compiler_test.rb b/test/yarp/compiler_test.rb index f7f8618ada18c3..ea8c390362b130 100644 --- a/test/yarp/compiler_test.rb +++ b/test/yarp/compiler_test.rb @@ -168,6 +168,12 @@ def test_EmbeddedVariableNode assert_equal "1", compile('$yct = 1; "#$yct"') end + def test_InterpolatedRegularExpressionNode + assert_equal /1 1 1/, compile('$yct = 1; /1 #$yct 1/') + assert_equal /1 3 1/, compile('/1 #{1 + 2} 1/') + assert_equal /1 2 3 1/, compile('/1 #{"2"} #{1 + 2} 1/') + end + def test_InterpolatedStringNode assert_equal "1 1 1", compile('$yct = 1; "1 #$yct 1"') assert_equal "1 3 1", compile('"1 #{1 + 2} 1"') @@ -183,6 +189,10 @@ def test_InterpolatedXStringNode assert_equal "100", compile('`printf "100"`') end + def test_RegularExpressionNode + assert_equal /yct/, compile('/yct/') + end + def test_StringConcatNode # assert_equal "YARP::CompilerTest", compile('"YARP" "::" "CompilerTest"') end diff --git a/yarp/yarp_compiler.c b/yarp/yarp_compiler.c index 058ca25e0b03b3..c77e8f36c20d22 100644 --- a/yarp/yarp_compiler.c +++ b/yarp/yarp_compiler.c @@ -358,10 +358,6 @@ yp_interpolated_node_compile(yp_node_list_t parts, rb_iseq_t *iseq, NODE dummy_l ADD_INSN(ret, &dummy_line_node, anytostring); } } - - if (parts_size > 1) { - ADD_INSN1(ret, &dummy_line_node, concatstrings, INT2FIX((int)(parts_size))); - } } else { ADD_INSN(ret, &dummy_line_node, putnil); @@ -1298,15 +1294,34 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, } return; } + case YP_NODE_INTERPOLATED_REGULAR_EXPRESSION_NODE: { + yp_interpolated_regular_expression_node_t *interp_regular_expression_node= (yp_interpolated_regular_expression_node_t *) node; + yp_interpolated_node_compile(interp_regular_expression_node->parts, iseq, dummy_line_node, ret, src, popped, compile_context); + if (interp_regular_expression_node->parts.size > 1) { + ADD_INSN2(ret, &dummy_line_node, toregexp, INT2FIX(0), INT2FIX((int)(interp_regular_expression_node->parts.size))); + } + + return; + } case YP_NODE_INTERPOLATED_STRING_NODE: { yp_interpolated_string_node_t *interp_string_node = (yp_interpolated_string_node_t *) node; yp_interpolated_node_compile(interp_string_node->parts, iseq, dummy_line_node, ret, src, popped, compile_context); + + size_t parts_size = interp_string_node->parts.size; + if (parts_size > 1) { + ADD_INSN1(ret, &dummy_line_node, concatstrings, INT2FIX((int)(parts_size))); + } return; } case YP_NODE_INTERPOLATED_SYMBOL_NODE: { yp_interpolated_symbol_node_t *interp_symbol_node = (yp_interpolated_symbol_node_t *) node; yp_interpolated_node_compile(interp_symbol_node->parts, iseq, dummy_line_node, ret, src, popped, compile_context); + size_t parts_size = interp_symbol_node->parts.size; + if (parts_size > 1) { + ADD_INSN1(ret, &dummy_line_node, concatstrings, INT2FIX((int)(parts_size))); + } + if (!popped) { ADD_INSN(ret, &dummy_line_node, intern); } @@ -1321,6 +1336,12 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, ADD_INSN(ret, &dummy_line_node, putself); yp_interpolated_node_compile(interp_x_string_node->parts, iseq, dummy_line_node, ret, src, false, compile_context); + size_t parts_size = interp_x_string_node->parts.size; + if (parts_size > 1) { + ADD_INSN1(ret, &dummy_line_node, concatstrings, INT2FIX((int)(parts_size))); + } + + ADD_SEND_WITH_FLAG(ret, &dummy_line_node, rb_intern("`"), INT2NUM(1), INT2FIX(VM_CALL_FCALL | VM_CALL_ARGS_SIMPLE)); if (popped) { ADD_INSN(ret, &dummy_line_node, pop); @@ -1631,6 +1652,16 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, ADD_INSNL(ret, &dummy_line_node, jump, ISEQ_COMPILE_DATA(iseq)->redo_label); return; } + case YP_NODE_REGULAR_EXPRESSION_NODE: { + if (!popped) { + yp_regular_expression_node_t *regular_expression_node = (yp_regular_expression_node_t *) node; + VALUE regex_str = parse_string(®ular_expression_node->unescaped); + // TODO: Replace 0 with regex options + VALUE regex = rb_reg_new(RSTRING_PTR(regex_str), RSTRING_LEN(regex_str), 0); + ADD_INSN1(ret, &dummy_line_node, putobject, regex); + } + return; + } case YP_NODE_RETURN_NODE: { yp_arguments_node_t *arguments = ((yp_return_node_t *)node)->arguments; From 60ef156b1463629d94cf7139430d129dd68a418f Mon Sep 17 00:00:00 2001 From: Alan Wu Date: Fri, 8 Sep 2023 12:30:55 -0400 Subject: [PATCH 38/46] [DOC] Kernel#{proc,lambda} don't issue warnings anymore They've been raising since 3.0.0. --- error.c | 1 - 1 file changed, 1 deletion(-) diff --git a/error.c b/error.c index 13a6e3a5e28a11..cd031120e2acfb 100644 --- a/error.c +++ b/error.c @@ -205,7 +205,6 @@ rb_warning_category_enabled_p(rb_warning_category_t category) * deprecation warnings * * assignment of non-nil value to $, and $; * * keyword arguments - * * proc/lambda without block * etc. * * +:experimental+ :: From 7f53da94fb23687ef3bea0507199196a00ca26f8 Mon Sep 17 00:00:00 2001 From: Matt Valentine-House Date: Fri, 8 Sep 2023 14:31:29 +0100 Subject: [PATCH 39/46] Fix weak_references count test This test creates a lot of Objects held in an array, and a set of weak references to them using WeakMap. It then clears the array and frees it and asserts that all the weak references to it are also gone. This test is failing because one of the dummy objects in our weakmap is ending up on the stack, and so is being marked, even though we thought that we'd removed the only reference to it. This behaviour has changed since this commit: https://github.com/ruby/ruby/commit/5b5ae3d9e064e17e2a7d8d21d739fcc62ae1075c which rewrites `Integer#times` from C into Ruby. This change is somehow causing the last object we append to our array to consistently end up on the stack during GC. This commit fixes the specific weakmap test by using an enumerator and each, instead of `Integer#times`, and thus avoids having our last object created end up on the stack. --- test/ruby/test_gc.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/ruby/test_gc.rb b/test/ruby/test_gc.rb index 0b4062e99f946c..567e7b5d80458b 100644 --- a/test/ruby/test_gc.rb +++ b/test/ruby/test_gc.rb @@ -303,7 +303,8 @@ def test_latest_gc_info_weak_references_count # Create some objects and place it in a WeakMap wmap = ObjectSpace::WeakMap.new ary = Array.new(count) - count.times do |i| + enum = count.times + enum.each.with_index do |i| obj = Object.new ary[i] = obj wmap[obj] = nil From 6050b5a4e860b05f6b5e553d5883330a908079f9 Mon Sep 17 00:00:00 2001 From: Vinicius Stock Date: Thu, 7 Sep 2023 13:44:35 -0400 Subject: [PATCH 40/46] [ruby/yarp] Add ParseResult#attach_comments! to tie comments to their locations https://github.com/ruby/yarp/commit/ddc699156f Co-authored-by: Kevin Newton --- lib/yarp.rb | 167 +++++++++++++++++++++++++++++++++++++ test/yarp/comments_test.rb | 24 ++++++ 2 files changed, 191 insertions(+) diff --git a/lib/yarp.rb b/lib/yarp.rb index 9ee9c4b341bc8a..32d4a1b536ab07 100644 --- a/lib/yarp.rb +++ b/lib/yarp.rb @@ -20,6 +20,10 @@ def line(value) offsets.bsearch_index { |offset| offset > value } || offsets.length end + def line_offset(value) + offsets[line(value) - 1] + end + def column(value) value - offsets[line(value) - 1] end @@ -46,10 +50,14 @@ class Location # The length of this location in bytes. attr_reader :length + # The list of comments attached to this location + attr_reader :comments + def initialize(source, start_offset, length) @source = source @start_offset = start_offset @length = length + @comments = [] end # Create a new location object with the given options. @@ -81,6 +89,12 @@ def start_line source.line(start_offset) end + # The content of the line where this location starts before this location. + def start_line_slice + offset = source.line_offset(start_offset) + source.slice(offset, start_offset - offset) + end + # The line number where this location ends. def end_line source.line(end_offset - 1) @@ -142,6 +156,11 @@ def deconstruct_keys(keys) { type: type, location: location } end + # Returns true if the comment happens on the same line as other code and false if the comment is by itself + def trailing? + type == :inline && !location.start_line_slice.strip.empty? + end + def inspect "#" end @@ -230,6 +249,154 @@ def failure? !success? end + # CommentAttacher is a utility class to attach comments to locations in the AST + class CommentAttacher + attr_reader :parse_result + + def initialize(parse_result) + @parse_result = parse_result + end + + def attach! + parse_result.comments.each do |comment| + preceding, enclosing, following = nearest_targets(parse_result.value, comment) + target = + if comment.trailing? + preceding || following || enclosing || NodeTarget.new(parse_result.value) + else + # If a comment exists on its own line, prefer a leading comment. + following || preceding || enclosing || NodeTarget.new(parse_result.value) + end + + target << comment + end + end + + # A target for attaching comments that is based on a specific node + class NodeTarget + attr_reader :node + + def initialize(node) + @node = node + end + + def start_offset + node.location.start_offset + end + + def end_offset + node.location.end_offset + end + + def encloses?(comment) + start_offset <= comment.location.start_offset && comment.location.end_offset <= end_offset + end + + def <<(comment) + node.location.comments << comment + end + end + + # A target for attaching comments that is based on a location, which could be a part of a node. For example, the + # `end` token of a ClassNode + class LocationTarget + attr_reader :location + + def initialize(location) + @location = location + end + + def start_offset + location.start_offset + end + + def end_offset + location.end_offset + end + + def encloses?(comment) + false + end + + def <<(comment) + location.comments << comment + end + end + + private + + # Responsible for finding the nearest targets to the given comment within the context of the given encapsulating + # node. + def nearest_targets(node, comment) + comment_start = comment.location.start_offset + comment_end = comment.location.end_offset + + targets = [] + node.deconstruct_keys(nil).each do |key, value| + next if key == :location + + case value + when StatementsNode + targets.concat(value.body.map { |node| NodeTarget.new(node) }) + when Node + targets << NodeTarget.new(value) + when Location + targets << LocationTarget.new(value) + when Array + targets.concat(value.map { |node| NodeTarget.new(node) }) if value.first.is_a?(Node) + end + end + + targets.sort_by!(&:start_offset) + preceding = nil + following = nil + + left = 0 + right = targets.length + + # This is a custom binary search that finds the nearest nodes to the given comment. When it finds a node that + # completely encapsulates the comment, it recursed downward into the tree. + while left < right + middle = (left + right) / 2 + target = targets[middle] + + target_start = target.start_offset + target_end = target.end_offset + + if target.encloses?(comment) + # The comment is completely contained by this target. Abandon the binary search at this level. + return nearest_targets(target.node, comment) + end + + if target_end <= comment_start + # This target falls completely before the comment. Because we will never consider this target or any targets + # before it again, this target must be the closest preceding target we have encountered so far. + preceding = target + left = middle + 1 + next + end + + if comment_end <= target_start + # This target falls completely after the comment. Because we will never consider this target or any targets + # after it again, this target must be the closest following target we have encountered so far. + following = target + right = middle + next + end + + # This should only happen if there is a bug in this parser. + raise "Comment location overlaps with target location" + end + + [preceding, NodeTarget.new(node), following] + end + end + + # Attach the list of comments to their respective locations in the AST + def attach_comments! + CommentAttacher.new(self).attach! + end + # Keep in sync with Java MarkNewlinesVisitor class MarkNewlinesVisitor < YARP::Visitor def initialize(newline_marked) diff --git a/test/yarp/comments_test.rb b/test/yarp/comments_test.rb index ac91eab4ac5188..ec419a9fffdcb1 100644 --- a/test/yarp/comments_test.rb +++ b/test/yarp/comments_test.rb @@ -55,6 +55,30 @@ def test_comment_embedded_document_with_content_on_same_line assert_comment source, :embdoc, 0..24 end + def test_attaching_comments + source = <<~RUBY + # Foo class + class Foo + # bar method + def bar + # baz invocation + baz + end # bar end + end # Foo end + RUBY + + result = YARP.parse(source) + result.attach_comments! + tree = result.value + class_node = tree.statements.body.first + method_node = class_node.body.body.first + call_node = method_node.body.body.first + + assert_equal("# Foo class\n# Foo end\n", class_node.location.comments.map { |c| c.location.slice }.join) + assert_equal("# bar method\n# bar end\n", method_node.location.comments.map { |c| c.location.slice }.join) + assert_equal("# baz invocation\n", call_node.location.comments.map { |c| c.location.slice }.join) + end + private def assert_comment(source, type, location) From 7fc4db35ee41944812011e04226609a1e5580091 Mon Sep 17 00:00:00 2001 From: Jemma Issroff Date: Fri, 8 Sep 2023 15:33:51 -0400 Subject: [PATCH 41/46] [YARP] Implement compilation for RationalNodes, fix other num types (#8404) --- test/yarp/compiler_test.rb | 27 ++++++----- test_code.rb | 1 + yarp/yarp_compiler.c | 98 ++++++++++++++++++++++++++++++++++---- 3 files changed, 105 insertions(+), 21 deletions(-) create mode 100644 test_code.rb diff --git a/test/yarp/compiler_test.rb b/test/yarp/compiler_test.rb index ea8c390362b130..862fc0cc1febe1 100644 --- a/test/yarp/compiler_test.rb +++ b/test/yarp/compiler_test.rb @@ -15,32 +15,37 @@ def test_FalseNode end def test_FloatNode - assert_equal 1.0, compile("1.0") - assert_equal 1.0e0, compile("1.0e0") - assert_equal(+1.0e+0, compile("+1.0e+0")) - assert_equal(-1.0e-0, compile("-1.0e-0")) + assert_equal 1.2, compile("1.2") + assert_equal 1.2e3, compile("1.2e3") + assert_equal(+1.2e+3, compile("+1.2e+3")) + assert_equal(-1.2e-3, compile("-1.2e-3")) end def test_ImaginaryNode - # assert_equal 1i, compile("1i") - # assert_equal +1.0i, compile("+1.0i") - # assert_equal 1ri, compile("1ri") + assert_equal 1i, compile("1i") + assert_equal +1.0i, compile("+1.0i") + assert_equal 1ri, compile("1ri") end def test_IntegerNode assert_equal 1, compile("1") assert_equal(+1, compile("+1")) assert_equal(-1, compile("-1")) - # assert_equal 0x10, compile("0x10") - # assert_equal 0b10, compile("0b10") - # assert_equal 0o10, compile("0o10") - # assert_equal 010, compile("010") + assert_equal 0x10, compile("0x10") + assert_equal 0b10, compile("0b10") + assert_equal 0o10, compile("0o10") + assert_equal 010, compile("010") end def test_NilNode assert_nil compile("nil") end + def test_RationalNode + assert_equal 1.2r, compile("1.2r") + assert_equal +1.2r, compile("+1.2r") + end + def test_SelfNode assert_equal TOPLEVEL_BINDING.eval("self"), compile("self") end diff --git a/test_code.rb b/test_code.rb new file mode 100644 index 00000000000000..f599e28b8ab0d8 --- /dev/null +++ b/test_code.rb @@ -0,0 +1 @@ +10 diff --git a/yarp/yarp_compiler.c b/yarp/yarp_compiler.c index c77e8f36c20d22..fae716bbe932f6 100644 --- a/yarp/yarp_compiler.c +++ b/yarp/yarp_compiler.c @@ -18,7 +18,19 @@ yp_iseq_new_with_opt(yp_scope_node_t *node, yp_parser_t *parser, VALUE name, VAL enum rb_iseq_type type, const rb_compile_option_t *option); static VALUE -parse_number(const yp_node_t *node) { +parse_integer(const yp_node_t *node) +{ + const char *start = (const char *)node->location.start; + const char *end = (const char *)node->location.end; + size_t length = end - start; + VALUE number = rb_int_parse_cstr(start, length, NULL, NULL, -10, RB_INT_PARSE_DEFAULT); + + return number; +} + +static VALUE +parse_float(const yp_node_t *node) +{ const uint8_t *start = node->location.start; const uint8_t *end = node->location.end; size_t length = end - start; @@ -27,19 +39,79 @@ parse_number(const yp_node_t *node) { memcpy(buffer, start, length); buffer[length] = '\0'; - VALUE number = rb_cstr_to_inum(buffer, -10, Qfalse); + VALUE number = DBL2NUM(rb_cstr_to_dbl(buffer, 0)); free(buffer); return number; } +static VALUE +parse_rational(const yp_node_t *node) +{ + const uint8_t *start = node->location.start; + const uint8_t *end = node->location.end - 1; + size_t length = end - start; + + VALUE res; + if (YP_NODE_TYPE_P(((yp_rational_node_t *)node)->numeric, YP_NODE_FLOAT_NODE)) { + char *buffer = malloc(length + 1); + memcpy(buffer, start, length); + + buffer[length] = '\0'; + + char *decimal = memchr(buffer, '.', length); + RUBY_ASSERT(decimal); + size_t seen_decimal = decimal - buffer; + size_t fraclen = length - seen_decimal - 1; + memmove(decimal, decimal + 1, fraclen + 1); + + VALUE v = rb_cstr_to_inum(buffer, 10, false); + res = rb_rational_new(v, rb_int_positive_pow(10, fraclen)); + + free(buffer); + } + else { + RUBY_ASSERT(YP_NODE_TYPE_P(((yp_rational_node_t *)node)->numeric, YP_NODE_INTEGER_NODE)); + VALUE number = rb_int_parse_cstr((const char *)start, length, NULL, NULL, -10, RB_INT_PARSE_DEFAULT); + res = rb_rational_raw(number, INT2FIX(1)); + } + + return res; +} + +static VALUE +parse_imaginary(yp_imaginary_node_t *node) +{ + VALUE imaginary_part; + switch (YP_NODE_TYPE(node->numeric)) { + case YP_NODE_FLOAT_NODE: { + imaginary_part = parse_float(node->numeric); + break; + } + case YP_NODE_INTEGER_NODE: { + imaginary_part = parse_integer(node->numeric); + break; + } + case YP_NODE_RATIONAL_NODE: { + imaginary_part = parse_rational(node->numeric); + break; + } + default: + rb_bug("Unexpected numeric type on imaginary number"); + } + + return rb_complex_raw(INT2FIX(0), imaginary_part); +} + static inline VALUE -parse_string(yp_string_t *string) { +parse_string(yp_string_t *string) +{ return rb_str_new((const char *) yp_string_source(string), yp_string_length(string)); } static inline ID -parse_symbol(const uint8_t *start, const uint8_t *end) { +parse_symbol(const uint8_t *start, const uint8_t *end) +{ return rb_intern2((const char *) start, end - start); } @@ -938,7 +1010,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, yp_defined_node_t *defined_node = (yp_defined_node_t *)node; // TODO: Correct defined_type enum defined_type dtype = DEFINED_CONST; - VALUE sym = parse_number(defined_node->value); + VALUE sym = parse_integer(defined_node->value); ADD_INSN3(ret, &dummy_line_node, defined, INT2FIX(dtype), sym, rb_iseq_defined_string(dtype)); return; @@ -1012,7 +1084,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, } case YP_NODE_FLOAT_NODE: { if (!popped) { - ADD_INSN1(ret, &dummy_line_node, putobject, parse_number(node)); + ADD_INSN1(ret, &dummy_line_node, putobject, parse_float(node)); } return; } @@ -1162,7 +1234,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, } case YP_NODE_IMAGINARY_NODE: { if (!popped) { - ADD_INSN1(ret, &dummy_line_node, putobject, parse_number(node)); + ADD_INSN1(ret, &dummy_line_node, putobject, parse_imaginary((yp_imaginary_node_t *)node)); } return; } @@ -1290,7 +1362,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, } case YP_NODE_INTEGER_NODE: { if (!popped) { - ADD_INSN1(ret, &dummy_line_node, putobject, parse_number(node)); + ADD_INSN1(ret, &dummy_line_node, putobject, parse_integer(node)); } return; } @@ -1621,8 +1693,8 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, yp_node_t *left = range_node->left; yp_node_t *right = range_node->right; VALUE val = rb_range_new( - left && left->type == YP_NODE_INTEGER_NODE ? parse_number(left) : Qnil, - right && right->type == YP_NODE_INTEGER_NODE ? parse_number(right) : Qnil, + left && YP_NODE_TYPE_P(left, YP_NODE_INTEGER_NODE) ? parse_integer(left) : Qnil, + right && YP_NODE_TYPE_P(right, YP_NODE_INTEGER_NODE) ? parse_integer(right) : Qnil, exclusive ); ADD_INSN1(ret, &dummy_line_node, putobject, val); @@ -1648,6 +1720,12 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, } return; } + case YP_NODE_RATIONAL_NODE: { + if (!popped) { + ADD_INSN1(ret, &dummy_line_node, putobject, parse_rational(node)); + } + return; + } case YP_NODE_REDO_NODE: { ADD_INSNL(ret, &dummy_line_node, jump, ISEQ_COMPILE_DATA(iseq)->redo_label); return; From 5d73c0f3dfa489ec3380b997dd151a07e790562a Mon Sep 17 00:00:00 2001 From: Kevin Newton Date: Fri, 8 Sep 2023 14:27:17 -0400 Subject: [PATCH 42/46] [ruby/yarp] Move parse result mutations into their own files https://github.com/ruby/yarp/commit/3be8272fa2 --- lib/yarp.rb | 190 +----------------------------- lib/yarp/parse_result/comments.rb | 174 +++++++++++++++++++++++++++ lib/yarp/parse_result/newlines.rb | 61 ++++++++++ lib/yarp/yarp.gemspec | 2 + test/yarp/newline_test.rb | 2 +- 5 files changed, 241 insertions(+), 188 deletions(-) create mode 100644 lib/yarp/parse_result/comments.rb create mode 100644 lib/yarp/parse_result/newlines.rb diff --git a/lib/yarp.rb b/lib/yarp.rb index 32d4a1b536ab07..f878e719cc32af 100644 --- a/lib/yarp.rb +++ b/lib/yarp.rb @@ -248,193 +248,6 @@ def success? def failure? !success? end - - # CommentAttacher is a utility class to attach comments to locations in the AST - class CommentAttacher - attr_reader :parse_result - - def initialize(parse_result) - @parse_result = parse_result - end - - def attach! - parse_result.comments.each do |comment| - preceding, enclosing, following = nearest_targets(parse_result.value, comment) - target = - if comment.trailing? - preceding || following || enclosing || NodeTarget.new(parse_result.value) - else - # If a comment exists on its own line, prefer a leading comment. - following || preceding || enclosing || NodeTarget.new(parse_result.value) - end - - target << comment - end - end - - # A target for attaching comments that is based on a specific node - class NodeTarget - attr_reader :node - - def initialize(node) - @node = node - end - - def start_offset - node.location.start_offset - end - - def end_offset - node.location.end_offset - end - - def encloses?(comment) - start_offset <= comment.location.start_offset && comment.location.end_offset <= end_offset - end - - def <<(comment) - node.location.comments << comment - end - end - - # A target for attaching comments that is based on a location, which could be a part of a node. For example, the - # `end` token of a ClassNode - class LocationTarget - attr_reader :location - - def initialize(location) - @location = location - end - - def start_offset - location.start_offset - end - - def end_offset - location.end_offset - end - - def encloses?(comment) - false - end - - def <<(comment) - location.comments << comment - end - end - - private - - # Responsible for finding the nearest targets to the given comment within the context of the given encapsulating - # node. - def nearest_targets(node, comment) - comment_start = comment.location.start_offset - comment_end = comment.location.end_offset - - targets = [] - node.deconstruct_keys(nil).each do |key, value| - next if key == :location - - case value - when StatementsNode - targets.concat(value.body.map { |node| NodeTarget.new(node) }) - when Node - targets << NodeTarget.new(value) - when Location - targets << LocationTarget.new(value) - when Array - targets.concat(value.map { |node| NodeTarget.new(node) }) if value.first.is_a?(Node) - end - end - - targets.sort_by!(&:start_offset) - preceding = nil - following = nil - - left = 0 - right = targets.length - - # This is a custom binary search that finds the nearest nodes to the given comment. When it finds a node that - # completely encapsulates the comment, it recursed downward into the tree. - while left < right - middle = (left + right) / 2 - target = targets[middle] - - target_start = target.start_offset - target_end = target.end_offset - - if target.encloses?(comment) - # The comment is completely contained by this target. Abandon the binary search at this level. - return nearest_targets(target.node, comment) - end - - if target_end <= comment_start - # This target falls completely before the comment. Because we will never consider this target or any targets - # before it again, this target must be the closest preceding target we have encountered so far. - preceding = target - left = middle + 1 - next - end - - if comment_end <= target_start - # This target falls completely after the comment. Because we will never consider this target or any targets - # after it again, this target must be the closest following target we have encountered so far. - following = target - right = middle - next - end - - # This should only happen if there is a bug in this parser. - raise "Comment location overlaps with target location" - end - - [preceding, NodeTarget.new(node), following] - end - end - - # Attach the list of comments to their respective locations in the AST - def attach_comments! - CommentAttacher.new(self).attach! - end - - # Keep in sync with Java MarkNewlinesVisitor - class MarkNewlinesVisitor < YARP::Visitor - def initialize(newline_marked) - @newline_marked = newline_marked - end - - def visit_block_node(node) - old_newline_marked = @newline_marked - @newline_marked = Array.new(old_newline_marked.size, false) - begin - super(node) - ensure - @newline_marked = old_newline_marked - end - end - alias_method :visit_lambda_node, :visit_block_node - - def visit_if_node(node) - node.set_newline_flag(@newline_marked) - super(node) - end - alias_method :visit_unless_node, :visit_if_node - - def visit_statements_node(node) - node.body.each do |child| - child.set_newline_flag(@newline_marked) - end - super(node) - end - end - private_constant :MarkNewlinesVisitor - - def mark_newlines - newline_marked = Array.new(1 + @source.offsets.size, false) - visitor = MarkNewlinesVisitor.new(newline_marked) - value.accept(visitor) - value - end end # This represents a token from the Ruby source. @@ -778,6 +591,9 @@ def self.parse_serialize_file(filepath) require_relative "yarp/pack" require_relative "yarp/pattern" +require_relative "yarp/parse_result/comments" +require_relative "yarp/parse_result/newlines" + if RUBY_ENGINE == "ruby" and !ENV["YARP_FFI_BACKEND"] require "yarp/yarp" else diff --git a/lib/yarp/parse_result/comments.rb b/lib/yarp/parse_result/comments.rb new file mode 100644 index 00000000000000..58eb80af59c5d5 --- /dev/null +++ b/lib/yarp/parse_result/comments.rb @@ -0,0 +1,174 @@ +# frozen_string_literal: true + +module YARP + class ParseResult + # When we've parsed the source, we have both the syntax tree and the list of + # comments that we found in the source. This class is responsible for + # walking the tree and finding the nearest location to attach each comment. + # + # It does this by first finding the nearest locations to each comment. + # Locations can either come from nodes directly or from location fields on + # nodes. For example, a `ClassNode` has an overall location encompassing the + # entire class, but it also has a location for the `class` keyword. + # + # Once the nearest locations are found, it determines which one to attach + # to. If it's a trailing comment (a comment on the same line as other source + # code), it will favor attaching to the nearest location that occurs before + # the comment. Otherwise it will favor attaching to the nearest location + # that is after the comment. + class Comments + # A target for attaching comments that is based on a specific node's + # location. + class NodeTarget + attr_reader :node + + def initialize(node) + @node = node + end + + def start_offset + node.location.start_offset + end + + def end_offset + node.location.end_offset + end + + def encloses?(comment) + start_offset <= comment.location.start_offset && + comment.location.end_offset <= end_offset + end + + def <<(comment) + node.location.comments << comment + end + end + + # A target for attaching comments that is based on a location field on a + # node. For example, the `end` token of a ClassNode. + class LocationTarget + attr_reader :location + + def initialize(location) + @location = location + end + + def start_offset + location.start_offset + end + + def end_offset + location.end_offset + end + + def encloses?(comment) + false + end + + def <<(comment) + location.comments << comment + end + end + + attr_reader :parse_result + + def initialize(parse_result) + @parse_result = parse_result + end + + def attach! + parse_result.comments.each do |comment| + preceding, enclosing, following = nearest_targets(parse_result.value, comment) + target = + if comment.trailing? + preceding || following || enclosing || NodeTarget.new(parse_result.value) + else + # If a comment exists on its own line, prefer a leading comment. + following || preceding || enclosing || NodeTarget.new(parse_result.value) + end + + target << comment + end + end + + private + + # Responsible for finding the nearest targets to the given comment within + # the context of the given encapsulating node. + def nearest_targets(node, comment) + comment_start = comment.location.start_offset + comment_end = comment.location.end_offset + + targets = [] + node.deconstruct_keys(nil).each do |key, value| + next if key == :location + + case value + when StatementsNode + targets.concat(value.body.map { |node| NodeTarget.new(node) }) + when Node + targets << NodeTarget.new(value) + when Location + targets << LocationTarget.new(value) + when Array + targets.concat(value.map { |node| NodeTarget.new(node) }) if value.first.is_a?(Node) + end + end + + targets.sort_by!(&:start_offset) + preceding = nil + following = nil + + left = 0 + right = targets.length + + # This is a custom binary search that finds the nearest nodes to the + # given comment. When it finds a node that completely encapsulates the + # comment, it recurses downward into the tree. + while left < right + middle = (left + right) / 2 + target = targets[middle] + + target_start = target.start_offset + target_end = target.end_offset + + if target.encloses?(comment) + # The comment is completely contained by this target. Abandon the + # binary search at this level. + return nearest_targets(target.node, comment) + end + + if target_end <= comment_start + # This target falls completely before the comment. Because we will + # never consider this target or any targets before it again, this + # target must be the closest preceding target we have encountered so + # far. + preceding = target + left = middle + 1 + next + end + + if comment_end <= target_start + # This target falls completely after the comment. Because we will + # never consider this target or any targets after it again, this + # target must be the closest following target we have encountered so + # far. + following = target + right = middle + next + end + + # This should only happen if there is a bug in this parser. + raise "Comment location overlaps with a target location" + end + + [preceding, NodeTarget.new(node), following] + end + end + + # Attach the list of comments to their respective locations in the tree. + def attach_comments! + Comments.new(self).attach! + end + end +end diff --git a/lib/yarp/parse_result/newlines.rb b/lib/yarp/parse_result/newlines.rb new file mode 100644 index 00000000000000..6f355434783225 --- /dev/null +++ b/lib/yarp/parse_result/newlines.rb @@ -0,0 +1,61 @@ +# frozen_string_literal: true + +module YARP + class ParseResult + # The :line tracepoint event gets fired whenever the Ruby VM encounters an + # expression on a new line. The types of expressions that can trigger this + # event are: + # + # * if statements + # * unless statements + # * nodes that are children of statements lists + # + # In order to keep track of the newlines, we have a list of offsets that + # come back from the parser. We assign these offsets to the first nodes that + # we find in the tree that are on those lines. + # + # Note that the logic in this file should be kept in sync with the Java + # MarkNewlinesVisitor, since that visitor is responsible for marking the + # newlines for JRuby/TruffleRuby. + class MarkNewlinesVisitor < Visitor + def initialize(newline_marked) + @newline_marked = newline_marked + end + + def visit_block_node(node) + old_newline_marked = @newline_marked + @newline_marked = Array.new(old_newline_marked.size, false) + + begin + super(node) + ensure + @newline_marked = old_newline_marked + end + end + + alias_method :visit_lambda_node, :visit_block_node + + def visit_if_node(node) + node.set_newline_flag(@newline_marked) + super(node) + end + + alias_method :visit_unless_node, :visit_if_node + + def visit_statements_node(node) + node.body.each do |child| + child.set_newline_flag(@newline_marked) + end + super(node) + end + end + + private_constant :MarkNewlinesVisitor + + # Walk the tree and mark nodes that are on a new line. + def mark_newlines! + newline_marked = Array.new(1 + source.offsets.size, false) + value.accept(MarkNewlinesVisitor.new(newline_marked)) + end + end +end diff --git a/lib/yarp/yarp.gemspec b/lib/yarp/yarp.gemspec index 33b47d676aa25e..0cd1cf2f661823 100644 --- a/lib/yarp/yarp.gemspec +++ b/lib/yarp/yarp.gemspec @@ -68,6 +68,8 @@ Gem::Specification.new do |spec| "lib/yarp/pattern.rb", "lib/yarp/ripper_compat.rb", "lib/yarp/serialize.rb", + "lib/yarp/parse_result/comments.rb", + "lib/yarp/parse_result/newlines.rb", "src/diagnostic.c", "src/enc/yp_big5.c", "src/enc/yp_euc_jp.c", diff --git a/test/yarp/newline_test.rb b/test/yarp/newline_test.rb index 5a85f856f39f5f..ba82b5ef45dc8e 100644 --- a/test/yarp/newline_test.rb +++ b/test/yarp/newline_test.rb @@ -37,7 +37,7 @@ def assert_newlines(base, relative) result = YARP.parse_file(filepath) assert_empty result.errors - result.mark_newlines + result.mark_newlines! visitor = NewlineVisitor.new(result.source) result.value.accept(visitor) From c0f162caab6098b1709cce893c2c86fec88d0d4c Mon Sep 17 00:00:00 2001 From: Kevin Newton Date: Fri, 8 Sep 2023 14:33:21 -0400 Subject: [PATCH 43/46] [ruby/yarp] Template out a comment_targets method https://github.com/ruby/yarp/commit/a94af7c4c8 --- lib/yarp/parse_result/comments.rb | 8 +++----- lib/yarp/parse_result/newlines.rb | 7 +++---- yarp/templates/lib/yarp/node.rb.erb | 10 ++++++++++ 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/lib/yarp/parse_result/comments.rb b/lib/yarp/parse_result/comments.rb index 58eb80af59c5d5..88240609b16c4d 100644 --- a/lib/yarp/parse_result/comments.rb +++ b/lib/yarp/parse_result/comments.rb @@ -100,9 +100,7 @@ def nearest_targets(node, comment) comment_end = comment.location.end_offset targets = [] - node.deconstruct_keys(nil).each do |key, value| - next if key == :location - + node.comment_targets.map do |value| case value when StatementsNode targets.concat(value.body.map { |node| NodeTarget.new(node) }) @@ -110,8 +108,6 @@ def nearest_targets(node, comment) targets << NodeTarget.new(value) when Location targets << LocationTarget.new(value) - when Array - targets.concat(value.map { |node| NodeTarget.new(node) }) if value.first.is_a?(Node) end end @@ -166,6 +162,8 @@ def nearest_targets(node, comment) end end + private_constant :Comments + # Attach the list of comments to their respective locations in the tree. def attach_comments! Comments.new(self).attach! diff --git a/lib/yarp/parse_result/newlines.rb b/lib/yarp/parse_result/newlines.rb index 6f355434783225..d16600afd0d4fb 100644 --- a/lib/yarp/parse_result/newlines.rb +++ b/lib/yarp/parse_result/newlines.rb @@ -17,7 +17,7 @@ class ParseResult # Note that the logic in this file should be kept in sync with the Java # MarkNewlinesVisitor, since that visitor is responsible for marking the # newlines for JRuby/TruffleRuby. - class MarkNewlinesVisitor < Visitor + class Newlines < Visitor def initialize(newline_marked) @newline_marked = newline_marked end @@ -50,12 +50,11 @@ def visit_statements_node(node) end end - private_constant :MarkNewlinesVisitor + private_constant :Newlines # Walk the tree and mark nodes that are on a new line. def mark_newlines! - newline_marked = Array.new(1 + source.offsets.size, false) - value.accept(MarkNewlinesVisitor.new(newline_marked)) + value.accept(Newlines.new(Array.new(1 + source.offsets.size, false))) end end end diff --git a/yarp/templates/lib/yarp/node.rb.erb b/yarp/templates/lib/yarp/node.rb.erb index 0d404063601d0f..9cc4495986c0fd 100644 --- a/yarp/templates/lib/yarp/node.rb.erb +++ b/yarp/templates/lib/yarp/node.rb.erb @@ -48,6 +48,16 @@ module YARP }.compact.join(", ") %>] end + # def comment_targets: () -> Array[Node | Location] + def comment_targets + [<%= node.fields.map { |field| + case field + when YARP::NodeField, YARP::LocationField then field.name + when YARP::OptionalNodeField, YARP::NodeListField, YARP::OptionalLocationField then "*#{field.name}" + end + }.compact.join(", ") %>] + end + # def copy: (**params) -> <%= node.name %> def copy(**params) <%= node.name %>.new( From f4443f3b1c6dd70b6b22470a7d5f8796175aace3 Mon Sep 17 00:00:00 2001 From: Kevin Newton Date: Fri, 8 Sep 2023 15:46:44 -0400 Subject: [PATCH 44/46] [ruby/yarp] Increment version https://github.com/ruby/yarp/commit/2b41ceb754 --- lib/yarp/yarp.gemspec | 2 +- yarp/extension.h | 2 +- yarp/templates/lib/yarp/serialize.rb.erb | 2 +- yarp/version.h | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/yarp/yarp.gemspec b/lib/yarp/yarp.gemspec index 0cd1cf2f661823..e96cb8d40346b6 100644 --- a/lib/yarp/yarp.gemspec +++ b/lib/yarp/yarp.gemspec @@ -2,7 +2,7 @@ Gem::Specification.new do |spec| spec.name = "yarp" - spec.version = "0.10.0" + spec.version = "0.11.0" spec.authors = ["Shopify"] spec.email = ["ruby@shopify.com"] diff --git a/yarp/extension.h b/yarp/extension.h index ccfb6f9454f173..ebcb3d614f02ac 100644 --- a/yarp/extension.h +++ b/yarp/extension.h @@ -1,7 +1,7 @@ #ifndef YARP_EXT_NODE_H #define YARP_EXT_NODE_H -#define EXPECTED_YARP_VERSION "0.10.0" +#define EXPECTED_YARP_VERSION "0.11.0" #include #include diff --git a/yarp/templates/lib/yarp/serialize.rb.erb b/yarp/templates/lib/yarp/serialize.rb.erb index 3f5329e3a9cdc5..370453565c8ea8 100644 --- a/yarp/templates/lib/yarp/serialize.rb.erb +++ b/yarp/templates/lib/yarp/serialize.rb.erb @@ -14,7 +14,7 @@ end module YARP module Serialize MAJOR_VERSION = 0 - MINOR_VERSION = 10 + MINOR_VERSION = 11 PATCH_VERSION = 0 def self.load(input, serialized) diff --git a/yarp/version.h b/yarp/version.h index 60fd830ca7c14b..6c7dd068d33c0f 100644 --- a/yarp/version.h +++ b/yarp/version.h @@ -1,4 +1,4 @@ #define YP_VERSION_MAJOR 0 -#define YP_VERSION_MINOR 10 +#define YP_VERSION_MINOR 11 #define YP_VERSION_PATCH 0 -#define YP_VERSION "0.10.0" +#define YP_VERSION "0.11.0" From 1f35789ffe88c7a52444471bbd28fd27b76b9398 Mon Sep 17 00:00:00 2001 From: git Date: Fri, 8 Sep 2023 19:52:16 +0000 Subject: [PATCH 45/46] Update default gems list at f4443f3b1c6dd70b6b22470a7d5f87 [ci skip] --- NEWS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index d15bf224c74c7e..cb44183265372a 100644 --- a/NEWS.md +++ b/NEWS.md @@ -96,7 +96,7 @@ The following default gems are updated. * time 0.2.2 * timeout 0.4.0 * uri 0.12.2 -* yarp 0.10.0 +* yarp 0.11.0 The following bundled gems are updated. From d9ede18154e125453bc6399463c58603b9a576a8 Mon Sep 17 00:00:00 2001 From: Jemma Issroff Date: Fri, 8 Sep 2023 16:33:05 -0400 Subject: [PATCH 46/46] [YARP] Extract YP_COMPILE helper (#8403) --- yarp/yarp_compiler.c | 135 +++++++++++++++++++++++-------------------- 1 file changed, 72 insertions(+), 63 deletions(-) diff --git a/yarp/yarp_compiler.c b/yarp/yarp_compiler.c index fae716bbe932f6..802c85d808ec82 100644 --- a/yarp/yarp_compiler.c +++ b/yarp/yarp_compiler.c @@ -12,6 +12,15 @@ #define NEW_CHILD_ISEQ(node, name, type, line_no) \ yp_new_child_iseq(iseq, (node), parser, rb_fstring(name), iseq, (type), (line_no)) +#define YP_COMPILE(node) \ + yp_compile_node(iseq, (node), ret, src, popped, compile_context) + +#define YP_COMPILE_POPPED(node) \ + yp_compile_node(iseq, (node), ret, src, true, compile_context) + +#define YP_COMPILE_NOT_POPPED(node) \ + yp_compile_node(iseq, (node), ret, src, false, compile_context) + rb_iseq_t * yp_iseq_new_with_opt(yp_scope_node_t *node, yp_parser_t *parser, VALUE name, VALUE path, VALUE realpath, int first_lineno, const rb_iseq_t *parent, int isolated_depth, @@ -374,7 +383,7 @@ yp_compile_while(rb_iseq_t *iseq, int lineno, yp_node_flags_t flags, enum yp_nod ADD_LABEL(ret, redo_label); if (statements) { - yp_compile_node(iseq, (yp_node_t *)statements, ret, src, true, compile_context); + YP_COMPILE_POPPED((yp_node_t *)statements); } ADD_LABEL(ret, next_label); @@ -424,7 +433,7 @@ yp_interpolated_node_compile(yp_node_list_t parts, rb_iseq_t *iseq, NODE dummy_l ADD_INSN1(ret, &dummy_line_node, putobject, parse_string(&string_node->unescaped)); } else { - yp_compile_node(iseq, part, ret, src, popped, compile_context); + YP_COMPILE(part); ADD_INSN(ret, &dummy_line_node, dup); ADD_INSN1(ret, &dummy_line_node, objtostring, new_callinfo(iseq, idTo_s, 0, VM_CALL_FCALL | VM_CALL_ARGS_SIMPLE , NULL, FALSE)); ADD_INSN(ret, &dummy_line_node, anytostring); @@ -495,7 +504,7 @@ yp_compile_class_path(LINK_ANCHOR *const ret, rb_iseq_t *iseq, const yp_node_t * yp_node_t *parent = ((yp_constant_path_node_t *)constant_path_node)->parent; if (parent) { /* Bar::Foo */ - yp_compile_node(iseq, parent, ret, src, popped, compile_context); + YP_COMPILE(parent); return VM_DEFINECLASS_FLAG_SCOPED; } else { @@ -537,8 +546,8 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, ADD_INSN1(ret, &dummy_line_node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE)); ADD_INSN1(ret, &dummy_line_node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_CBASE)); - yp_compile_node(iseq, alias_node->new_name, ret, src, popped, compile_context); - yp_compile_node(iseq, alias_node->old_name, ret, src, popped, compile_context); + YP_COMPILE(alias_node->new_name); + YP_COMPILE(alias_node->old_name); ADD_SEND(ret, &dummy_line_node, id_core_set_method_alias, INT2FIX(3)); return; @@ -547,7 +556,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, yp_and_node_t *and_node = (yp_and_node_t *) node; LABEL *end_label = NEW_LABEL(lineno); - yp_compile_node(iseq, and_node->left, ret, src, popped, compile_context); + YP_COMPILE(and_node->left); if (!popped) { ADD_INSN(ret, &dummy_line_node, dup); } @@ -556,7 +565,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, if (!popped) { ADD_INSN(ret, &dummy_line_node, pop); } - yp_compile_node(iseq, and_node->right, ret, src, popped, compile_context); + YP_COMPILE(and_node->right); ADD_LABEL(ret, end_label); return; } @@ -564,7 +573,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, yp_arguments_node_t *arguments_node = (yp_arguments_node_t *) node; yp_node_list_t node_list = arguments_node->arguments; for (size_t index = 0; index < node_list.size; index++) { - yp_compile_node(iseq, node_list.nodes[index], ret, src, popped, compile_context); + YP_COMPILE(node_list.nodes[index]); } return; } @@ -580,7 +589,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, } else { for (size_t index = 0; index < elements.size; index++) { - yp_compile_node(iseq, elements.nodes[index], ret, src, popped, compile_context); + YP_COMPILE(elements.nodes[index]); } if (!popped) { @@ -592,15 +601,15 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, } case YP_NODE_ASSOC_NODE: { yp_assoc_node_t *assoc_node = (yp_assoc_node_t *) node; - yp_compile_node(iseq, assoc_node->key, ret, src, popped, compile_context); + YP_COMPILE(assoc_node->key); if (assoc_node->value) { - yp_compile_node(iseq, assoc_node->value, ret, src, popped, compile_context); + YP_COMPILE(assoc_node->value); } return; } case YP_NODE_ASSOC_SPLAT_NODE: { yp_assoc_splat_node_t *assoc_splat_node = (yp_assoc_splat_node_t *)node; - yp_compile_node(iseq, assoc_splat_node->value, ret, src, popped, compile_context); + YP_COMPILE(assoc_splat_node->value); // TODO: Not sure this is accurate, look at FLUSH_CHUNK in the compiler ADD_INSN1(ret, &dummy_line_node, newarraykwsplat, INT2FIX(0)); @@ -623,7 +632,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, case YP_NODE_BEGIN_NODE: { yp_begin_node_t *begin_node = (yp_begin_node_t *) node; if (begin_node->statements) { - yp_compile_node(iseq, (yp_node_t *)begin_node->statements, ret, src, popped, compile_context); + YP_COMPILE((yp_node_t *)begin_node->statements); } else { ADD_INSN(ret, &dummy_line_node, putnil); @@ -633,7 +642,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, case YP_NODE_BREAK_NODE: { yp_break_node_t *break_node = (yp_break_node_t *) node; if (break_node->arguments) { - yp_compile_node(iseq, (yp_node_t *)break_node->arguments, ret, src, Qfalse, compile_context); + YP_COMPILE_NOT_POPPED((yp_node_t *)break_node->arguments); } else { ADD_INSN(ret, &dummy_line_node, putnil); @@ -653,7 +662,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, if (call_node->receiver == NULL) { ADD_INSN(ret, &dummy_line_node, putself); } else { - yp_compile_node(iseq, call_node->receiver, ret, src, false, compile_context); + YP_COMPILE_NOT_POPPED(call_node->receiver); } if (call_node->arguments == NULL) { @@ -662,7 +671,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, } } else { yp_arguments_node_t *arguments = call_node->arguments; - yp_compile_node(iseq, (yp_node_t *) arguments, ret, src, false, compile_context); + YP_COMPILE((yp_node_t *) arguments); orig_argc = (int)arguments->arguments.size; } @@ -713,7 +722,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, yp_compile_class_path(ret, iseq, class_node->constant_path, &dummy_line_node, src, popped, compile_context); if (class_node->superclass) { - yp_compile_node(iseq, class_node->superclass, ret, src, popped, compile_context); + YP_COMPILE(class_node->superclass); } else { ADD_INSN(ret, &dummy_line_node, putnil); @@ -749,7 +758,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, ADD_INSN(ret, &dummy_line_node, pop); } - yp_compile_node(iseq, class_variable_and_write_node->value, ret, src, false, compile_context); + YP_COMPILE_NOT_POPPED(class_variable_and_write_node->value); if (!popped) { ADD_INSN(ret, &dummy_line_node, dup); @@ -772,7 +781,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, class_variable_name_val, get_cvar_ic_value(iseq, class_variable_name_id)); - yp_compile_node(iseq, class_variable_operator_write_node->value, ret, src, false, compile_context); + YP_COMPILE_NOT_POPPED(class_variable_operator_write_node->value); ID method_id = yp_constant_id_lookup(compile_context, class_variable_operator_write_node->operator); int flags = VM_CALL_ARGS_SIMPLE; @@ -810,7 +819,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, ADD_INSN(ret, &dummy_line_node, pop); } - yp_compile_node(iseq, class_variable_or_write_node->value, ret, src, false, compile_context); + YP_COMPILE_NOT_POPPED(class_variable_or_write_node->value); if (!popped) { ADD_INSN(ret, &dummy_line_node, dup); @@ -839,7 +848,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, } case YP_NODE_CLASS_VARIABLE_WRITE_NODE: { yp_class_variable_write_node_t *write_node = (yp_class_variable_write_node_t *) node; - yp_compile_node(iseq, write_node->value, ret, src, false, compile_context); + YP_COMPILE_NOT_POPPED(write_node->value); if (!popped) { ADD_INSN(ret, &dummy_line_node, dup); } @@ -851,7 +860,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, case YP_NODE_CONSTANT_PATH_NODE: { yp_constant_path_node_t *constant_path_node = (yp_constant_path_node_t*) node; if (constant_path_node->parent) { - yp_compile_node(iseq, constant_path_node->parent, ret, src, popped, compile_context); + YP_COMPILE(constant_path_node->parent); } ADD_INSN1(ret, &dummy_line_node, putobject, Qfalse); ADD_INSN1(ret, &dummy_line_node, getconstant, ID2SYM(parse_node_symbol((yp_node_t *)constant_path_node->child))); @@ -859,7 +868,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, } case YP_NODE_CONSTANT_PATH_WRITE_NODE: { yp_constant_path_write_node_t *constant_path_write_node = (yp_constant_path_write_node_t*) node; - yp_compile_node(iseq, constant_path_write_node->value, ret, src, popped, compile_context); + YP_COMPILE(constant_path_write_node->value); if (!popped) { ADD_INSN(ret, &dummy_line_node, dup); } @@ -901,7 +910,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, ADD_INSN(ret, &dummy_line_node, pop); } - yp_compile_node(iseq, constant_and_write_node->value, ret, src, false, compile_context); + YP_COMPILE_NOT_POPPED(constant_and_write_node->value); if (!popped) { ADD_INSN(ret, &dummy_line_node, dup); @@ -921,7 +930,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, ADD_INSN1(ret, &dummy_line_node, putobject, Qtrue); ADD_INSN1(ret, &dummy_line_node, getconstant, ID2SYM(constant_name)); - yp_compile_node(iseq, constant_operator_write_node->value, ret, src, false, compile_context); + YP_COMPILE_NOT_POPPED(constant_operator_write_node->value); ID method_id = yp_constant_id_lookup(compile_context, constant_operator_write_node->operator); int flags = VM_CALL_ARGS_SIMPLE; @@ -965,7 +974,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, } ADD_LABEL(ret, set_label); - yp_compile_node(iseq, constant_or_write_node->value, ret, src, false, compile_context); + YP_COMPILE_NOT_POPPED(constant_or_write_node->value); if (!popped) { ADD_INSN(ret, &dummy_line_node, dup); @@ -979,7 +988,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, } case YP_NODE_CONSTANT_WRITE_NODE: { yp_constant_write_node_t *constant_write_node = (yp_constant_write_node_t *) node; - yp_compile_node(iseq, constant_write_node->value, ret, src, false, compile_context); + YP_COMPILE_NOT_POPPED(constant_write_node->value); if (!popped) { ADD_INSN(ret, &dummy_line_node, dup); @@ -1019,7 +1028,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, yp_embedded_statements_node_t *embedded_statements_node = (yp_embedded_statements_node_t *)node; if (embedded_statements_node->statements) { - yp_compile_node(iseq, (yp_node_t *) (embedded_statements_node->statements), ret, src, popped, compile_context); + YP_COMPILE((yp_node_t *) (embedded_statements_node->statements)); } else { ADD_INSN(ret, &dummy_line_node, putnil); @@ -1033,7 +1042,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, } case YP_NODE_EMBEDDED_VARIABLE_NODE: { yp_embedded_variable_node_t *embedded_node = (yp_embedded_variable_node_t *)node; - yp_compile_node(iseq, embedded_node->variable, ret, src, popped, compile_context); + YP_COMPILE(embedded_node->variable); return; } case YP_NODE_FALSE_NODE: @@ -1058,7 +1067,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, ADD_INSN2(ret, &dummy_line_node, getspecial, key, INT2FIX(0)); ADD_INSNL(ret, &dummy_line_node, branchif, lend); - yp_compile_node(iseq, flip_flop_node->left, ret, src, popped, compile_context); + YP_COMPILE(flip_flop_node->left); /* *flip == 0 */ ADD_INSNL(ret, &dummy_line_node, branchunless, else_label); ADD_INSN1(ret, &dummy_line_node, putobject, Qtrue); @@ -1069,7 +1078,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, /* *flip == 1 */ ADD_LABEL(ret, lend); - yp_compile_node(iseq, flip_flop_node->right, ret, src, popped, compile_context); + YP_COMPILE(flip_flop_node->right); ADD_INSNL(ret, &dummy_line_node, branchunless, then_label); ADD_INSN1(ret, &dummy_line_node, putobject, Qfalse); ADD_INSN1(ret, &dummy_line_node, setspecial, key); @@ -1107,7 +1116,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, ADD_INSN(ret, &dummy_line_node, pop); } - yp_compile_node(iseq, global_variable_and_write_node->value, ret, src, false, compile_context); + YP_COMPILE_NOT_POPPED(global_variable_and_write_node->value); if (!popped) { ADD_INSN(ret, &dummy_line_node, dup); @@ -1124,7 +1133,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, VALUE global_variable_name = ID2SYM(yp_constant_id_lookup(compile_context, global_variable_operator_write_node->name)); ADD_INSN1(ret, &dummy_line_node, getglobal, global_variable_name); - yp_compile_node(iseq, global_variable_operator_write_node->value, ret, src, false, compile_context); + YP_COMPILE_NOT_POPPED(global_variable_operator_write_node->value); ID method_id = yp_constant_id_lookup(compile_context, global_variable_operator_write_node->operator); int flags = VM_CALL_ARGS_SIMPLE; @@ -1165,7 +1174,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, } ADD_LABEL(ret, set_label); - yp_compile_node(iseq, global_variable_or_write_node->value, ret, src, false, compile_context); + YP_COMPILE_NOT_POPPED(global_variable_or_write_node->value); if (!popped) { ADD_INSN(ret, &dummy_line_node, dup); @@ -1187,7 +1196,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, } case YP_NODE_GLOBAL_VARIABLE_WRITE_NODE: { yp_global_variable_write_node_t *write_node = (yp_global_variable_write_node_t *) node; - yp_compile_node(iseq, write_node->value, ret, src, false, compile_context); + YP_COMPILE_NOT_POPPED(write_node->value); if (!popped) { ADD_INSN(ret, &dummy_line_node, dup); } @@ -1214,7 +1223,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, } for (size_t index = 0; index < elements.size; index++) { - yp_compile_node(iseq, elements.nodes[index], ret, src, popped, compile_context); + YP_COMPILE(elements.nodes[index]); } if (!popped) { @@ -1261,7 +1270,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, ADD_INSN(ret, &dummy_line_node, pop); } - yp_compile_node(iseq, instance_variable_and_write_node->value, ret, src, false, compile_context); + YP_COMPILE_NOT_POPPED(instance_variable_and_write_node->value); if (!popped) { ADD_INSN(ret, &dummy_line_node, dup); @@ -1284,7 +1293,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, instance_variable_name_val, get_ivar_ic_value(iseq, instance_variable_name_id)); - yp_compile_node(iseq, instance_variable_operator_write_node->value, ret, src, false, compile_context); + YP_COMPILE_NOT_POPPED(instance_variable_operator_write_node->value); ID method_id = yp_constant_id_lookup(compile_context, instance_variable_operator_write_node->operator); int flags = VM_CALL_ARGS_SIMPLE; @@ -1323,7 +1332,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, ADD_INSN(ret, &dummy_line_node, pop); } - yp_compile_node(iseq, instance_variable_or_write_node->value, ret, src, false, compile_context); + YP_COMPILE_NOT_POPPED(instance_variable_or_write_node->value); if (!popped) { ADD_INSN(ret, &dummy_line_node, dup); @@ -1348,7 +1357,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, } case YP_NODE_INSTANCE_VARIABLE_WRITE_NODE: { yp_instance_variable_write_node_t *write_node = (yp_instance_variable_write_node_t *) node; - yp_compile_node(iseq, write_node->value, ret, src, false, compile_context); + YP_COMPILE_NOT_POPPED(write_node->value); if (!popped) { ADD_INSN(ret, &dummy_line_node, dup); @@ -1425,7 +1434,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, yp_node_list_t elements = keyword_hash_node->elements; for (size_t index = 0; index < elements.size; index++) { - yp_compile_node(iseq, elements.nodes[index], ret, src, popped, compile_context); + YP_COMPILE(elements.nodes[index]); } ADD_INSN1(ret, &dummy_line_node, newhash, INT2FIX(elements.size * 2)); @@ -1467,7 +1476,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, ADD_INSN(ret, &dummy_line_node, pop); } - yp_compile_node(iseq, local_variable_and_write_node->value, ret, src, false, compile_context); + YP_COMPILE_NOT_POPPED(local_variable_and_write_node->value); if (!popped) { ADD_INSN(ret, &dummy_line_node, dup); @@ -1487,7 +1496,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, int local_index = yp_lookup_local_index_with_depth(iseq, compile_context, constant_id, depth); ADD_GETLOCAL(ret, &dummy_line_node, local_index, depth); - yp_compile_node(iseq, local_variable_operator_write_node->value, ret, src, false, compile_context); + YP_COMPILE_NOT_POPPED(local_variable_operator_write_node->value); ID method_id = yp_constant_id_lookup(compile_context, local_variable_operator_write_node->operator); int flags = VM_CALL_ARGS_SIMPLE | VM_CALL_FCALL | VM_CALL_VCALL; @@ -1526,7 +1535,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, } ADD_LABEL(ret, set_label); - yp_compile_node(iseq, local_variable_or_write_node->value, ret, src, false, compile_context); + YP_COMPILE_NOT_POPPED(local_variable_or_write_node->value); if (!popped) { ADD_INSN(ret, &dummy_line_node, dup); @@ -1548,7 +1557,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, } case YP_NODE_LOCAL_VARIABLE_WRITE_NODE: { yp_local_variable_write_node_t *local_write_node = (yp_local_variable_write_node_t *) node; - yp_compile_node(iseq, local_write_node->value, ret, src, false, compile_context); + YP_COMPILE_NOT_POPPED(local_write_node->value); if (!popped) { ADD_INSN(ret, &dummy_line_node, dup); @@ -1588,7 +1597,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, } case YP_NODE_MULTI_WRITE_NODE: { yp_multi_write_node_t *multi_write_node = (yp_multi_write_node_t *)node; - yp_compile_node(iseq, multi_write_node->value, ret, src, popped, compile_context); + YP_COMPILE(multi_write_node->value); // TODO: int flag = 0x02 | (NODE_NAMED_REST_P(restn) ? 0x01 : 0x00); int flag = 0x00; @@ -1598,7 +1607,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, yp_node_list_t node_list = multi_write_node->targets; for (size_t index = 0; index < node_list.size; index++) { - yp_compile_node(iseq, node_list.nodes[index], ret, src, popped, compile_context); + YP_COMPILE(node_list.nodes[index]); } return; @@ -1606,7 +1615,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, case YP_NODE_NEXT_NODE: { yp_next_node_t *next_node = (yp_next_node_t *) node; if (next_node->arguments) { - yp_compile_node(iseq, (yp_node_t *)next_node->arguments, ret, src, Qfalse, compile_context); + YP_COMPILE_NOT_POPPED((yp_node_t *)next_node->arguments); } else { ADD_INSN(ret, &dummy_line_node, putnil); @@ -1633,7 +1642,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, yp_or_node_t *or_node = (yp_or_node_t *) node; LABEL *end_label = NEW_LABEL(lineno); - yp_compile_node(iseq, or_node->left, ret, src, popped, compile_context); + YP_COMPILE(or_node->left); if (!popped) { ADD_INSN(ret, &dummy_line_node, dup); @@ -1643,14 +1652,14 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, if (!popped) { ADD_INSN(ret, &dummy_line_node, pop); } - yp_compile_node(iseq, or_node->right, ret, src, popped, compile_context); + YP_COMPILE(or_node->right); ADD_LABEL(ret, end_label); return; } case YP_NODE_OPTIONAL_PARAMETER_NODE: { yp_optional_parameter_node_t *optional_parameter_node = (yp_optional_parameter_node_t *)node; - yp_compile_node(iseq, optional_parameter_node->value, ret, src, false, compile_context); + YP_COMPILE_NOT_POPPED(optional_parameter_node->value); int index = yp_lookup_local_index(iseq, compile_context, optional_parameter_node->name); @@ -1664,7 +1673,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, if (parentheses_node->body == NULL) { ADD_INSN(ret, &dummy_line_node, putnil); } else { - yp_compile_node(iseq, parentheses_node->body, ret, src, popped, compile_context); + YP_COMPILE(parentheses_node->body); } return; @@ -1679,7 +1688,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, ADD_INSN(ret, &dummy_line_node, leave); } else { yp_scope_node_t *res_node = &scope_node; - yp_compile_node(iseq, (yp_node_t *) res_node, ret, src, popped, compile_context); + YP_COMPILE((yp_node_t *) res_node); } return; @@ -1705,13 +1714,13 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, if (range_node->left == NULL) { ADD_INSN(ret, &dummy_line_node, putnil); } else { - yp_compile_node(iseq, range_node->left, ret, src, popped, compile_context); + YP_COMPILE(range_node->left); } if (range_node->right == NULL) { ADD_INSN(ret, &dummy_line_node, putnil); } else { - yp_compile_node(iseq, range_node->right, ret, src, popped, compile_context); + YP_COMPILE(range_node->right); } if (!popped) { @@ -1744,7 +1753,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, yp_arguments_node_t *arguments = ((yp_return_node_t *)node)->arguments; if (arguments) { - yp_compile_node(iseq, (yp_node_t *)arguments, ret, src, popped, compile_context); + YP_COMPILE((yp_node_t *)arguments); } else { ADD_INSN(ret, &dummy_line_node, putnil); @@ -1886,7 +1895,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, const rb_iseq_t *singleton_class = NEW_ISEQ(&scope_node, rb_fstring_lit("singleton class"), ISEQ_TYPE_CLASS, lineno); - yp_compile_node(iseq, singleton_class_node->expression, ret, src, popped, compile_context); + YP_COMPILE(singleton_class_node->expression); ADD_INSN(ret, &dummy_line_node, putnil); ID singletonclass; CONST_ID(singletonclass, "singletonclass"); @@ -1937,7 +1946,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, } case YP_NODE_SPLAT_NODE: { yp_splat_node_t *splat_node = (yp_splat_node_t *)node; - yp_compile_node(iseq, splat_node->expression, ret, src, popped, compile_context); + YP_COMPILE(splat_node->expression); ADD_INSN1(ret, &dummy_line_node, splatarray, Qtrue); @@ -1950,10 +1959,10 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, yp_statements_node_t *statements_node = (yp_statements_node_t *) node; yp_node_list_t node_list = statements_node->body; for (size_t index = 0; index < node_list.size - 1; index++) { - yp_compile_node(iseq, node_list.nodes[index], ret, src, true, compile_context); + YP_COMPILE_POPPED(node_list.nodes[index]); } if (node_list.size > 0) { - yp_compile_node(iseq, node_list.nodes[node_list.size - 1], ret, src, popped, compile_context); + YP_COMPILE(node_list.nodes[node_list.size - 1]); } else { ADD_INSN(ret, &dummy_line_node, putnil); @@ -1962,8 +1971,8 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, } case YP_NODE_STRING_CONCAT_NODE: { yp_string_concat_node_t *str_concat_node = (yp_string_concat_node_t *)node; - yp_compile_node(iseq, str_concat_node->left, ret, src, popped, compile_context); - yp_compile_node(iseq, str_concat_node->right, ret, src, popped, compile_context); + YP_COMPILE(str_concat_node->left); + YP_COMPILE(str_concat_node->right); return; } case YP_NODE_STRING_NODE: { @@ -1992,7 +2001,7 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, ADD_INSN1(ret, &dummy_line_node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE)); ADD_INSN1(ret, &dummy_line_node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_CBASE)); - yp_compile_node(iseq, undef_node->names.nodes[index], ret, src, popped, compile_context); + YP_COMPILE(undef_node->names.nodes[index]); ADD_SEND(ret, &dummy_line_node, rb_intern("core#undef_method"), INT2NUM(2));