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 }} 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/NEWS.md b/NEWS.md index f424808bf2d203..cb44183265372a 100644 --- a/NEWS.md +++ b/NEWS.md @@ -96,11 +96,11 @@ 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. -* minitest 5.19.0 +* minitest 5.20.0 * test-unit 3.6.1 * rexml 3.2.6 * rss 0.3.0 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); 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/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+ :: diff --git a/gc.c b/gc.c index fb5cb14ad44e78..356ef22fc2e24e 100644 --- a/gc.c +++ b/gc.c @@ -773,7 +773,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_global_gc : 1; unsigned int during_incremental_marking : 1; @@ -2926,7 +2926,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 @@ -2936,7 +2936,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 { \ @@ -3467,7 +3467,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 = UNLIKELY(borrowing) ? newobj_alloc_borrowing(objspace, cr, size_pool_idx, false) : newobj_alloc(objspace, cr, size_pool_idx, false); newobj_init(klass, flags, wb_protected, objspace, obj); diff --git a/gems/bundled_gems b/gems/bundled_gems index f11380027ac77c..a12fd3bac3e2cf 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 @@ -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/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( 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 7cd24092c93112..44102c47c829a5 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 @@ -274,9 +274,9 @@ 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) + specs.use remote_specs end def dependency_names_to_double_check @@ -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) @@ -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 diff --git a/lib/yarp.rb b/lib/yarp.rb index 769b149bcabf55..f878e719cc32af 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 @@ -229,45 +248,6 @@ def success? def failure? !success? 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. @@ -540,10 +520,10 @@ 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 { |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 & @@ -611,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..88240609b16c4d --- /dev/null +++ b/lib/yarp/parse_result/comments.rb @@ -0,0 +1,172 @@ +# 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.comment_targets.map do |value| + 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) + 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 + + private_constant :Comments + + # 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..d16600afd0d4fb --- /dev/null +++ b/lib/yarp/parse_result/newlines.rb @@ -0,0 +1,60 @@ +# 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 Newlines < 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 :Newlines + + # Walk the tree and mark nodes that are on a new line. + def mark_newlines! + value.accept(Newlines.new(Array.new(1 + source.offsets.size, false))) + end + end +end diff --git a/lib/yarp/yarp.gemspec b/lib/yarp/yarp.gemspec index 33b47d676aa25e..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"] @@ -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/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/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/process.c b/process.c index acb74c2d47b167..681535d92fd452 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 + * + * The behavior is unspecified 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 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 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_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 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_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")}} 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{ 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) diff --git a/test/yarp/compiler_test.rb b/test/yarp/compiler_test.rb index d1cd7e33055476..862fc0cc1febe1 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 # ############################################################################ @@ -11,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 @@ -164,6 +173,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"') @@ -174,6 +189,15 @@ 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_RegularExpressionNode + assert_equal /yct/, compile('/yct/') + end + def test_StringConcatNode # assert_equal "YARP::CompilerTest", compile('"YARP" "::" "CompilerTest"') end diff --git a/test/yarp/errors_test.rb b/test/yarp/errors_test.rb index 6c03960ec3ed3e..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 @@ -19,15 +19,14 @@ def test_module_name_recoverable Location(), ConstantReadNode(:Parent), StatementsNode( - [ModuleNode([], Location(), MissingNode(), nil, Location(), :"", :"")] + [ModuleNode([], Location(), MissingNode(), nil, Location(), :"")] ), Location(), - :Parent, :Parent ) 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 @@ -43,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 @@ -59,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 @@ -74,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 @@ -99,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 @@ -137,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 @@ -329,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 @@ -350,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 @@ -385,16 +384,17 @@ 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 def test_module_definition_in_method_body expected = DefNode( + :foo, Location(), nil, nil, - StatementsNode([ModuleNode([], Location(), ConstantReadNode(:A), nil, Location(), :A, :A)]), + StatementsNode([ModuleNode([], Location(), ConstantReadNode(:A), nil, Location(), :A)]), [], Location(), nil, @@ -405,12 +405,13 @@ 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 def test_module_definition_in_method_body_within_block expected = DefNode( + :foo, Location(), nil, nil, @@ -425,7 +426,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() ), @@ -442,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 @@ -453,6 +454,7 @@ module Foo;end def test_class_definition_in_method_body expected = DefNode( + :foo, Location(), nil, nil, @@ -465,7 +467,6 @@ def test_class_definition_in_method_body nil, nil, Location(), - :A, :A )] ), @@ -479,12 +480,13 @@ 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 def test_bad_arguments expected = DefNode( + :foo, Location(), nil, ParametersNode([ @@ -504,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 @@ -538,20 +540,21 @@ 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 def test_do_not_allow_trailing_commas_in_method_parameters expected = DefNode( + :foo, Location(), nil, ParametersNode( @@ -574,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 @@ -593,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 @@ -601,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 @@ -615,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 @@ -623,18 +626,19 @@ 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 def test_method_parameters_after_block expected = DefNode( + :foo, Location(), nil, ParametersNode( @@ -662,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())), @@ -682,6 +687,7 @@ def test_method_with_arguments_after_anonymous_block def test_method_parameters_after_arguments_forwarding expected = DefNode( + :foo, Location(), nil, ParametersNode( @@ -709,6 +715,7 @@ def test_method_parameters_after_arguments_forwarding def test_keywords_parameters_before_required_parameters expected = DefNode( + :foo, Location(), nil, ParametersNode( @@ -716,7 +723,7 @@ def test_keywords_parameters_before_required_parameters [], [RequiredParameterNode(:a)], nil, - [KeywordParameterNode(Location(), nil)], + [KeywordParameterNode(:b, Location(), nil)], nil, nil ), @@ -736,6 +743,7 @@ def test_keywords_parameters_before_required_parameters def test_rest_keywords_parameters_before_required_parameters expected = DefNode( + :foo, Location(), nil, ParametersNode( @@ -743,8 +751,8 @@ def test_rest_keywords_parameters_before_required_parameters [], [], nil, - [KeywordParameterNode(Location(), nil)], - KeywordRestParameterNode(Location(), Location()), + [KeywordParameterNode(:b, Location(), nil)], + KeywordRestParameterNode(:rest, Location(), Location()), nil ), nil, @@ -756,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] ] @@ -763,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), @@ -783,6 +793,7 @@ def test_double_arguments_forwarding def test_multiple_error_in_parameters_order expected = DefNode( + :foo, Location(), nil, ParametersNode( @@ -790,8 +801,8 @@ def test_multiple_error_in_parameters_order [], [RequiredParameterNode(:a)], nil, - [KeywordParameterNode(Location(), nil)], - KeywordRestParameterNode(Location(), Location()), + [KeywordParameterNode(:b, Location(), nil)], + KeywordRestParameterNode(:args, Location(), Location()), nil ), nil, @@ -812,6 +823,7 @@ def test_multiple_error_in_parameters_order def test_switching_to_optional_arguments_twice expected = DefNode( + :foo, Location(), nil, ParametersNode( @@ -819,8 +831,8 @@ def test_switching_to_optional_arguments_twice [], [RequiredParameterNode(:a)], nil, - [KeywordParameterNode(Location(), nil)], - KeywordRestParameterNode(Location(), Location()), + [KeywordParameterNode(:b, Location(), nil)], + KeywordRestParameterNode(:args, Location(), Location()), nil ), nil, @@ -841,6 +853,7 @@ def test_switching_to_optional_arguments_twice def test_switching_to_named_arguments_twice expected = DefNode( + :foo, Location(), nil, ParametersNode( @@ -848,8 +861,8 @@ def test_switching_to_named_arguments_twice [], [RequiredParameterNode(:a)], nil, - [KeywordParameterNode(Location(), nil)], - KeywordRestParameterNode(Location(), Location()), + [KeywordParameterNode(:b, Location(), nil)], + KeywordRestParameterNode(:args, Location(), Location()), nil ), nil, @@ -870,6 +883,7 @@ def test_switching_to_named_arguments_twice def test_returning_to_optional_parameters_multiple_times expected = DefNode( + :foo, Location(), nil, ParametersNode( @@ -909,12 +923,13 @@ 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 def test_setter_method_cannot_be_defined_in_an_endless_method_definition expected = DefNode( + :a=, Location(), nil, nil, @@ -929,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 @@ -944,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 @@ -968,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 @@ -981,12 +996,11 @@ def test_dont_allow_return_inside_class_body nil, StatementsNode([ReturnNode(Location(), nil)]), Location(), - :A, :A ) 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 @@ -997,12 +1011,11 @@ def test_dont_allow_return_inside_module_body ConstantReadNode(:A), StatementsNode([ReturnNode(Location(), nil)]), Location(), - :A, :A ) 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 @@ -1020,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 @@ -1030,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), @@ -1044,14 +1058,15 @@ 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 expected = DefNode( + :foo, 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(), @@ -1063,13 +1078,14 @@ 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( + :foo, 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(), @@ -1081,10 +1097,11 @@ 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( + :foo, Location(), nil, ParametersNode([RequiredParameterNode(:a), RequiredParameterNode(:b)], [], [], nil, [], nil, BlockParameterNode(:a, Location(), Location())), @@ -1099,13 +1116,14 @@ 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( + :foo, 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(), @@ -1116,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/test/yarp/location_test.rb b/test/yarp/location_test.rb index d86afb0b3bb1a4..6b219a0b3664c3 100644 --- a/test/yarp/location_test.rb +++ b/test/yarp/location_test.rb @@ -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) = qux", 5...15) { |node| node.targets.last } + end + def test_MultiWriteNode assert_location(MultiWriteNode, "foo, bar = baz") end 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) 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/test/yarp/snapshots/arrays.txt b/test/yarp/snapshots/arrays.txt index ec251f0827757d..a29cbeecb56433 100644 --- a/test/yarp/snapshots/arrays.txt +++ b/test/yarp/snapshots/arrays.txt @@ -359,14 +359,14 @@ ProgramNode(0...511)( 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/blocks.txt b/test/yarp/snapshots/blocks.txt index 4a2c3f7585eeff..b23965960afcdf 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)() )], @@ -602,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/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/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/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/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/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/method_calls.txt b/test/yarp/snapshots/method_calls.txt index f320ab86feed20..37f03ef25f572c 100644 --- a/test/yarp/snapshots/method_calls.txt +++ b/test/yarp/snapshots/method_calls.txt @@ -390,14 +390,14 @@ ProgramNode(0...1237)( 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"), @@ -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/methods.txt b/test/yarp/snapshots/methods.txt index 13a81d15cda623..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)( @@ -218,7 +229,7 @@ ProgramNode(0...1194)( [], [], nil, - [KeywordParameterNode(212...214)((212...214), nil)], + [KeywordParameterNode(212...214)(:b, (212...214), nil)], nil, nil ), @@ -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)( @@ -240,7 +252,7 @@ ProgramNode(0...1194)( [], [], nil, - [KeywordParameterNode(235...237)((235...237), nil)], + [KeywordParameterNode(235...237)(:b, (235...237), nil)], nil, nil ), @@ -254,6 +266,7 @@ ProgramNode(0...1194)( (239...242) ), DefNode(244...258)( + :a, (248...249), nil, ParametersNode(250...253)( @@ -262,7 +275,7 @@ ProgramNode(0...1194)( [], nil, [], - KeywordRestParameterNode(250...253)((250...252), (252...253)), + KeywordRestParameterNode(250...253)(:b, (252...253), (250...252)), nil ), nil, @@ -275,6 +288,7 @@ ProgramNode(0...1194)( (255...258) ), DefNode(260...273)( + :a, (264...265), nil, ParametersNode(266...268)( @@ -283,7 +297,7 @@ ProgramNode(0...1194)( [], nil, [], - KeywordRestParameterNode(266...268)((266...268), nil), + KeywordRestParameterNode(266...268)(nil, nil, (266...268)), nil ), nil, @@ -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)( @@ -359,8 +377,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)() )], @@ -377,6 +396,7 @@ ProgramNode(0...1194)( (342...345) ), DefNode(347...366)( + :a, (351...352), nil, ParametersNode(353...361)( @@ -384,8 +404,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)() )], @@ -402,6 +423,7 @@ ProgramNode(0...1194)( (363...366) ), DefNode(368...389)( + :a, (372...373), nil, ParametersNode(374...384)( @@ -410,10 +432,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 ), @@ -428,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)( @@ -460,6 +484,7 @@ ProgramNode(0...1194)( (418...421) ), DefNode(423...434)( + :a, (427...428), nil, nil, @@ -473,6 +498,7 @@ ProgramNode(0...1194)( (431...434) ), DefNode(436...454)( + :a, (440...441), nil, ParametersNode(442...450)( @@ -499,6 +525,7 @@ ProgramNode(0...1194)( (451...454) ), DefNode(456...467)( + :a, (460...461), nil, ParametersNode(462...463)( @@ -520,6 +547,7 @@ ProgramNode(0...1194)( (464...467) ), DefNode(469...501)( + :a, (473...474), nil, nil, @@ -540,13 +568,14 @@ ProgramNode(0...1194)( (498...501) ), DefNode(503...515)( + :a, (507...508), nil, ParametersNode(509...511)( [], [], [], - RestParameterNode(509...511)((509...510), (510...511)), + RestParameterNode(509...511)(:b, (510...511), (509...510)), [], nil, nil @@ -561,13 +590,14 @@ ProgramNode(0...1194)( (512...515) ), DefNode(517...529)( + :a, (521...522), nil, ParametersNode(523...524)( [], [], [], - RestParameterNode(523...524)((523...524), nil), + RestParameterNode(523...524)(nil, nil, (523...524)), [], nil, nil @@ -582,6 +612,7 @@ ProgramNode(0...1194)( (526...529) ), DefNode(531...546)( + :a, (535...536), nil, nil, @@ -603,6 +634,7 @@ ProgramNode(0...1194)( (543...546) ), DefNode(548...562)( + :a, (557...558), SelfNode(552...556)(), nil, @@ -616,6 +648,7 @@ ProgramNode(0...1194)( (559...562) ), DefNode(564...578)( + :a, (573...574), TrueNode(568...572)(), nil, @@ -629,6 +662,7 @@ ProgramNode(0...1194)( (575...578) ), DefNode(580...589)( + :a, (584...585), nil, nil, @@ -642,6 +676,7 @@ ProgramNode(0...1194)( (586...589) ), DefNode(591...625)( + :hi, (595...597), nil, nil, @@ -671,6 +706,7 @@ ProgramNode(0...1194)( (622...625) ), DefNode(627...638)( + :foo, (631...634), nil, nil, @@ -684,6 +720,7 @@ ProgramNode(0...1194)( nil ), DefNode(639...650)( + :bar, (643...646), nil, nil, @@ -697,6 +734,7 @@ ProgramNode(0...1194)( nil ), DefNode(652...670)( + :foo, (656...659), nil, ParametersNode(660...663)( @@ -718,6 +756,7 @@ ProgramNode(0...1194)( nil ), DefNode(672...685)( + :foo, (676...679), nil, nil, @@ -731,13 +770,14 @@ ProgramNode(0...1194)( nil ), DefNode(687...706)( + :a, (691...692), nil, ParametersNode(693...694)( [], [], [], - RestParameterNode(693...694)((693...694), nil), + RestParameterNode(693...694)(nil, nil, (693...694)), [], nil, nil @@ -764,6 +804,7 @@ ProgramNode(0...1194)( (703...706) ), DefNode(708...731)( + :a, (712...713), nil, ParametersNode(714...717)( @@ -797,6 +838,7 @@ ProgramNode(0...1194)( (728...731) ), DefNode(733...762)( + :a, (737...738), nil, ParametersNode(739...742)( @@ -834,6 +876,7 @@ ProgramNode(0...1194)( (759...762) ), DefNode(764...781)( + :a, (776...777), ParenthesesNode(768...775)( LocalVariableWriteNode(769...774)( @@ -867,6 +910,7 @@ ProgramNode(0...1194)( (778...781) ), DefNode(783...795)( + :a, (787...788), nil, ParametersNode(789...791)( @@ -888,6 +932,7 @@ ProgramNode(0...1194)( (792...795) ), DefNode(797...809)( + :a, (801...802), nil, ParametersNode(803...804)( @@ -909,6 +954,7 @@ ProgramNode(0...1194)( (806...809) ), DefNode(811...826)( + :a, (821...822), ClassVariableReadNode(815...820)(:@@var), nil, @@ -922,6 +968,7 @@ ProgramNode(0...1194)( (823...826) ), DefNode(828...845)( + :C, (840...841), ParenthesesNode(832...839)( LocalVariableWriteNode(833...838)( @@ -955,6 +1002,7 @@ ProgramNode(0...1194)( (842...845) ), DefNode(847...875)( + :Array_function, (856...870), SelfNode(851...855)(), nil, @@ -974,6 +1022,7 @@ ProgramNode(0...1194)( (883...884) ), DefNode(888...903)( + :a, (898...899), ConstantReadNode(892...897)(:Const), nil, @@ -987,6 +1036,7 @@ ProgramNode(0...1194)( (900...903) ), DefNode(905...936)( + :a, (909...910), nil, ParametersNode(911...914)( @@ -1033,6 +1083,7 @@ ProgramNode(0...1194)( (933...936) ), DefNode(938...980)( + :foo, (942...945), nil, nil, @@ -1103,6 +1154,7 @@ ProgramNode(0...1194)( (977...980) ), DefNode(982...1006)( + :bar, (986...989), nil, ParametersNode(990...1001)( @@ -1111,6 +1163,7 @@ ProgramNode(0...1194)( [], nil, [KeywordParameterNode(990...1001)( + :a, (990...992), ParenthesesNode(993...1001)( StatementsNode(994...1000)( @@ -1138,6 +1191,7 @@ ProgramNode(0...1194)( (1003...1006) ), DefNode(1008...1031)( + :bar, (1012...1015), nil, ParametersNode(1016...1026)( @@ -1146,6 +1200,7 @@ ProgramNode(0...1194)( [], nil, [KeywordParameterNode(1016...1026)( + :a, (1016...1018), ParenthesesNode(1019...1026)( StatementsNode(1020...1025)( @@ -1173,6 +1228,7 @@ ProgramNode(0...1194)( (1028...1031) ), DefNode(1033...1055)( + :bar, (1037...1040), nil, ParametersNode(1041...1050)( @@ -1181,6 +1237,7 @@ ProgramNode(0...1194)( [], nil, [KeywordParameterNode(1041...1050)( + :a, (1041...1043), ParenthesesNode(1044...1050)( StatementsNode(1045...1049)( @@ -1208,6 +1265,7 @@ ProgramNode(0...1194)( (1052...1055) ), DefNode(1057...1082)( + :bar, (1061...1064), nil, ParametersNode(1065...1077)( @@ -1245,6 +1303,7 @@ ProgramNode(0...1194)( (1079...1082) ), DefNode(1084...1108)( + :bar, (1088...1091), nil, ParametersNode(1092...1103)( @@ -1282,6 +1341,7 @@ ProgramNode(0...1194)( (1105...1108) ), DefNode(1110...1133)( + :bar, (1114...1117), nil, ParametersNode(1118...1128)( @@ -1319,6 +1379,7 @@ ProgramNode(0...1194)( (1130...1133) ), DefNode(1135...1167)( + :method, (1139...1145), nil, ParametersNode(1146...1147)( @@ -1380,6 +1441,7 @@ ProgramNode(0...1194)( (1164...1167) ), DefNode(1169...1194)( + :foo, (1173...1176), nil, ParametersNode(1177...1189)( 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/non_alphanumeric_methods.txt b/test/yarp/snapshots/non_alphanumeric_methods.txt index a8e9cd798fb465..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)( @@ -115,7 +124,7 @@ ProgramNode(0...434)( [], nil, [], - KeywordRestParameterNode(110...113)((110...112), (112...113)), + KeywordRestParameterNode(110...113)(:b, (112...113), (110...112)), nil ), nil, @@ -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/procs.txt b/test/yarp/snapshots/procs.txt index 64ad900220fa5f..fca9ccb7103a9a 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)) ), @@ -116,10 +116,10 @@ ProgramNode(0...266)( IntegerNode(142...143)() )], [], - RestParameterNode(145...147)((145...146), (146...147)), - [KeywordParameterNode(149...151)((149...151), nil), - KeywordParameterNode(153...155)((153...155), nil)], - KeywordRestParameterNode(157...160)((157...159), (159...160)), + 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)), BlockParameterNode(162...164)(:g, (163...164), (162...163)) ), [], @@ -143,10 +143,10 @@ ProgramNode(0...266)( IntegerNode(184...185)() )], [], - RestParameterNode(187...189)((187...188), (188...189)), - [KeywordParameterNode(191...193)((191...193), nil), - KeywordParameterNode(195...197)((195...197), nil)], - KeywordRestParameterNode(199...202)((199...201), (201...202)), + 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)), BlockParameterNode(204...206)(:g, (205...206), (204...205)) ), [], @@ -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/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 6ae8ed6d031f7d..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)( @@ -87,7 +88,6 @@ ProgramNode(0...689)( )] ), (266...269), - :X, :X ), ClassNode(293...376)( @@ -112,12 +112,10 @@ ProgramNode(0...689)( )] ), (355...358), - :Y, :Y )] ), (373...376), - :X, :X ), ClassNode(395...498)( @@ -128,6 +126,7 @@ ProgramNode(0...689)( nil, StatementsNode(417...480)( [DefNode(417...480)( + :y, (421...422), nil, ParametersNode(423...444)( @@ -165,7 +164,6 @@ ProgramNode(0...689)( )] ), (495...498), - :X, :X ), ModuleNode(517...565)( @@ -186,7 +184,6 @@ ProgramNode(0...689)( )] ), (562...565), - :X, :X ), ModuleNode(568...651)( @@ -207,12 +204,10 @@ ProgramNode(0...689)( )] ), (630...633), - :Y, :Y )] ), (648...651), - :X, :X ), CallNode(670...689)( diff --git a/test/yarp/snapshots/seattlerb/args_kw_block.txt b/test/yarp/snapshots/seattlerb/args_kw_block.txt index c11a1590702c09..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)( @@ -9,7 +10,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_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_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_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_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/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/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/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/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 905c5914a2f19b..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, @@ -23,7 +24,6 @@ ProgramNode(19...71)( )] ), (68...71), - :X, :X )] ) diff --git a/test/yarp/snapshots/seattlerb/defn_arg_asplat_arg.txt b/test/yarp/snapshots/seattlerb/defn_arg_asplat_arg.txt index 6e7e9478f14181..207e45aab9eed4 100644 --- a/test/yarp/snapshots/seattlerb/defn_arg_asplat_arg.txt +++ b/test/yarp/snapshots/seattlerb/defn_arg_asplat_arg.txt @@ -2,13 +2,14 @@ ProgramNode(0...29)( [], StatementsNode(0...29)( [DefNode(0...29)( + :call, (4...8), nil, ParametersNode(9...24)( [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_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 5872579ee6ef8b..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)( @@ -10,7 +11,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_kwarg.txt b/test/yarp/snapshots/seattlerb/defn_kwarg_kwarg.txt index 6dcd4aaf2bd2f7..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)( @@ -9,8 +10,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..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)( @@ -9,8 +10,8 @@ ProgramNode(0...20)( [], [], nil, - [KeywordParameterNode(6...10)((6...8), IntegerNode(9...10)())], - KeywordRestParameterNode(12...15)((12...14), (14...15)), + [KeywordParameterNode(6...10)(:b, (6...8), IntegerNode(9...10)())], + 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 3dfb42f6d7525a..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)( @@ -9,8 +10,8 @@ ProgramNode(0...19)( [], [], nil, - [KeywordParameterNode(6...10)((6...8), IntegerNode(9...10)())], - KeywordRestParameterNode(12...14)((12...14), nil), + [KeywordParameterNode(6...10)(:b, (6...8), IntegerNode(9...10)())], + KeywordRestParameterNode(12...14)(nil, nil, (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..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)( @@ -10,6 +11,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..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)( @@ -9,7 +10,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..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)( @@ -9,7 +10,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/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 bbbdc17368d7b9..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)( @@ -31,7 +32,6 @@ ProgramNode(0...28)( )] ), (25...28), - :X, :X )] ) 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 cd181b55b3aa0a..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)( @@ -13,7 +14,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_powarg.txt b/test/yarp/snapshots/seattlerb/defn_powarg.txt index a6d63f56cb44e9..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)( @@ -10,7 +11,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/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 0fb8bb01c157d9..95a16a11b56e25 100644 --- a/test/yarp/snapshots/seattlerb/defn_splat_arg.txt +++ b/test/yarp/snapshots/seattlerb/defn_splat_arg.txt @@ -2,13 +2,14 @@ ProgramNode(0...15)( [], StatementsNode(0...15)( [DefNode(0...15)( + :f, (4...5), nil, ParametersNode(6...10)( [], [], [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/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 0309161b8e4fab..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)( @@ -9,7 +10,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/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 1a88fffa507e10..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)( @@ -31,7 +32,6 @@ ProgramNode(0...33)( )] ), (30...33), - :X, :X )] ) 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/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/f_kw.txt b/test/yarp/snapshots/seattlerb/f_kw.txt index ace0997f9e1378..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)( @@ -9,7 +10,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..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)( @@ -9,7 +10,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_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/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..5ade32c4838c74 100644 --- a/test/yarp/snapshots/seattlerb/iter_kwarg_kwsplat.txt +++ b/test/yarp/snapshots/seattlerb/iter_kwarg_kwsplat.txt @@ -16,8 +16,8 @@ ProgramNode(0...17)( [], [], nil, - [KeywordParameterNode(5...9)((5...7), IntegerNode(8...9)())], - KeywordRestParameterNode(11...14)((11...13), (13...14)), + [KeywordParameterNode(5...9)(:b, (5...7), IntegerNode(8...9)())], + KeywordRestParameterNode(11...14)(:c, (13...14), (11...13)), nil ), [], diff --git a/test/yarp/snapshots/seattlerb/magic_encoding_comment.txt b/test/yarp/snapshots/seattlerb/magic_encoding_comment.txt index 77efd6f4160317..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, @@ -31,7 +32,6 @@ ProgramNode(18...90)( )] ), (87...90), - :ExampleUTF8ClassNameVarietà, :ExampleUTF8ClassNameVarietà )] ) diff --git a/test/yarp/snapshots/seattlerb/masgn_anon_splat_arg.txt b/test/yarp/snapshots/seattlerb/masgn_anon_splat_arg.txt index c57ea8778fa388..2fb68f7b6db4ea 100644 --- a/test/yarp/snapshots/seattlerb/masgn_anon_splat_arg.txt +++ b/test/yarp/snapshots/seattlerb/masgn_anon_splat_arg.txt @@ -2,18 +2,12 @@ ProgramNode(0...8)( [:a], StatementsNode(0...8)( [MultiWriteNode(0...8)( - [MultiWriteNode(0...1)( - [SplatNode(0...1)((0...1), nil)], - nil, - nil, - nil, - nil - ), + [MultiTargetNode(0...1)([SplatNode(0...1)((0...1), nil)], nil, nil), LocalVariableTargetNode(3...4)(:a, 0)], - (5...6), - CallNode(7...8)(nil, nil, (7...8), nil, nil, nil, nil, 2, "b"), nil, - 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 1a8275332e534b..fd2eeb213aa871 100644 --- a/test/yarp/snapshots/seattlerb/masgn_arg_colon_arg.txt +++ b/test/yarp/snapshots/seattlerb/masgn_arg_colon_arg.txt @@ -14,10 +14,10 @@ ProgramNode(0...11)( 0, "c=" )], - (8...9), - CallNode(10...11)(nil, nil, (10...11), nil, nil, nil, nil, 2, "d"), nil, - 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 da590680c034a3..a8b17ce70710c1 100644 --- a/test/yarp/snapshots/seattlerb/masgn_arg_ident.txt +++ b/test/yarp/snapshots/seattlerb/masgn_arg_ident.txt @@ -14,10 +14,10 @@ ProgramNode(0...10)( 0, "C=" )], - (7...8), - CallNode(9...10)(nil, nil, (9...10), nil, nil, nil, nil, 2, "d"), nil, - 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 c22781a5d01f29..e922b3b5e8737e 100644 --- a/test/yarp/snapshots/seattlerb/masgn_arg_splat_arg.txt +++ b/test/yarp/snapshots/seattlerb/masgn_arg_splat_arg.txt @@ -5,10 +5,10 @@ ProgramNode(0...12)( [LocalVariableTargetNode(0...1)(:a, 0), SplatNode(3...5)((3...4), LocalVariableTargetNode(4...5)(:b, 0)), LocalVariableTargetNode(7...8)(:c, 0)], - (9...10), - CallNode(11...12)(nil, nil, (11...12), nil, nil, nil, nil, 2, "d"), nil, - 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 cf85e7d1ed0540..d9a2744466fb45 100644 --- a/test/yarp/snapshots/seattlerb/masgn_colon2.txt +++ b/test/yarp/snapshots/seattlerb/masgn_colon2.txt @@ -8,14 +8,14 @@ ProgramNode(0...14)( 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..355f40f1cfb8fd 100644 --- a/test/yarp/snapshots/seattlerb/masgn_colon3.txt +++ b/test/yarp/snapshots/seattlerb/masgn_colon3.txt @@ -12,14 +12,14 @@ ProgramNode(0...15)( 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..4563136c2f2bc8 100644 --- a/test/yarp/snapshots/seattlerb/masgn_command_call.txt +++ b/test/yarp/snapshots/seattlerb/masgn_command_call.txt @@ -3,6 +3,8 @@ ProgramNode(0...10)( StatementsNode(0...10)( [MultiWriteNode(0...10)( [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 +16,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..107be851e3a907 100644 --- a/test/yarp/snapshots/seattlerb/masgn_double_paren.txt +++ b/test/yarp/snapshots/seattlerb/masgn_double_paren.txt @@ -1,19 +1,17 @@ -ProgramNode(0...9)( +ProgramNode(1...9)( [:a, :b], - StatementsNode(0...9)( - [MultiWriteNode(0...9)( - [MultiWriteNode(1...6)( + StatementsNode(1...9)( + [MultiWriteNode(1...9)( + [MultiTargetNode(1...6)( [LocalVariableTargetNode(2...3)(:a, 0), LocalVariableTargetNode(4...5)(:b, 0)], - nil, - nil, (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..4730ed961825b7 100644 --- a/test/yarp/snapshots/seattlerb/masgn_lhs_splat.txt +++ b/test/yarp/snapshots/seattlerb/masgn_lhs_splat.txt @@ -3,14 +3,14 @@ ProgramNode(0...12)( StatementsNode(0...12)( [MultiWriteNode(0...12)( [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..32b4fc2989b576 100644 --- a/test/yarp/snapshots/seattlerb/masgn_paren.txt +++ b/test/yarp/snapshots/seattlerb/masgn_paren.txt @@ -4,6 +4,8 @@ ProgramNode(0...12)( [MultiWriteNode(0...12)( [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 +17,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..e2729a861dc8f1 100644 --- a/test/yarp/snapshots/seattlerb/masgn_splat_arg.txt +++ b/test/yarp/snapshots/seattlerb/masgn_splat_arg.txt @@ -2,18 +2,16 @@ ProgramNode(0...9)( [:a, :b], StatementsNode(0...9)( [MultiWriteNode(0...9)( - [MultiWriteNode(0...2)( + [MultiTargetNode(0...2)( [SplatNode(0...2)((0...1), LocalVariableTargetNode(1...2)(:a, 0))], nil, - nil, - nil, nil ), LocalVariableTargetNode(4...5)(:b, 0)], - (6...7), - CallNode(8...9)(nil, nil, (8...9), nil, nil, nil, nil, 2, "c"), nil, - 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 9046d08d2bb091..bd6a51261480a3 100644 --- a/test/yarp/snapshots/seattlerb/masgn_splat_arg_arg.txt +++ b/test/yarp/snapshots/seattlerb/masgn_splat_arg_arg.txt @@ -2,19 +2,17 @@ ProgramNode(0...12)( [:a, :b, :c], StatementsNode(0...12)( [MultiWriteNode(0...12)( - [MultiWriteNode(0...2)( + [MultiTargetNode(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)], - (9...10), - CallNode(11...12)(nil, nil, (11...12), nil, nil, nil, nil, 2, "d"), nil, - 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 8b7cb8e266e96e..015e5edcc9cbcd 100644 --- a/test/yarp/snapshots/seattlerb/masgn_star.txt +++ b/test/yarp/snapshots/seattlerb/masgn_star.txt @@ -3,10 +3,10 @@ ProgramNode(0...5)( StatementsNode(0...5)( [MultiWriteNode(0...5)( [SplatNode(0...1)((0...1), nil)], - (2...3), - IntegerNode(4...5)(), 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 64d21d637316be..f6d0136d99ffee 100644 --- a/test/yarp/snapshots/seattlerb/masgn_var_star_var.txt +++ b/test/yarp/snapshots/seattlerb/masgn_var_star_var.txt @@ -5,10 +5,10 @@ ProgramNode(0...11)( [LocalVariableTargetNode(0...1)(:a, 0), SplatNode(3...4)((3...4), nil), LocalVariableTargetNode(6...7)(:b, 0)], - (8...9), - CallNode(10...11)(nil, nil, (10...11), nil, nil, nil, nil, 2, "c"), nil, - 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 ba484f89b0374a..59e954706b19ea 100644 --- a/test/yarp/snapshots/seattlerb/mlhs_back_anonsplat.txt +++ b/test/yarp/snapshots/seattlerb/mlhs_back_anonsplat.txt @@ -6,10 +6,10 @@ ProgramNode(0...14)( LocalVariableTargetNode(3...4)(:b, 0), LocalVariableTargetNode(6...7)(:c, 0), SplatNode(9...10)((9...10), nil)], - (11...12), - CallNode(13...14)(nil, nil, (13...14), nil, nil, nil, nil, 2, "f"), 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 9578258257e340..8014663bd34ffa 100644 --- a/test/yarp/snapshots/seattlerb/mlhs_back_splat.txt +++ b/test/yarp/snapshots/seattlerb/mlhs_back_splat.txt @@ -6,10 +6,10 @@ ProgramNode(0...15)( LocalVariableTargetNode(3...4)(:b, 0), LocalVariableTargetNode(6...7)(:c, 0), SplatNode(9...11)((9...10), LocalVariableTargetNode(10...11)(:s, 0))], - (12...13), - CallNode(14...15)(nil, nil, (14...15), nil, nil, nil, nil, 2, "f"), nil, - 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 8ed6e38ebdac89..74a63d328bfe58 100644 --- a/test/yarp/snapshots/seattlerb/mlhs_front_anonsplat.txt +++ b/test/yarp/snapshots/seattlerb/mlhs_front_anonsplat.txt @@ -2,20 +2,14 @@ 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 - ), + [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)], - (11...12), - CallNode(13...14)(nil, nil, (13...14), nil, nil, nil, nil, 2, "f"), 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_front_splat.txt b/test/yarp/snapshots/seattlerb/mlhs_front_splat.txt index 07866df9edc139..f3110882cc1133 100644 --- a/test/yarp/snapshots/seattlerb/mlhs_front_splat.txt +++ b/test/yarp/snapshots/seattlerb/mlhs_front_splat.txt @@ -2,20 +2,18 @@ ProgramNode(0...15)( [:s, :x, :y, :z], StatementsNode(0...15)( [MultiWriteNode(0...15)( - [MultiWriteNode(0...2)( + [MultiTargetNode(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)], - (12...13), - CallNode(14...15)(nil, nil, (14...15), nil, nil, nil, nil, 2, "f"), nil, - 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 ce114d05287340..c0e3acc145169f 100644 --- a/test/yarp/snapshots/seattlerb/mlhs_mid_anonsplat.txt +++ b/test/yarp/snapshots/seattlerb/mlhs_mid_anonsplat.txt @@ -9,10 +9,10 @@ ProgramNode(0...23)( LocalVariableTargetNode(12...13)(:x, 0), LocalVariableTargetNode(15...16)(:y, 0), LocalVariableTargetNode(18...19)(:z, 0)], - (20...21), - CallNode(22...23)(nil, nil, (22...23), nil, nil, nil, nil, 2, "f"), nil, - 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 672de03089e4be..46d81adf646bb7 100644 --- a/test/yarp/snapshots/seattlerb/mlhs_mid_splat.txt +++ b/test/yarp/snapshots/seattlerb/mlhs_mid_splat.txt @@ -9,10 +9,10 @@ ProgramNode(0...24)( LocalVariableTargetNode(13...14)(:x, 0), LocalVariableTargetNode(16...17)(:y, 0), LocalVariableTargetNode(19...20)(:z, 0)], - (21...22), - CallNode(23...24)(nil, nil, (23...24), nil, nil, nil, nil, 2, "f"), nil, - 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 3e1cd57291d87b..427c56dfea2b4a 100644 --- a/test/yarp/snapshots/seattlerb/mlhs_rescue.txt +++ b/test/yarp/snapshots/seattlerb/mlhs_rescue.txt @@ -4,14 +4,14 @@ ProgramNode(0...18)( [MultiWriteNode(0...18)( [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/module_comments.txt b/test/yarp/snapshots/seattlerb/module_comments.txt index 152697f4022a1d..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, @@ -21,7 +22,6 @@ ProgramNode(24...77)( )] ), (74...77), - :X, :X )] ) 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_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/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/parse_line_to_ary.txt b/test/yarp/snapshots/seattlerb/parse_line_to_ary.txt index 7f0a75913c6395..e8736976c78a9c 100644 --- a/test/yarp/snapshots/seattlerb/parse_line_to_ary.txt +++ b/test/yarp/snapshots/seattlerb/parse_line_to_ary.txt @@ -4,10 +4,10 @@ ProgramNode(0...10)( [MultiWriteNode(0...8)( [LocalVariableTargetNode(0...1)(:a, 0), LocalVariableTargetNode(3...4)(:b, 0)], - (5...6), - CallNode(7...8)(nil, nil, (7...8), nil, nil, nil, nil, 2, "c"), nil, - nil + nil, + (5...6), + 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/seattlerb/required_kwarg_no_value.txt b/test/yarp/snapshots/seattlerb/required_kwarg_no_value.txt index 95cf0e279a730e..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)( @@ -9,8 +10,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_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/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/assignment.txt b/test/yarp/snapshots/unparser/corpus/literal/assignment.txt index 38c06a29bc928c..3f82c3a8e40bac 100644 --- a/test/yarp/snapshots/unparser/corpus/literal/assignment.txt +++ b/test/yarp/snapshots/unparser/corpus/literal/assignment.txt @@ -10,88 +10,86 @@ ProgramNode(0...704)( MultiWriteNode(7...24)( [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)( + [MultiTargetNode(26...30)( [LocalVariableTargetNode(27...28)(:a, 0), SplatNode(28...29)((28...29), nil)], - nil, - nil, (26...27), (29...30) ), LocalVariableTargetNode(32...33)(:b, 0)], - (35...36), - IntegerNode(37...38)(), (25...26), - (33...34) + (33...34), + (35...36), + IntegerNode(37...38)() ), MultiWriteNode(39...48)( [SplatNode(40...42)( (40...41), LocalVariableTargetNode(41...42)(:a, 0) )], - (44...45), - ArrayNode(46...48)([], (46...47), (47...48)), (39...40), - (42...43) + (42...43), + (44...45), + ArrayNode(46...48)([], (46...47), (47...48)) ), MultiWriteNode(49...64)( [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)], + (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)], + (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)( + MultiTargetNode(107...113)( [LocalVariableTargetNode(108...109)(:b, 0), LocalVariableTargetNode(111...112)(:c, 0)], - nil, - nil, (107...108), (112...113) )], + (103...104), + (113...114), (115...116), ArrayNode(117...128)( [IntegerNode(118...119)(), @@ -102,21 +100,19 @@ 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)], + (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), @@ -124,42 +120,42 @@ ProgramNode(0...704)( (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)], + (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)], - (187...188), - LocalVariableReadNode(189...192)(:foo, 0), (180...181), - (185...186) + (185...186), + (187...188), + LocalVariableReadNode(189...192)(:foo, 0) ), MultiWriteNode(193...203)( [LocalVariableTargetNode(194...195)(:a, 0), SplatNode(195...196)((195...196), nil)], - (198...199), - LocalVariableReadNode(200...203)(:foo, 0), (193...194), - (196...197) + (196...197), + (198...199), + LocalVariableReadNode(200...203)(:foo, 0) ), MultiWriteNode(204...227)( [CallNode(205...210)( @@ -184,14 +180,14 @@ ProgramNode(0...704)( 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)( @@ -221,14 +217,14 @@ ProgramNode(0...704)( 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)( @@ -253,14 +249,14 @@ ProgramNode(0...704)( 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)( @@ -277,10 +273,10 @@ ProgramNode(0...704)( "foo=" ) )], - (284...285), - IntegerNode(286...287)(), (275...276), - (282...283) + (282...283), + (284...285), + IntegerNode(286...287)() ), ConstantPathWriteNode(288...301)( ConstantPathNode(288...293)( @@ -335,10 +331,10 @@ ProgramNode(0...704)( [MultiWriteNode(356...366)( [LocalVariableTargetNode(357...358)(:b, 0), LocalVariableTargetNode(360...361)(:c, 0)], - (363...364), - IntegerNode(365...366)(), (356...357), - (361...362) + (361...362), + (363...364), + IntegerNode(365...366)() )] ), (355...356), 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/class.txt b/test/yarp/snapshots/unparser/corpus/literal/class.txt index cb49848ae35d70..5d0ca9da7bb9c5 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)( @@ -140,6 +134,7 @@ ProgramNode(0...213)( "include" ), DefNode(172...194)( + :foo, (176...179), nil, nil, @@ -156,7 +151,6 @@ ProgramNode(0...213)( )] ), (195...198), - :A, :A ), ClassNode(200...213)( @@ -171,7 +165,6 @@ ProgramNode(0...213)( nil, nil, (210...213), - :A, :A )] ) diff --git a/test/yarp/snapshots/unparser/corpus/literal/def.txt b/test/yarp/snapshots/unparser/corpus/literal/def.txt index f458483791f2a4..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)( @@ -179,8 +182,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 ), @@ -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)( @@ -570,6 +585,7 @@ ProgramNode(0...913)( [], nil, [KeywordParameterNode(459...465)( + :bar, (459...463), IntegerNode(464...465)() )], @@ -586,6 +602,7 @@ ProgramNode(0...913)( (467...470) ), DefNode(472...493)( + :foo, (476...479), nil, ParametersNode(480...488)( @@ -594,6 +611,7 @@ ProgramNode(0...913)( [], nil, [KeywordParameterNode(480...488)( + :bar, (480...484), CallNode(485...488)( nil, @@ -620,6 +638,7 @@ ProgramNode(0...913)( (490...493) ), DefNode(495...518)( + :foo, (499...502), nil, ParametersNode(503...513)( @@ -628,6 +647,7 @@ ProgramNode(0...913)( [], nil, [KeywordParameterNode(503...513)( + :bar, (503...507), CallNode(508...513)( nil, @@ -654,13 +674,14 @@ ProgramNode(0...913)( (515...518) ), DefNode(520...540)( + :foo, (524...527), nil, ParametersNode(528...529)( [], [], [], - RestParameterNode(528...529)((528...529), nil), + RestParameterNode(528...529)(nil, nil, (528...529)), [], nil, nil @@ -687,13 +708,14 @@ ProgramNode(0...913)( (537...540) ), DefNode(542...565)( + :foo, (546...549), nil, ParametersNode(550...554)( [], [], [], - RestParameterNode(550...554)((550...551), (551...554)), + RestParameterNode(550...554)(:bar, (551...554), (550...551)), [], nil, nil @@ -708,13 +730,14 @@ ProgramNode(0...913)( (562...565) ), DefNode(567...595)( + :foo, (571...574), nil, ParametersNode(575...584)( [RequiredParameterNode(575...578)(:bar)], [], [], - RestParameterNode(580...584)((580...581), (581...584)), + RestParameterNode(580...584)(:baz, (581...584), (580...581)), [], nil, nil @@ -729,6 +752,7 @@ ProgramNode(0...913)( (592...595) ), DefNode(597...632)( + :foo, (601...604), nil, ParametersNode(605...621)( @@ -740,7 +764,7 @@ ProgramNode(0...913)( TrueNode(611...615)() )], [], - RestParameterNode(617...621)((617...618), (618...621)), + RestParameterNode(617...621)(:bor, (618...621), (617...618)), [], nil, nil @@ -767,6 +791,7 @@ ProgramNode(0...913)( (629...632) ), DefNode(634...677)( + :foo, (638...641), nil, ParametersNode(642...666)( @@ -778,7 +803,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)) @@ -805,6 +830,7 @@ ProgramNode(0...913)( (674...677) ), DefNode(679...719)( + :foo, (683...686), nil, ParametersNode(687...708)( @@ -816,7 +842,7 @@ ProgramNode(0...913)( TrueNode(698...702)() )], [], - RestParameterNode(704...708)((704...705), (705...708)), + RestParameterNode(704...708)(:bor, (705...708), (704...705)), [], nil, nil @@ -831,6 +857,7 @@ ProgramNode(0...913)( (716...719) ), DefNode(721...746)( + :foo, (725...728), nil, ParametersNode(729...735)( @@ -864,6 +891,7 @@ ProgramNode(0...913)( (743...746) ), DefNode(748...778)( + :foo, (752...755), nil, ParametersNode(756...767)( @@ -885,6 +913,7 @@ ProgramNode(0...913)( (775...778) ), DefNode(780...803)( + :foo, (784...787), nil, nil, @@ -921,6 +950,7 @@ ProgramNode(0...913)( (800...803) ), DefNode(805...821)( + :f, (809...810), nil, ParametersNode(811...816)( @@ -950,6 +980,7 @@ ProgramNode(0...913)( (818...821) ), DefNode(823...854)( + :foo, (827...830), nil, ParametersNode(831...849)( @@ -957,8 +988,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), @@ -980,6 +1012,7 @@ ProgramNode(0...913)( (851...854) ), DefNode(856...896)( + :f, (860...861), nil, nil, @@ -1001,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/defined.txt b/test/yarp/snapshots/unparser/corpus/literal/defined.txt index 8e77e8e5df9a68..58816ee742a8fd 100644 --- a/test/yarp/snapshots/unparser/corpus/literal/defined.txt +++ b/test/yarp/snapshots/unparser/corpus/literal/defined.txt @@ -20,14 +20,14 @@ ProgramNode(0...56)( [MultiWriteNode(39...54)( [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/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/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/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..355b57ac531e21 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)( @@ -69,6 +66,7 @@ ProgramNode(0...106)( "include" ), DefNode(80...102)( + :foo, (84...87), nil, nil, @@ -85,7 +83,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..858101f5a3a2c8 100644 --- a/test/yarp/snapshots/unparser/corpus/literal/send.txt +++ b/test/yarp/snapshots/unparser/corpus/literal/send.txt @@ -14,6 +14,8 @@ ProgramNode(0...999)( [MultiWriteNode(20...30)( [LocalVariableTargetNode(21...22)(:a, 0), LocalVariableTargetNode(24...25)(:_, 0)], + (20...21), + (25...26), (27...28), CallNode(29...30)( nil, @@ -25,9 +27,7 @@ ProgramNode(0...999)( nil, 2, "b" - ), - (20...21), - (25...26) + ) )] ), (19...20), @@ -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), @@ -132,6 +128,7 @@ ProgramNode(0...999)( ParenthesesNode(133...152)( StatementsNode(134...151)( [DefNode(134...145)( + :foo, (138...141), nil, nil, @@ -238,6 +235,7 @@ ProgramNode(0...999)( ), CallNode(218...238)( DefNode(218...234)( + :foo, (227...230), SelfNode(222...226)(), nil, @@ -261,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 31397bf46874e3..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)( @@ -10,7 +11,7 @@ ProgramNode(0...90)( [], nil, [], - KeywordRestParameterNode(18...20)((18...20), nil), + KeywordRestParameterNode(18...20)(nil, nil, (18...20)), nil ), StatementsNode(24...41)( @@ -40,13 +41,14 @@ ProgramNode(0...90)( (42...45) ), DefNode(47...90)( + :foo, (51...54), nil, ParametersNode(55...66)( [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/unparser/corpus/literal/while.txt b/test/yarp/snapshots/unparser/corpus/literal/while.txt index 4d924f0d3df9fa..f6dc399041a381 100644 --- a/test/yarp/snapshots/unparser/corpus/literal/while.txt +++ b/test/yarp/snapshots/unparser/corpus/literal/while.txt @@ -64,10 +64,10 @@ ProgramNode(0...620)( )] ), (65...68), - :A, :A ), DefNode(70...110)( + :foo, (74...77), nil, nil, @@ -160,7 +160,6 @@ ProgramNode(0...620)( )] ), (143...146), - :A, :A ), ModuleNode(148...182)( @@ -195,7 +194,6 @@ ProgramNode(0...620)( )] ), (179...182), - :A, :A ), ModuleNode(184...228)( @@ -240,7 +238,6 @@ ProgramNode(0...620)( )] ), (225...228), - :A, :A ), ModuleNode(230...299)( @@ -316,7 +313,6 @@ ProgramNode(0...620)( )] ), (296...299), - :A, :A ), ModuleNode(301...370)( @@ -382,7 +378,6 @@ ProgramNode(0...620)( )] ), (367...370), - :A, :A ), LocalVariableWriteNode(371...402)( 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/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/variables.txt b/test/yarp/snapshots/variables.txt index 4d50fa0db398d2..29f5e44817e5b9 100644 --- a/test/yarp/snapshots/variables.txt +++ b/test/yarp/snapshots/variables.txt @@ -11,10 +11,10 @@ ProgramNode(0...293)( MultiWriteNode(18...34)( [ClassVariableTargetNode(18...23)(:@@foo), ClassVariableTargetNode(25...30)(:@@bar)], - (31...32), - IntegerNode(33...34)(), nil, - nil + nil, + (31...32), + IntegerNode(33...34)() ), ClassVariableWriteNode(36...48)( :@@foo, @@ -51,10 +51,10 @@ ProgramNode(0...293)( MultiWriteNode(94...108)( [GlobalVariableTargetNode(94...98)(:$foo), GlobalVariableTargetNode(100...104)(:$bar)], - (105...106), - IntegerNode(107...108)(), nil, - nil + nil, + (105...106), + IntegerNode(107...108)() ), GlobalVariableWriteNode(110...121)( :$foo, @@ -69,10 +69,10 @@ ProgramNode(0...293)( MultiWriteNode(123...137)( [InstanceVariableTargetNode(123...127)(:@foo), InstanceVariableTargetNode(129...133)(:@bar)], - (134...135), - IntegerNode(136...137)(), nil, - nil + nil, + (134...135), + IntegerNode(136...137)() ), InstanceVariableWriteNode(139...150)( :@foo, @@ -116,26 +116,26 @@ ProgramNode(0...293)( MultiWriteNode(185...198)( [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)], + 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), @@ -143,25 +143,25 @@ ProgramNode(0...293)( (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)( + MultiTargetNode(236...246)( [LocalVariableTargetNode(237...240)(:bar, 0), LocalVariableTargetNode(242...245)(:baz, 0)], - nil, - nil, (236...237), (245...246) )], + nil, + nil, (247...248), ArrayNode(249...258)( [IntegerNode(249...250)(), @@ -172,9 +172,7 @@ ProgramNode(0...293)( )], nil, nil - ), - nil, - nil + ) ), LocalVariableWriteNode(260...270)( :foo, diff --git a/test/yarp/snapshots/while.txt b/test/yarp/snapshots/while.txt index 843db1e147fb2b..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)( @@ -139,7 +140,6 @@ ProgramNode(0...314)( )] ), (195...198), - :Foo, :Foo ), StatementsNode(200...205)([BreakNode(200...205)(nil, (200...205))]), diff --git a/test/yarp/snapshots/whitequark/and_or_masgn.txt b/test/yarp/snapshots/whitequark/and_or_masgn.txt index bc64788ca43665..e34c3e19ee09ee 100644 --- a/test/yarp/snapshots/whitequark/and_or_masgn.txt +++ b/test/yarp/snapshots/whitequark/and_or_masgn.txt @@ -8,6 +8,8 @@ ProgramNode(0...40)( [MultiWriteNode(8...18)( [LocalVariableTargetNode(8...9)(:a, 0), LocalVariableTargetNode(11...12)(:b, 0)], + nil, + nil, (13...14), CallNode(15...18)( nil, @@ -19,9 +21,7 @@ ProgramNode(0...40)( nil, 2, "bar" - ), - nil, - nil + ) )] ), (7...8), @@ -36,6 +36,8 @@ ProgramNode(0...40)( [MultiWriteNode(29...39)( [LocalVariableTargetNode(29...30)(:a, 0), LocalVariableTargetNode(32...33)(:b, 0)], + nil, + nil, (34...35), CallNode(36...39)( nil, @@ -47,9 +49,7 @@ ProgramNode(0...40)( nil, 2, "bar" - ), - nil, - nil + ) )] ), (28...29), 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 faa2ee445925f6..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)( @@ -306,6 +318,7 @@ ProgramNode(0...690)( [], nil, [KeywordParameterNode(236...242)( + :foo, (236...240), IntegerNode(241...242)() )], @@ -322,6 +335,7 @@ ProgramNode(0...690)( (249...252) ), DefNode(254...292)( + :f, (258...259), nil, ParametersNode(261...286)( @@ -330,14 +344,16 @@ ProgramNode(0...690)( [], nil, [KeywordParameterNode(261...267)( + :foo, (261...265), IntegerNode(266...267)() ), KeywordParameterNode(269...275)( + :bar, (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, @@ -350,6 +366,7 @@ ProgramNode(0...690)( (289...292) ), DefNode(294...314)( + :f, (298...299), nil, ParametersNode(300...309)( @@ -358,7 +375,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, @@ -371,15 +388,16 @@ ProgramNode(0...690)( (311...314) ), DefNode(316...332)( + :f, (320...321), nil, ParametersNode(322...327)( [], [], [], - RestParameterNode(322...323)((322...323), nil), + RestParameterNode(322...323)(nil, nil, (322...323)), [], - KeywordRestParameterNode(325...327)((325...327), nil), + KeywordRestParameterNode(325...327)(nil, nil, (325...327)), nil ), nil, @@ -392,13 +410,14 @@ ProgramNode(0...690)( (329...332) ), DefNode(334...351)( + :f, (338...339), nil, ParametersNode(340...346)( [], [], [], - RestParameterNode(340...342)((340...341), (341...342)), + RestParameterNode(340...342)(:r, (341...342), (340...341)), [], nil, BlockParameterNode(344...346)(:b, (345...346), (344...345)) @@ -413,13 +432,14 @@ ProgramNode(0...690)( (348...351) ), DefNode(353...373)( + :f, (357...358), nil, ParametersNode(359...368)( [], [], [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)) @@ -434,6 +454,7 @@ ProgramNode(0...690)( (370...373) ), DefNode(375...386)( + :f, (379...380), nil, nil, @@ -447,6 +468,7 @@ ProgramNode(0...690)( (383...386) ), DefNode(388...404)( + :f, (392...393), nil, ParametersNode(394...399)( @@ -468,13 +490,14 @@ ProgramNode(0...690)( (401...404) ), DefNode(406...426)( + :f, (410...411), nil, ParametersNode(412...421)( [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)) @@ -489,13 +512,14 @@ ProgramNode(0...690)( (423...426) ), DefNode(428...451)( + :f, (432...433), nil, ParametersNode(434...446)( [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)) @@ -510,6 +534,7 @@ ProgramNode(0...690)( (448...451) ), DefNode(453...474)( + :f, (457...458), nil, ParametersNode(459...469)( @@ -536,6 +561,7 @@ ProgramNode(0...690)( (471...474) ), DefNode(476...501)( + :f, (480...481), nil, ParametersNode(482...496)( @@ -547,7 +573,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)) @@ -562,6 +588,7 @@ ProgramNode(0...690)( (498...501) ), DefNode(503...531)( + :f, (507...508), nil, ParametersNode(509...526)( @@ -573,7 +600,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)) @@ -588,6 +615,7 @@ ProgramNode(0...690)( (528...531) ), DefNode(533...557)( + :f, (537...538), nil, ParametersNode(539...552)( @@ -614,6 +642,7 @@ ProgramNode(0...690)( (554...557) ), DefNode(559...575)( + :f, (563...564), nil, ParametersNode(565...569)( @@ -621,7 +650,7 @@ ProgramNode(0...690)( [], [], nil, - [KeywordParameterNode(565...569)((565...569), nil)], + [KeywordParameterNode(565...569)(:foo, (565...569), nil)], nil, nil ), @@ -635,6 +664,7 @@ ProgramNode(0...690)( (572...575) ), DefNode(577...596)( + :f, (581...582), nil, ParametersNode(583...590)( @@ -643,6 +673,7 @@ ProgramNode(0...690)( [], nil, [KeywordParameterNode(583...590)( + :foo, (583...587), IntegerNode(588...590)() )], @@ -659,6 +690,7 @@ ProgramNode(0...690)( (593...596) ), DefNode(598...616)( + :f, (602...603), nil, ParametersNode(604...611)( @@ -685,6 +717,7 @@ ProgramNode(0...690)( (613...616) ), DefNode(618...640)( + :f, (622...623), nil, ParametersNode(624...635)( @@ -696,7 +729,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)) @@ -711,6 +744,7 @@ ProgramNode(0...690)( (637...640) ), DefNode(642...667)( + :f, (646...647), nil, ParametersNode(648...662)( @@ -722,7 +756,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)) @@ -737,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/blockargs.txt b/test/yarp/snapshots/whitequark/blockargs.txt index d716003643385c..dd0b942a291c63 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)) ), [], @@ -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 @@ -807,6 +807,7 @@ ProgramNode(0...550)( [], nil, [KeywordParameterNode(403...409)( + :foo, (403...407), IntegerNode(408...409)() )], @@ -840,14 +841,20 @@ ProgramNode(0...550)( [], nil, [KeywordParameterNode(422...428)( + :foo, (422...426), IntegerNode(427...428)() ), KeywordParameterNode(430...436)( + :bar, (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)) ), [], @@ -876,7 +883,7 @@ ProgramNode(0...550)( [], [], nil, - [KeywordParameterNode(456...460)((456...460), nil)], + [KeywordParameterNode(456...460)(:foo, (456...460), nil)], nil, nil ), @@ -945,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)) @@ -980,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/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/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/cond_begin_masgn.txt b/test/yarp/snapshots/whitequark/cond_begin_masgn.txt index 8114bd1cb4491d..9a5e51bd10a57c 100644 --- a/test/yarp/snapshots/whitequark/cond_begin_masgn.txt +++ b/test/yarp/snapshots/whitequark/cond_begin_masgn.txt @@ -9,6 +9,8 @@ ProgramNode(0...25)( MultiWriteNode(9...19)( [LocalVariableTargetNode(9...10)(:a, 0), LocalVariableTargetNode(12...13)(:b, 0)], + nil, + nil, (14...15), CallNode(16...19)( nil, @@ -20,9 +22,7 @@ ProgramNode(0...25)( nil, 2, "foo" - ), - nil, - nil + ) )] ), (3...4), 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/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/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/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/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 a751f923c117be..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)( @@ -10,7 +11,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_argument_with_restarg.txt b/test/yarp/snapshots/whitequark/forwarded_argument_with_restarg.txt index ff0602c3982005..842def39c5cca8 100644 --- a/test/yarp/snapshots/whitequark/forwarded_argument_with_restarg.txt +++ b/test/yarp/snapshots/whitequark/forwarded_argument_with_restarg.txt @@ -2,13 +2,14 @@ ProgramNode(0...43)( [], StatementsNode(0...43)( [DefNode(0...43)( + :foo, (4...7), nil, ParametersNode(8...19)( [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_kwrestarg.txt b/test/yarp/snapshots/whitequark/forwarded_kwrestarg.txt index 0fcac6a2985d97..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)( @@ -10,7 +11,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..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)( @@ -10,7 +11,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/forwarded_restarg.txt b/test/yarp/snapshots/whitequark/forwarded_restarg.txt index d45b60fc0a348b..40384fce94e885 100644 --- a/test/yarp/snapshots/whitequark/forwarded_restarg.txt +++ b/test/yarp/snapshots/whitequark/forwarded_restarg.txt @@ -2,13 +2,14 @@ ProgramNode(0...23)( [], StatementsNode(0...23)( [DefNode(0...23)( + :foo, (4...7), nil, ParametersNode(8...9)( [], [], [], - RestParameterNode(8...9)((8...9), nil), + RestParameterNode(8...9)(nil, nil, (8...9)), [], nil, nil diff --git a/test/yarp/snapshots/whitequark/if_masgn__24.txt b/test/yarp/snapshots/whitequark/if_masgn__24.txt index 24c9ef784ddc58..1bdfd7bff69715 100644 --- a/test/yarp/snapshots/whitequark/if_masgn__24.txt +++ b/test/yarp/snapshots/whitequark/if_masgn__24.txt @@ -8,6 +8,8 @@ ProgramNode(0...20)( [MultiWriteNode(4...14)( [LocalVariableTargetNode(4...5)(:a, 0), LocalVariableTargetNode(7...8)(:b, 0)], + nil, + nil, (9...10), CallNode(11...14)( nil, @@ -19,9 +21,7 @@ ProgramNode(0...20)( nil, 2, "foo" - ), - nil, - nil + ) )] ), (3...4), 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/kwarg.txt b/test/yarp/snapshots/whitequark/kwarg.txt index d096caece0c61c..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)( @@ -9,7 +10,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/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 9514567387d91f..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)( @@ -9,7 +10,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..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)( @@ -9,8 +10,8 @@ ProgramNode(0...28)( [], [], nil, - [KeywordParameterNode(6...12)((6...8), NilNode(9...12)())], - KeywordRestParameterNode(14...16)((14...16), nil), + [KeywordParameterNode(6...12)(:a, (6...8), NilNode(9...12)())], + 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..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)( @@ -10,7 +11,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..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)( @@ -10,7 +11,7 @@ ProgramNode(0...14)( [], nil, [], - KeywordRestParameterNode(6...8)((6...8), nil), + KeywordRestParameterNode(6...8)(nil, nil, (6...8)), nil ), nil, diff --git a/test/yarp/snapshots/whitequark/masgn.txt b/test/yarp/snapshots/whitequark/masgn.txt index 69667e1a38b5a9..419d68ee7b4c69 100644 --- a/test/yarp/snapshots/whitequark/masgn.txt +++ b/test/yarp/snapshots/whitequark/masgn.txt @@ -4,39 +4,39 @@ ProgramNode(0...56)( [MultiWriteNode(0...17)( [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)], + 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)], + 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..5ad893c96dd0cb 100644 --- a/test/yarp/snapshots/whitequark/masgn_attr.txt +++ b/test/yarp/snapshots/whitequark/masgn_attr.txt @@ -14,10 +14,10 @@ ProgramNode(0...63)( "A=" ), LocalVariableTargetNode(8...11)(:foo, 0)], - (12...13), - LocalVariableReadNode(14...17)(:foo, 0), nil, - nil + nil, + (12...13), + LocalVariableReadNode(14...17)(:foo, 0) ), MultiWriteNode(19...43)( [CallNode(19...25)( @@ -44,10 +44,10 @@ ProgramNode(0...63)( 0, "[]=" )], - (38...39), - LocalVariableReadNode(40...43)(:foo, 0), nil, - nil + nil, + (38...39), + LocalVariableReadNode(40...43)(:foo, 0) ), MultiWriteNode(45...63)( [CallNode(45...52)( @@ -62,10 +62,10 @@ ProgramNode(0...63)( "a=" ), LocalVariableTargetNode(54...57)(:foo, 0)], - (58...59), - LocalVariableReadNode(60...63)(:foo, 0), nil, - 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 14d81d79bcf2b3..5b9b9b03cec9d9 100644 --- a/test/yarp/snapshots/whitequark/masgn_cmd.txt +++ b/test/yarp/snapshots/whitequark/masgn_cmd.txt @@ -4,6 +4,8 @@ ProgramNode(0...16)( [MultiWriteNode(0...16)( [LocalVariableTargetNode(0...3)(:foo, 0), LocalVariableTargetNode(5...8)(:bar, 0)], + nil, + nil, (9...10), CallNode(11...16)( nil, @@ -15,9 +17,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..85155526189cf6 100644 --- a/test/yarp/snapshots/whitequark/masgn_const.txt +++ b/test/yarp/snapshots/whitequark/masgn_const.txt @@ -8,10 +8,10 @@ ProgramNode(0...34)( (0...2) ), LocalVariableTargetNode(5...8)(:foo, 0)], - (9...10), - LocalVariableReadNode(11...14)(:foo, 0), nil, - nil + nil, + (9...10), + LocalVariableReadNode(11...14)(:foo, 0) ), MultiWriteNode(16...34)( [ConstantPathTargetNode(16...23)( @@ -20,10 +20,10 @@ ProgramNode(0...34)( (20...22) ), LocalVariableTargetNode(25...28)(:foo, 0)], - (29...30), - LocalVariableReadNode(31...34)(:foo, 0), nil, - 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 b1601b8aa7436a..00f4eb1ef40745 100644 --- a/test/yarp/snapshots/whitequark/masgn_nested.txt +++ b/test/yarp/snapshots/whitequark/masgn_nested.txt @@ -1,34 +1,30 @@ -ProgramNode(0...30)( +ProgramNode(1...30)( [:b, :a, :c], - StatementsNode(0...30)( - [MultiWriteNode(0...13)( - [MultiWriteNode(1...6)( + StatementsNode(1...30)( + [MultiWriteNode(1...13)( + [MultiTargetNode(1...6)( [LocalVariableTargetNode(2...3)(:b, 0), SplatNode(3...4)((3...4), nil)], - nil, - 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)( + MultiTargetNode(18...24)( [LocalVariableTargetNode(19...20)(:b, 0), LocalVariableTargetNode(22...23)(:c, 0)], - nil, - nil, (18...19), (23...24) )], - (25...26), - CallNode(27...30)(nil, nil, (27...30), nil, nil, nil, nil, 2, "foo"), nil, - 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 d21760a65b3921..c6cbe9ee70a3a0 100644 --- a/test/yarp/snapshots/whitequark/masgn_splat.txt +++ b/test/yarp/snapshots/whitequark/masgn_splat.txt @@ -3,56 +3,50 @@ ProgramNode(0...139)( StatementsNode(0...139)( [MultiWriteNode(0...7)( [SplatNode(0...1)((0...1), nil)], - (2...3), - CallNode(4...7)(nil, nil, (4...7), nil, nil, nil, nil, 2, "bar"), nil, - nil + nil, + (2...3), + 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 - ), + [MultiTargetNode(9...10)([SplatNode(9...10)((9...10), nil)], nil, nil), LocalVariableTargetNode(12...13)(:c, 0), LocalVariableTargetNode(15...16)(:d, 0)], - (17...18), - CallNode(19...22)(nil, nil, (19...22), nil, nil, nil, nil, 2, "bar"), nil, - nil + nil, + (17...18), + 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) )], - (27...28), - CallNode(29...32)(nil, nil, (29...32), nil, nil, nil, nil, 2, "bar"), nil, - nil + nil, + (27...28), + CallNode(29...32)(nil, nil, (29...32), nil, nil, nil, nil, 2, "bar") ), MultiWriteNode(34...45)( - [MultiWriteNode(34...36)( + [MultiTargetNode(34...36)( [SplatNode(34...36)( (34...35), LocalVariableTargetNode(35...36)(:b, 0) )], nil, - nil, - nil, nil ), LocalVariableTargetNode(38...39)(:c, 0)], - (40...41), - CallNode(42...45)(nil, nil, (42...45), nil, nil, nil, nil, 2, "bar"), nil, - nil + nil, + (40...41), + CallNode(42...45)(nil, nil, (42...45), nil, nil, nil, nil, 2, "bar") ), MultiWriteNode(47...65)( [InstanceVariableTargetNode(47...51)(:@foo), ClassVariableTargetNode(53...58)(:@@bar)], + nil, + nil, (59...60), ArrayNode(61...65)( [SplatNode(61...65)( @@ -71,26 +65,24 @@ ProgramNode(0...139)( )], nil, nil - ), - nil, - nil + ) ), MultiWriteNode(67...77)( [LocalVariableTargetNode(67...68)(:a, 0), SplatNode(70...71)((70...71), nil)], - (72...73), - CallNode(74...77)(nil, nil, (74...77), nil, nil, nil, nil, 2, "bar"), nil, - nil + nil, + (72...73), + 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)], - (87...88), - CallNode(89...92)(nil, nil, (89...92), nil, nil, nil, nil, 2, "bar"), nil, - nil + nil, + (87...88), + CallNode(89...92)(nil, nil, (89...92), nil, nil, nil, nil, 2, "bar") ), MultiWriteNode(94...105)( [LocalVariableTargetNode(94...95)(:a, 0), @@ -98,20 +90,10 @@ ProgramNode(0...139)( (97...98), LocalVariableTargetNode(98...99)(:b, 0) )], - (100...101), - CallNode(102...105)( - nil, - nil, - (102...105), - nil, - nil, - nil, - 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), @@ -120,24 +102,16 @@ ProgramNode(0...139)( LocalVariableTargetNode(111...112)(:b, 0) ), LocalVariableTargetNode(114...115)(:c, 0)], - (116...117), - CallNode(118...121)( - nil, - nil, - (118...121), - nil, - nil, - nil, - 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)], + nil, + nil, (128...129), ArrayNode(130...139)( [SplatNode(130...134)( @@ -167,9 +141,7 @@ ProgramNode(0...139)( )], nil, nil - ), - nil, - nil + ) )] ) ) 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/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/not_masgn__24.txt b/test/yarp/snapshots/whitequark/not_masgn__24.txt index 47895d8c462466..c20896826318b2 100644 --- a/test/yarp/snapshots/whitequark/not_masgn__24.txt +++ b/test/yarp/snapshots/whitequark/not_masgn__24.txt @@ -7,6 +7,8 @@ ProgramNode(0...13)( [MultiWriteNode(2...12)( [LocalVariableTargetNode(2...3)(:a, 0), LocalVariableTargetNode(5...6)(:b, 0)], + nil, + nil, (7...8), CallNode(9...12)( nil, @@ -18,9 +20,7 @@ ProgramNode(0...13)( nil, 2, "foo" - ), - nil, - nil + ) )] ), (1...2), diff --git a/test/yarp/snapshots/whitequark/numparam_outside_block.txt b/test/yarp/snapshots/whitequark/numparam_outside_block.txt index 61d138fa6d5a89..0dff33b0a99b56 100644 --- a/test/yarp/snapshots/whitequark/numparam_outside_block.txt +++ b/test/yarp/snapshots/whitequark/numparam_outside_block.txt @@ -22,10 +22,10 @@ ProgramNode(0...83)( [CallNode(36...38)(nil, nil, (36...38), nil, nil, nil, nil, 2, "_1")] ), (40...43), - :A, :A ), DefNode(45...64)( + :m, (54...55), SelfNode(49...53)(), nil, @@ -48,7 +48,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/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 b3b5b04a4a4baf..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, @@ -49,7 +51,6 @@ ProgramNode(0...132)( nil, nil, (72...75), - :C, :C )] ), @@ -65,6 +66,7 @@ ProgramNode(0...132)( (82...85) ), DefNode(87...132)( + :m, (91...92), nil, nil, @@ -81,7 +83,6 @@ ProgramNode(0...132)( ConstantReadNode(116...117)(:M), nil, (119...122), - :M, :M )] ), 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/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/test/yarp/snapshots/whitequark/rescue_mod_masgn.txt b/test/yarp/snapshots/whitequark/rescue_mod_masgn.txt index 13023afc175e47..82b1220cd7a4d8 100644 --- a/test/yarp/snapshots/whitequark/rescue_mod_masgn.txt +++ b/test/yarp/snapshots/whitequark/rescue_mod_masgn.txt @@ -4,6 +4,8 @@ ProgramNode(0...29)( [MultiWriteNode(0...29)( [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 +15,7 @@ ProgramNode(0...29)( (23...24), (28...29) ) - ), - nil, - nil + ) )] ) ) diff --git a/test/yarp/snapshots/whitequark/restarg_named.txt b/test/yarp/snapshots/whitequark/restarg_named.txt index ce26b2fc67a590..d3eed889c6f03e 100644 --- a/test/yarp/snapshots/whitequark/restarg_named.txt +++ b/test/yarp/snapshots/whitequark/restarg_named.txt @@ -2,13 +2,14 @@ ProgramNode(0...16)( [], StatementsNode(0...16)( [DefNode(0...16)( + :f, (4...5), nil, ParametersNode(6...10)( [], [], [], - 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..a15f667603c2ea 100644 --- a/test/yarp/snapshots/whitequark/restarg_unnamed.txt +++ b/test/yarp/snapshots/whitequark/restarg_unnamed.txt @@ -2,13 +2,14 @@ ProgramNode(0...13)( [], StatementsNode(0...13)( [DefNode(0...13)( + :f, (4...5), nil, ParametersNode(6...7)( [], [], [], - RestParameterNode(6...7)((6...7), nil), + RestParameterNode(6...7)(nil, nil, (6...7)), [], nil, nil 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_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..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)( @@ -9,7 +10,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.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/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/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/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/thread.c b/thread.c index 3884181310b511..3d0e7d108d1b4d 100644 --- a/thread.c +++ b/thread.c @@ -1908,6 +1908,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) { @@ -1920,6 +1937,16 @@ rb_threadptr_pending_interrupt_check_mask(rb_thread_t *th, VALUE err) for (i=0; ipending_interrupt_mask_stack, mask); if (!rb_threadptr_pending_interrupt_empty_p(th)) { th->pending_interrupt_queue_checked = 0; diff --git a/yarp/config.yml b/yarp/config.yml index 5ccdabab16cda9..e63c2bb80216e3 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. @@ -1041,6 +1039,8 @@ nodes: ^^^^^^^ - name: DefNode fields: + - name: name + type: constant - name: name_loc type: location - name: receiver @@ -1558,6 +1558,8 @@ nodes: ^^^^ - name: KeywordParameterNode fields: + - name: name + type: constant - name: name_loc type: location - name: value @@ -1574,10 +1576,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. @@ -1742,21 +1746,15 @@ nodes: type: location - name: name type: constant - - name: name_constant - type: constant comment: | Represents a module declaration involving the `module` keyword. 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 @@ -1764,6 +1762,23 @@ nodes: comment: | Represents a multi-target expression. + a, b, c = 1, 2, 3 + ^^^^^^^ + - name: MultiWriteNode + fields: + - name: targets + type: node[] + - name: lparen_loc + type: location? + - name: rparen_loc + type: location? + - 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 @@ -2059,10 +2074,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/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/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/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/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( diff --git a/yarp/templates/lib/yarp/serialize.rb.erb b/yarp/templates/lib/yarp/serialize.rb.erb index c8d7f422cdb5ba..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) @@ -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/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/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/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/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" diff --git a/yarp/yarp.c b/yarp/yarp.c index 2bce80abade61f..820361e25a7c01 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. @@ -510,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 @@ -544,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 ); } } @@ -638,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; } @@ -811,10 +816,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), @@ -1182,7 +1184,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 }; @@ -1443,9 +1445,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); @@ -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; @@ -2030,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, @@ -2533,10 +2532,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), @@ -3035,10 +3031,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 }; @@ -3069,6 +3062,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 }; @@ -3089,8 +3083,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; @@ -3305,7 +3300,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,39 +3314,33 @@ 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; } -// 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)) { @@ -3364,9 +3352,31 @@ 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 + } + }, + .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; } // Allocate and initialize a new NextNode node. @@ -3490,7 +3500,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, @@ -3773,7 +3783,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 }; @@ -3838,10 +3848,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, @@ -3902,8 +3909,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; @@ -4568,11 +4576,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 /******************************************************************************/ @@ -4610,15 +4613,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 +4635,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 @@ -4640,11 +4654,13 @@ 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); } } -// 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; @@ -4981,7 +4997,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); } /******************************************************************************/ @@ -5141,7 +5157,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; } } @@ -5162,7 +5178,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; @@ -5174,7 +5190,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; @@ -5186,7 +5202,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; @@ -5211,7 +5227,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; @@ -5241,7 +5257,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; @@ -5293,7 +5309,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; } @@ -5334,7 +5350,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; @@ -5365,7 +5381,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; @@ -5705,7 +5721,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; } @@ -5756,9 +5772,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 @@ -5857,7 +5873,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); @@ -6287,7 +6303,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; @@ -6431,7 +6447,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 @@ -6628,7 +6644,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 ); } @@ -6677,7 +6693,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 ); } @@ -6775,7 +6791,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); } @@ -6814,7 +6830,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); } @@ -6939,7 +6955,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; } } @@ -6975,7 +6991,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; } @@ -7046,9 +7062,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 @@ -7921,17 +7944,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); @@ -7944,13 +7967,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 @@ -8027,14 +8050,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. @@ -8060,7 +8083,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)); @@ -8074,7 +8097,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; @@ -8083,13 +8106,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 = { .start = NULL, .end = NULL }; - - 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); + 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 *) multi_target; } case YP_CALL_NODE: { yp_call_node_t *call = (yp_call_node_t *) target; @@ -8123,7 +8143,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; @@ -8167,7 +8187,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; } } @@ -8192,7 +8212,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); @@ -8215,14 +8235,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; @@ -8230,11 +8244,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 = { .start = NULL, .end = NULL }; - 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; @@ -8264,7 +8277,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; @@ -8337,7 +8350,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; } } @@ -8365,11 +8378,9 @@ 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_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; @@ -8382,19 +8393,19 @@ 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); } 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 @@ -8402,45 +8413,35 @@ 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) { + 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_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; - - 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_t) { .start = lparen.start, .end = lparen.end }; - target->rparen_loc = (yp_location_t) { .start = rparen.start, .end = rparen.end }; - } else { - yp_token_t operator = not_provided(parser); - - target = yp_multi_write_node_create( - parser, - &operator, - NULL, - &(yp_location_t) { .start = lparen.start, .end = lparen.end }, - &(yp_location_t) { .start = rparen.start, .end = rparen.end } - ); + 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)) { @@ -8448,7 +8449,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); } @@ -8456,14 +8457,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, "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); + yp_multi_target_node_targets_append(result, target); } } while (accept(parser, YP_TOKEN_COMMA)); } @@ -8488,7 +8489,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 @@ -8533,7 +8534,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); } } @@ -8556,9 +8557,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); @@ -8572,24 +8573,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; } @@ -8637,7 +8638,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; @@ -8646,7 +8647,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); @@ -8665,9 +8666,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); @@ -8681,15 +8682,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); @@ -8705,11 +8706,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); @@ -8720,12 +8721,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; @@ -8738,7 +8739,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); @@ -8794,7 +8795,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); @@ -8805,7 +8806,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); @@ -8817,7 +8818,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; @@ -8832,7 +8833,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); @@ -8842,7 +8843,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; @@ -8897,12 +8898,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; } @@ -8957,7 +8958,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); } @@ -8965,7 +8966,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); @@ -8988,16 +8989,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; } @@ -9015,7 +9016,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); @@ -9073,7 +9074,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); } @@ -9114,7 +9115,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); } @@ -9148,7 +9149,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); } @@ -9166,11 +9167,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); } } @@ -9211,7 +9212,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); @@ -9229,7 +9230,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 @@ -9241,7 +9242,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); @@ -9255,7 +9256,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)) { @@ -9375,7 +9376,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); @@ -9407,7 +9408,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); @@ -9421,7 +9422,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)) { @@ -9436,7 +9437,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; @@ -9454,19 +9455,19 @@ 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); 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_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; @@ -9503,7 +9504,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); @@ -9541,7 +9543,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); @@ -9568,7 +9570,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); @@ -9584,7 +9586,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. @@ -9673,7 +9676,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 @@ -9734,7 +9737,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); @@ -9788,7 +9791,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; } @@ -9797,7 +9800,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; } } @@ -9828,7 +9831,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; } @@ -9872,7 +9875,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); } @@ -9887,7 +9890,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); } @@ -9915,7 +9918,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); } } @@ -9957,7 +9960,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); } } @@ -10176,7 +10179,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 * @@ -10185,7 +10188,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); @@ -10207,9 +10210,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; @@ -10218,8 +10221,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; @@ -10244,8 +10247,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; } @@ -10260,8 +10263,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; } @@ -10276,8 +10279,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; } @@ -10344,7 +10347,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; @@ -10374,12 +10377,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); @@ -10400,7 +10403,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); @@ -10419,11 +10422,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)) { @@ -10433,8 +10436,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; } @@ -10447,8 +10450,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; } @@ -10487,15 +10490,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; } @@ -10504,14 +10507,14 @@ 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; 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; @@ -10526,18 +10529,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)) { @@ -10548,7 +10551,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: @@ -10608,17 +10611,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); } @@ -10628,7 +10631,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); @@ -10642,7 +10645,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); } } @@ -10650,7 +10653,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 { @@ -10667,9 +10670,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); } @@ -10680,13 +10683,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) { @@ -10705,7 +10708,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); @@ -10718,7 +10721,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; @@ -10746,7 +10749,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; } @@ -10778,12 +10781,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); @@ -10851,7 +10854,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 @@ -10863,11 +10866,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); @@ -10879,11 +10882,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); @@ -10895,7 +10898,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); @@ -10913,7 +10916,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); @@ -10928,14 +10931,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 @@ -10948,29 +10951,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 = { .start = opening.start, .end = opening.end }; - yp_location_t rparen_loc = { .start = parser->previous.start, .end = parser->previous.end }; - 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 @@ -10993,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 @@ -11010,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); } @@ -11025,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; @@ -11085,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); @@ -11101,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: @@ -11230,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)); @@ -11255,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; @@ -11303,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; } @@ -11312,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; } @@ -11337,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)); } @@ -11361,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; @@ -11378,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)) { @@ -11402,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); } @@ -11428,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; } @@ -11451,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; @@ -11466,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; } @@ -11487,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); @@ -11496,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 ); } @@ -11506,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: @@ -11543,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); } @@ -11581,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); @@ -11598,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); @@ -11606,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; @@ -11622,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; @@ -11643,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; @@ -11685,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; @@ -11753,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; @@ -11763,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); @@ -11783,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; } @@ -11806,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; } @@ -11837,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; } @@ -11862,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); } @@ -11883,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; } @@ -11915,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( @@ -11934,18 +11935,18 @@ 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: { 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: @@ -11958,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; @@ -11976,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); @@ -12020,22 +12021,22 @@ 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`."); + 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."); - arguments.closing_loc = ((yp_location_t) { .start = parser->previous.start, .end = parser->previous.end }); + 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); } @@ -12048,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 @@ -12061,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); @@ -12072,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); @@ -12093,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); @@ -12121,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); @@ -12132,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); @@ -12142,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); @@ -12153,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); @@ -12166,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); @@ -12175,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; @@ -12311,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; } @@ -12322,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; @@ -12338,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); @@ -12346,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; @@ -12462,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; } @@ -12473,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; @@ -12537,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; @@ -12601,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; } @@ -12619,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); @@ -12629,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); @@ -12639,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; @@ -12648,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; @@ -12657,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: @@ -12696,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; @@ -12723,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)) { @@ -12740,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; @@ -12752,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; @@ -12794,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 @@ -12821,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)) { @@ -12858,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); } } @@ -12876,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); } } @@ -12897,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 @@ -12924,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); @@ -12935,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; } @@ -12964,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: { @@ -12973,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; @@ -12986,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; } } @@ -12994,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); @@ -13008,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); @@ -13017,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); @@ -13032,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); @@ -13042,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); @@ -13059,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); @@ -13073,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: @@ -13087,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; } } @@ -13095,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); @@ -13109,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); @@ -13118,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); @@ -13133,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); @@ -13143,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); @@ -13160,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); @@ -13174,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: @@ -13188,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; } } @@ -13206,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); @@ -13220,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); @@ -13229,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); @@ -13244,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); @@ -13254,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); @@ -13271,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); @@ -13285,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: @@ -13299,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; } } @@ -13307,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: { @@ -13325,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. @@ -13376,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: @@ -13403,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 }; } } @@ -13428,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); @@ -13437,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: { @@ -13452,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: { @@ -13460,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 @@ -13481,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); } @@ -13553,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); } @@ -13562,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); } @@ -13570,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); @@ -13579,10 +13580,10 @@ 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_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. @@ -13613,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); @@ -13628,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); @@ -13646,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); @@ -13654,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; } @@ -13757,7 +13758,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 +13900,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); } @@ -13933,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 diff --git a/yarp/yarp_compiler.c b/yarp/yarp_compiler.c index 10ef6a1e8c4d9f..802c85d808ec82 100644 --- a/yarp/yarp_compiler.c +++ b/yarp/yarp_compiler.c @@ -12,13 +12,34 @@ #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, 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 +48,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); } @@ -100,7 +181,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 +339,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; } @@ -298,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); @@ -334,6 +419,31 @@ 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(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); + } + } + } + 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) { @@ -394,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 { @@ -436,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; @@ -446,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); } @@ -455,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; } @@ -463,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; } @@ -479,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) { @@ -491,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)); @@ -522,14 +632,17 @@ 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); } return; } 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); @@ -549,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) { @@ -558,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; } @@ -597,7 +710,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))); @@ -609,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); @@ -645,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); @@ -668,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; @@ -706,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); @@ -735,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); } @@ -747,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))); @@ -755,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); } @@ -797,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); @@ -817,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; @@ -861,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); @@ -875,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); @@ -906,7 +1019,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; @@ -914,14 +1027,22 @@ 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) - yp_compile_node(iseq, (yp_node_t *) (embedded_statements_node->statements), ret, src, popped, compile_context); + if (embedded_statements_node->statements) { + YP_COMPILE((yp_node_t *) (embedded_statements_node->statements)); + } + 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; } 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: @@ -946,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); @@ -957,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); @@ -972,7 +1093,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; } @@ -995,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); @@ -1012,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; @@ -1053,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); @@ -1075,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); } @@ -1102,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) { @@ -1122,7 +1243,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; } @@ -1149,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); @@ -1172,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; @@ -1211,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); @@ -1236,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); @@ -1250,59 +1371,36 @@ 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; } - case YP_NODE_INTERPOLATED_STRING_NODE: { - yp_interpolated_string_node_t *interp_string_node= (yp_interpolated_string_node_t *) node; - - 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; - } + 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))); } - if (interp_string_node->parts.size > 1) { - ADD_INSN1(ret, &dummy_line_node, concatstrings, INT2FIX((int)(interp_string_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; - - 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; - } - } + 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 (interp_symbol_node->parts.size > 1) { - ADD_INSN1(ret, &dummy_line_node, concatstrings, INT2FIX((int)(interp_symbol_node->parts.size))); + 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) { @@ -1314,12 +1412,29 @@ 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); + + 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); + } + 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; 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)); @@ -1361,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); @@ -1381,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; @@ -1420,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); @@ -1442,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); @@ -1463,7 +1578,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); @@ -1482,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; @@ -1492,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; @@ -1500,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); @@ -1527,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); @@ -1537,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); @@ -1558,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; @@ -1570,9 +1685,10 @@ 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); + YP_COMPILE((yp_node_t *) res_node); } return; @@ -1586,8 +1702,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); @@ -1598,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) { @@ -1613,15 +1729,31 @@ 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; } + 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; 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); @@ -1723,6 +1855,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 +1883,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; @@ -1758,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"); @@ -1809,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); @@ -1822,15 +1959,20 @@ 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_list.nodes[node_list.size - 1]); + } + else { + ADD_INSN(ret, &dummy_line_node, putnil); } - yp_compile_node(iseq, node_list.nodes[node_list.size - 1], ret, src, false, compile_context); return; } 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: { @@ -1842,7 +1984,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,10 +1998,10 @@ 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); + YP_COMPILE(undef_node->names.nodes[index]); ADD_SEND(ret, &dummy_line_node, rb_intern("core#undef_method"), INT2NUM(2)); diff --git a/yjit/src/codegen.rs b/yjit/src/codegen.rs index 92dd239c8b9f66..69b1c52c9ca739 100644 --- a/yjit/src/codegen.rs +++ b/yjit/src/codegen.rs @@ -2035,11 +2035,11 @@ fn jit_chain_guard( } } -// up to 5 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 5 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; @@ -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, ); @@ -4697,9 +4694,48 @@ 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, out_val); + + 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 @@ -4975,7 +5011,7 @@ fn jit_obj_respond_to( jit, asm, ocb, - SEND_MAX_CHAIN_DEPTH, + SEND_MAX_DEPTH, Counter::guard_send_respond_to_mid_mismatch, ); @@ -6027,7 +6063,7 @@ fn gen_send_iseq( jit, asm, ocb, - SEND_MAX_CHAIN_DEPTH, + SEND_MAX_DEPTH, Counter::guard_send_block_arg_type, ); @@ -7175,7 +7211,7 @@ fn gen_send_general( jit, asm, ocb, - SEND_MAX_CHAIN_DEPTH, + SEND_MAX_DEPTH, Counter::guard_send_send_chain, ); @@ -7417,7 +7453,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; } @@ -7451,7 +7487,7 @@ fn gen_invokeblock_specialized( jit, asm, ocb, - SEND_MAX_CHAIN_DEPTH, + SEND_MAX_DEPTH, Counter::guard_invokeblock_tag_changed, ); @@ -7467,7 +7503,7 @@ fn gen_invokeblock_specialized( jit, asm, ocb, - SEND_MAX_CHAIN_DEPTH, + SEND_MAX_DEPTH, Counter::guard_invokeblock_iseq_block_changed, ); @@ -7510,7 +7546,7 @@ fn gen_invokeblock_specialized( jit, asm, ocb, - SEND_MAX_CHAIN_DEPTH, + SEND_MAX_DEPTH, Counter::guard_invokeblock_tag_changed, ); @@ -7591,7 +7627,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; } @@ -7675,7 +7711,7 @@ fn gen_invokesuper_specialized( jit, asm, ocb, - SEND_MAX_CHAIN_DEPTH, + SEND_MAX_DEPTH, Counter::guard_invokesuper_me_changed, ); @@ -8750,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); 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