diff options
author | Kevin Newton <[email protected]> | 2024-07-02 14:27:04 -0400 |
---|---|---|
committer | Kevin Newton <[email protected]> | 2024-07-11 14:25:54 -0400 |
commit | ca48fb76fb0669ca0666a7aa129e1f5d2b7468da (patch) | |
tree | fce04cbe37f6976af6824f885a6032f66df7d470 | |
parent | 678dd769e560db9cebff41218e3413e6688aaf12 (diff) |
[ruby/prism] Move location to second position for node initializers
https://github.com/ruby/prism/commit/4cc0eda4ca
-rw-r--r-- | lib/prism/desugar_compiler.rb | 185 | ||||
-rw-r--r-- | lib/prism/node_ext.rb | 20 | ||||
-rw-r--r-- | lib/prism/parse_result.rb | 13 | ||||
-rw-r--r-- | lib/prism/parse_result/errors.rb | 5 | ||||
-rw-r--r-- | prism/templates/ext/prism/api_node.c.erb | 8 | ||||
-rw-r--r-- | prism/templates/lib/prism/dsl.rb.erb | 115 | ||||
-rw-r--r-- | prism/templates/lib/prism/node.rb.erb | 10 | ||||
-rw-r--r-- | prism/templates/lib/prism/serialize.rb.erb | 12 | ||||
-rw-r--r-- | test/prism/errors/content_after_unterminated_heredoc.txt | 2 | ||||
-rw-r--r-- | test/prism/snapshots/patterns.txt | 144 |
10 files changed, 363 insertions, 151 deletions
diff --git a/lib/prism/desugar_compiler.rb b/lib/prism/desugar_compiler.rb index de02445149..c51bdd2b1c 100644 --- a/lib/prism/desugar_compiler.rb +++ b/lib/prism/desugar_compiler.rb @@ -2,11 +2,13 @@ module Prism class DesugarAndWriteNode # :nodoc: - attr_reader :node, :source, :read_class, :write_class, :arguments + include DSL - def initialize(node, source, read_class, write_class, *arguments) + attr_reader :node, :default_source, :read_class, :write_class, :arguments + + def initialize(node, default_source, read_class, write_class, **arguments) @node = node - @source = source + @default_source = default_source @read_class = read_class @write_class = write_class @arguments = arguments @@ -14,22 +16,30 @@ module Prism # Desugar `x &&= y` to `x && x = y` def compile - AndNode.new( - source, - read_class.new(source, *arguments, node.name_loc), - write_class.new(source, *arguments, node.name_loc, node.value, node.operator_loc, node.location), - node.operator_loc, - node.location + and_node( + location: node.location, + left: public_send(read_class, location: node.name_loc, **arguments), + right: public_send( + write_class, + location: node.location, + **arguments, + name_loc: node.name_loc, + value: node.value, + operator_loc: node.operator_loc + ), + operator_loc: node.operator_loc ) end end class DesugarOrWriteDefinedNode # :nodoc: - attr_reader :node, :source, :read_class, :write_class, :arguments + include DSL + + attr_reader :node, :default_source, :read_class, :write_class, :arguments - def initialize(node, source, read_class, write_class, *arguments) + def initialize(node, default_source, read_class, write_class, **arguments) @node = node - @source = source + @default_source = default_source @read_class = read_class @write_class = write_class @arguments = arguments @@ -37,35 +47,50 @@ module Prism # Desugar `x ||= y` to `defined?(x) ? x : x = y` def compile - IfNode.new( - source, - node.operator_loc, - DefinedNode.new(source, nil, read_class.new(source, *arguments, node.name_loc), nil, node.operator_loc, node.name_loc), - node.operator_loc, - StatementsNode.new(source, [read_class.new(source, *arguments, node.name_loc)], node.location), - ElseNode.new( - source, - node.operator_loc, - StatementsNode.new( - source, - [write_class.new(source, *arguments, node.name_loc, node.value, node.operator_loc, node.location)], - node.location + if_node( + location: node.location, + if_keyword_loc: node.operator_loc, + predicate: defined_node( + location: node.name_loc, + value: public_send(read_class, location: node.name_loc, **arguments), + keyword_loc: node.operator_loc + ), + then_keyword_loc: node.operator_loc, + statements: statements_node( + location: node.location, + body: [public_send(read_class, location: node.name_loc, **arguments)] + ), + consequent: else_node( + location: node.location, + else_keyword_loc: node.operator_loc, + statements: statements_node( + location: node.location, + body: [ + public_send( + write_class, + location: node.location, + **arguments, + name_loc: node.name_loc, + value: node.value, + operator_loc: node.operator_loc + ) + ] ), - node.operator_loc, - node.location + end_keyword_loc: node.operator_loc ), - node.operator_loc, - node.location + end_keyword_loc: node.operator_loc ) end end class DesugarOperatorWriteNode # :nodoc: - attr_reader :node, :source, :read_class, :write_class, :arguments + include DSL - def initialize(node, source, read_class, write_class, *arguments) + attr_reader :node, :default_source, :read_class, :write_class, :arguments + + def initialize(node, default_source, read_class, write_class, **arguments) @node = node - @source = source + @default_source = default_source @read_class = read_class @write_class = write_class @arguments = arguments @@ -75,35 +100,41 @@ module Prism def compile binary_operator_loc = node.binary_operator_loc.chop - write_class.new( - source, - *arguments, - node.name_loc, - CallNode.new( - source, - 0, - read_class.new(source, *arguments, node.name_loc), - nil, - binary_operator_loc.slice.to_sym, - binary_operator_loc, - nil, - ArgumentsNode.new(source, 0, [node.value], node.value.location), - nil, - nil, - node.location + public_send( + write_class, + location: node.location, + **arguments, + name_loc: node.name_loc, + value: call_node( + location: node.location, + receiver: public_send( + read_class, + location: node.name_loc, + **arguments + ), + name: binary_operator_loc.slice.to_sym, + message_loc: binary_operator_loc, + arguments: arguments_node( + location: node.value.location, + arguments: [node.value] + ) ), - node.binary_operator_loc.copy(start_offset: node.binary_operator_loc.end_offset - 1, length: 1), - node.location + operator_loc: node.binary_operator_loc.copy( + start_offset: node.binary_operator_loc.end_offset - 1, + length: 1 + ) ) end end class DesugarOrWriteNode # :nodoc: - attr_reader :node, :source, :read_class, :write_class, :arguments + include DSL - def initialize(node, source, read_class, write_class, *arguments) + attr_reader :node, :default_source, :read_class, :write_class, :arguments + + def initialize(node, default_source, read_class, write_class, **arguments) @node = node - @source = source + @default_source = default_source @read_class = read_class @write_class = write_class @arguments = arguments @@ -111,12 +142,18 @@ module Prism # Desugar `x ||= y` to `x || x = y` def compile - OrNode.new( - source, - read_class.new(source, *arguments, node.name_loc), - write_class.new(source, *arguments, node.name_loc, node.value, node.operator_loc, node.location), - node.operator_loc, - node.location + or_node( + location: node.location, + left: public_send(read_class, location: node.name_loc, **arguments), + right: public_send( + write_class, + location: node.location, + **arguments, + name_loc: node.name_loc, + value: node.value, + operator_loc: node.operator_loc + ), + operator_loc: node.operator_loc ) end end @@ -125,91 +162,91 @@ module Prism class ClassVariableAndWriteNode def desugar # :nodoc: - DesugarAndWriteNode.new(self, source, ClassVariableReadNode, ClassVariableWriteNode, name).compile + DesugarAndWriteNode.new(self, source, :class_variable_read_node, :class_variable_write_node, name: name).compile end end class ClassVariableOrWriteNode def desugar # :nodoc: - DesugarOrWriteDefinedNode.new(self, source, ClassVariableReadNode, ClassVariableWriteNode, name).compile + DesugarOrWriteDefinedNode.new(self, source, :class_variable_read_node, :class_variable_write_node, name: name).compile end end class ClassVariableOperatorWriteNode def desugar # :nodoc: - DesugarOperatorWriteNode.new(self, source, ClassVariableReadNode, ClassVariableWriteNode, name).compile + DesugarOperatorWriteNode.new(self, source, :class_variable_read_node, :class_variable_write_node, name: name).compile end end class ConstantAndWriteNode def desugar # :nodoc: - DesugarAndWriteNode.new(self, source, ConstantReadNode, ConstantWriteNode, name).compile + DesugarAndWriteNode.new(self, source, :constant_read_node, :constant_write_node, name: name).compile end end class ConstantOrWriteNode def desugar # :nodoc: - DesugarOrWriteDefinedNode.new(self, source, ConstantReadNode, ConstantWriteNode, name).compile + DesugarOrWriteDefinedNode.new(self, source, :constant_read_node, :constant_write_node, name: name).compile end end class ConstantOperatorWriteNode def desugar # :nodoc: - DesugarOperatorWriteNode.new(self, source, ConstantReadNode, ConstantWriteNode, name).compile + DesugarOperatorWriteNode.new(self, source, :constant_read_node, :constant_write_node, name: name).compile end end class GlobalVariableAndWriteNode def desugar # :nodoc: - DesugarAndWriteNode.new(self, source, GlobalVariableReadNode, GlobalVariableWriteNode, name).compile + DesugarAndWriteNode.new(self, source, :global_variable_read_node, :global_variable_write_node, name: name).compile end end class GlobalVariableOrWriteNode def desugar # :nodoc: - DesugarOrWriteDefinedNode.new(self, source, GlobalVariableReadNode, GlobalVariableWriteNode, name).compile + DesugarOrWriteDefinedNode.new(self, source, :global_variable_read_node, :global_variable_write_node, name: name).compile end end class GlobalVariableOperatorWriteNode def desugar # :nodoc: - DesugarOperatorWriteNode.new(self, source, GlobalVariableReadNode, GlobalVariableWriteNode, name).compile + DesugarOperatorWriteNode.new(self, source, :global_variable_read_node, :global_variable_write_node, name: name).compile end end class InstanceVariableAndWriteNode def desugar # :nodoc: - DesugarAndWriteNode.new(self, source, InstanceVariableReadNode, InstanceVariableWriteNode, name).compile + DesugarAndWriteNode.new(self, source, :instance_variable_read_node, :instance_variable_write_node, name: name).compile end end class InstanceVariableOrWriteNode def desugar # :nodoc: - DesugarOrWriteNode.new(self, source, InstanceVariableReadNode, InstanceVariableWriteNode, name).compile + DesugarOrWriteNode.new(self, source, :instance_variable_read_node, :instance_variable_write_node, name: name).compile end end class InstanceVariableOperatorWriteNode def desugar # :nodoc: - DesugarOperatorWriteNode.new(self, source, InstanceVariableReadNode, InstanceVariableWriteNode, name).compile + DesugarOperatorWriteNode.new(self, source, :instance_variable_read_node, :instance_variable_write_node, name: name).compile end end class LocalVariableAndWriteNode def desugar # :nodoc: - DesugarAndWriteNode.new(self, source, LocalVariableReadNode, LocalVariableWriteNode, name, depth).compile + DesugarAndWriteNode.new(self, source, :local_variable_read_node, :local_variable_write_node, name: name, depth: depth).compile end end class LocalVariableOrWriteNode def desugar # :nodoc: - DesugarOrWriteNode.new(self, source, LocalVariableReadNode, LocalVariableWriteNode, name, depth).compile + DesugarOrWriteNode.new(self, source, :local_variable_read_node, :local_variable_write_node, name: name, depth: depth).compile end end class LocalVariableOperatorWriteNode def desugar # :nodoc: - DesugarOperatorWriteNode.new(self, source, LocalVariableReadNode, LocalVariableWriteNode, name, depth).compile + DesugarOperatorWriteNode.new(self, source, :local_variable_read_node, :local_variable_write_node, name: name, depth: depth).compile end end diff --git a/lib/prism/node_ext.rb b/lib/prism/node_ext.rb index aa6a18cf29..fe36be8541 100644 --- a/lib/prism/node_ext.rb +++ b/lib/prism/node_ext.rb @@ -69,11 +69,11 @@ module Prism def to_interpolated InterpolatedStringNode.new( source, + location, frozen? ? InterpolatedStringNodeFlags::FROZEN : 0, opening_loc, - [copy(opening_loc: nil, closing_loc: nil, location: content_loc)], - closing_loc, - location + [copy(location: content_loc, opening_loc: nil, closing_loc: nil)], + closing_loc ) end end @@ -86,10 +86,10 @@ module Prism def to_interpolated InterpolatedXStringNode.new( source, + location, opening_loc, - [StringNode.new(source, 0, nil, content_loc, nil, unescaped, content_loc)], - closing_loc, - location + [StringNode.new(source, content_loc, 0, nil, content_loc, nil, unescaped)], + closing_loc ) end end @@ -115,9 +115,9 @@ module Prism deprecated("value", "numerator", "denominator") if denominator == 1 - IntegerNode.new(source, flags, numerator, location.chop) + IntegerNode.new(source, location.chop, flags, numerator) else - FloatNode.new(source, numerator.to_f / denominator, location.chop) + FloatNode.new(source, location.chop, numerator.to_f / denominator) end end end @@ -195,7 +195,7 @@ module Prism # continue to supply that API. def child deprecated("name", "name_loc") - name ? ConstantReadNode.new(source, name, name_loc) : MissingNode.new(source, location) + name ? ConstantReadNode.new(source, name_loc, name) : MissingNode.new(source, location) end end @@ -231,7 +231,7 @@ module Prism # continue to supply that API. def child deprecated("name", "name_loc") - name ? ConstantReadNode.new(source, name, name_loc) : MissingNode.new(source, location) + name ? ConstantReadNode.new(source, name_loc, name) : MissingNode.new(source, location) end end diff --git a/lib/prism/parse_result.rb b/lib/prism/parse_result.rb index cc4f942283..ae57242707 100644 --- a/lib/prism/parse_result.rb +++ b/lib/prism/parse_result.rb @@ -10,7 +10,11 @@ module Prism # specialized and more performant `ASCIISource` if no multibyte characters # are present in the source code. def self.for(source, start_line = 1, offsets = []) - source.ascii_only? ? ASCIISource.new(source, start_line, offsets): new(source, start_line, offsets) + if source.ascii_only? + ASCIISource.new(source, start_line, offsets) + else + new(source, start_line, offsets) + end end # The source code that this source object represents. @@ -87,7 +91,12 @@ module Prism # encodings, it is not captured here. def code_units_offset(byte_offset, encoding) byteslice = (source.byteslice(0, byte_offset) or raise).encode(encoding) - (encoding == Encoding::UTF_16LE || encoding == Encoding::UTF_16BE) ? (byteslice.bytesize / 2) : byteslice.length + + if encoding == Encoding::UTF_16LE || encoding == Encoding::UTF_16BE + byteslice.bytesize / 2 + else + byteslice.length + end end # Returns the column number in code units for the given encoding for the diff --git a/lib/prism/parse_result/errors.rb b/lib/prism/parse_result/errors.rb index 40dda3c264..1eaeebee6e 100644 --- a/lib/prism/parse_result/errors.rb +++ b/lib/prism/parse_result/errors.rb @@ -4,13 +4,18 @@ require "stringio" module Prism class ParseResult < Result + # An object to represent the set of errors on a parse result. This object + # can be used to format the errors in a human-readable way. class Errors + # The parse result that contains the errors. attr_reader :parse_result + # Initialize a new set of errors from the given parse result. def initialize(parse_result) @parse_result = parse_result end + # Formats the errors in a human-readable way and return them as a string. def format error_lines = {} parse_result.errors.each do |error| diff --git a/prism/templates/ext/prism/api_node.c.erb b/prism/templates/ext/prism/api_node.c.erb index de6f4b95fd..258c61f319 100644 --- a/prism/templates/ext/prism/api_node.c.erb +++ b/prism/templates/ext/prism/api_node.c.erb @@ -177,7 +177,10 @@ pm_ast_new(const pm_parser_t *parser, const pm_node_t *node, rb_encoding *encodi // source argv[0] = source; - <%- node.fields.each.with_index(1) do |field, index| -%> + + // location + argv[1] = pm_location_new(parser, node->location.start, node->location.end); + <%- node.fields.each.with_index(2) do |field, index| -%> // <%= field.name %> <%- case field -%> @@ -232,9 +235,6 @@ pm_ast_new(const pm_parser_t *parser, const pm_node_t *node, rb_encoding *encodi <%- end -%> <%- end -%> - // location - argv[<%= node.fields.length + 1 %>] = pm_location_new(parser, node->location.start, node->location.end); - rb_ary_push(value_stack, rb_class_new_instance(<%= node.fields.length + 2 %>, argv, rb_cPrism<%= node.name %>)); break; } diff --git a/prism/templates/lib/prism/dsl.rb.erb b/prism/templates/lib/prism/dsl.rb.erb index eff0d1c4fc..4f61d71a2a 100644 --- a/prism/templates/lib/prism/dsl.rb.erb +++ b/prism/templates/lib/prism/dsl.rb.erb @@ -5,45 +5,118 @@ module Prism # source = Prism::Source.for("[1]") # # Prism::ArrayNode.new( + # source, + # Prism::Location.new(source, 0, 3), + # 0, # [ # Prism::IntegerNode.new( - # Prism::IntegerBaseFlags::DECIMAL, - # 1, + # source, # Prism::Location.new(source, 1, 1), - # source + # Prism::IntegerBaseFlags::DECIMAL, + # 1 # ) # ], # Prism::Location.new(source, 0, 1), - # Prism::Location.new(source, 2, 1), - # source + # Prism::Location.new(source, 2, 1) # ) # # you could instead write: # - # source = Prism::Source.for("[1]") + # class Builder + # include Prism::DSL # - # ArrayNode( - # IntegerNode(Prism::IntegerBaseFlags::DECIMAL, 1, Location(source, 1, 1)), source), - # Location(source, 0, 1), - # Location(source, 2, 1), - # source - # ) + # attr_reader :default_source + # + # def initialize + # @default_source = source("[1]") + # end # - # This is mostly helpful in the context of writing tests, but can also be used - # to generate trees programmatically. + # def build + # array_node( + # location: location(start_offset: 0, length: 3), + # elements: [ + # integer_node( + # location: location(start_offset: 1, length: 1), + # flags: integer_base_flag(:decimal), + # value: 1 + # ) + # ], + # opening_loc: location(start_offset: 0, length: 1), + # closing_loc: location(start_offset: 2, length: 1) + # ) + # end + # end + # + # This is mostly helpful in the context of generating trees programmatically. module DSL - private + # Provide all of these methods as module methods as well, to allow for + # building nodes like Prism::DSL.nil_node. + extend self - # Create a new Location object - def Location(source = nil, start_offset = 0, length = 0) - Location.new(source, start_offset, length) # steep:ignore + # Create a new Source object. + def source(string) + Source.for(string) + end + + # Create a new Location object. + def location(source: default_source, start_offset: 0, length: 0) + Location.new(source, start_offset, length) end <%- nodes.each do |node| -%> - # Create a new <%= node.name %> node - def <%= node.name %>(<%= (node.fields.map(&:name) + ["source = nil, location = Location()"]).join(", ") %>) - <%= node.name %>.new(<%= ["source", *node.fields.map(&:name), "location"].join(", ") %>) + # Create a new <%= node.name %> node. + def <%= node.human %>(<%= ["source: default_source", "location: default_location", *node.fields.map { |field| + case field + when Prism::Template::NodeField, Prism::Template::ConstantField + "#{field.name}: default_node(source, location)" + when Prism::Template::OptionalNodeField, Prism::Template::OptionalConstantField, Prism::Template::OptionalLocationField + "#{field.name}: nil" + when Prism::Template::NodeListField, Prism::Template::ConstantListField + "#{field.name}: []" + when Prism::Template::StringField + "#{field.name}: \"\"" + when Prism::Template::LocationField + "#{field.name}: location" + when Prism::Template::UInt8Field, Prism::Template::UInt32Field, Prism::Template::FlagsField, Prism::Template::IntegerField, Prism::Template::DoubleField + "#{field.name}: 0" + else + raise + end + }].join(", ") %>) + <%= node.name %>.new(<%= ["source", "location", *node.fields.map(&:name)].join(", ") %>) end <%- end -%> + <%- flags.each do |flag| -%> + + # Retrieve the value of one of the <%= flag.name %> flags. + def <%= flag.human.chomp("s") %>(name) + case name + <%- flag.values.each do |value| -%> + when :<%= value.name.downcase %> then <%= flag.name %>::<%= value.name %> + <%- end -%> + else raise ArgumentError, "invalid <%= flag.name %> flag: #{name.inspect}" + end + end + <%- end -%> + + private + + # The default source object that gets attached to nodes and locations if no + # source is specified. + def default_source + Source.for("") + end + + # The default location object that gets attached to nodes if no location is + # specified, which uses the given source. + def default_location + Location.new(default_source, 0, 0) + end + + # The default node that gets attached to nodes if no node is specified for a + # required node field. + def default_node(source, location) + MissingNode.new(source, location) + end end end diff --git a/prism/templates/lib/prism/node.rb.erb b/prism/templates/lib/prism/node.rb.erb index f0ce226def..945b62fadb 100644 --- a/prism/templates/lib/prism/node.rb.erb +++ b/prism/templates/lib/prism/node.rb.erb @@ -166,8 +166,8 @@ module Prism #<%= line %> <%- end -%> class <%= node.name -%> < Node - # def initialize: (<%= (node.fields.map { |field| "#{field.rbs_class} #{field.name}" } + ["Location location"]).join(", ") %>) -> void - def initialize(source, <%= (node.fields.map(&:name) + ["location"]).join(", ") %>) + # Initialize a new <%= node.name %> node. + def initialize(<%= ["source", "location", *node.fields.map(&:name)].join(", ") %>) @source = source @location = location <%- node.fields.each do |field| -%> @@ -228,9 +228,9 @@ module Prism }.compact.join(", ") %>] #: Array[Prism::node | Location] end - # def copy: (<%= (node.fields.map { |field| "?#{field.name}: #{field.rbs_class}" } + ["?location: Location"]).join(", ") %>) -> <%= node.name %> - def copy(<%= (node.fields.map(&:name) + ["location"]).map { |field| "#{field}: self.#{field}" }.join(", ") %>) - <%= node.name %>.new(<%= ["source", *node.fields.map(&:name), "location"].join(", ") %>) + # def copy: (<%= (["?location: Location"] + node.fields.map { |field| "?#{field.name}: #{field.rbs_class}" }).join(", ") %>) -> <%= node.name %> + def copy(<%= (["location"] + node.fields.map(&:name)).map { |field| "#{field}: self.#{field}" }.join(", ") %>) + <%= node.name %>.new(<%= ["source", "location", *node.fields.map(&:name)].join(", ") %>) end # def deconstruct: () -> Array[nil | Node] diff --git a/prism/templates/lib/prism/serialize.rb.erb b/prism/templates/lib/prism/serialize.rb.erb index 19116b9e6b..5532a7fd6a 100644 --- a/prism/templates/lib/prism/serialize.rb.erb +++ b/prism/templates/lib/prism/serialize.rb.erb @@ -319,7 +319,7 @@ module Prism end end - if RUBY_ENGINE == 'ruby' + if RUBY_ENGINE == "ruby" def load_node type = io.getbyte location = load_location @@ -330,8 +330,7 @@ module Prism <%- if node.needs_serialized_length? -%> load_uint32 <%- end -%> - <%= node.name %>.new( - source, <%= (node.fields.map { |field| + <%= node.name %>.new(<%= ["source", "location", *node.fields.map { |field| case field when Prism::Template::NodeField then "load_node" when Prism::Template::OptionalNodeField then "load_optional_node" @@ -348,7 +347,7 @@ module Prism when Prism::Template::DoubleField then "load_double" else raise end - } + ["location"]).join(", ") -%>) + }].join(", ") -%>) <%- end -%> end end @@ -367,8 +366,7 @@ module Prism <%- if node.needs_serialized_length? -%> load_uint32 <%- end -%> - <%= node.name %>.new( - source, <%= (node.fields.map { |field| + <%= node.name %>.new(<%= ["source", "location", *node.fields.map { |field| case field when Prism::Template::NodeField then "load_node" when Prism::Template::OptionalNodeField then "load_optional_node" @@ -385,7 +383,7 @@ module Prism when Prism::Template::DoubleField then "load_double" else raise end - } + ["location"]).join(", ") -%>) + }].join(", ") -%>) }, <%- end -%> ] diff --git a/test/prism/errors/content_after_unterminated_heredoc.txt b/test/prism/errors/content_after_unterminated_heredoc.txt index 43815cd9d0..c0446a8c39 100644 --- a/test/prism/errors/content_after_unterminated_heredoc.txt +++ b/test/prism/errors/content_after_unterminated_heredoc.txt @@ -1,2 +1,4 @@ <<~FOO.foo ^~~ unterminated heredoc; can't find string "FOO" anywhere before EOF + ^~~ unterminated heredoc; can't find string "FOO" anywhere before EOF + diff --git a/test/prism/snapshots/patterns.txt b/test/prism/snapshots/patterns.txt index 17aa23b4b9..51026972e1 100644 --- a/test/prism/snapshots/patterns.txt +++ b/test/prism/snapshots/patterns.txt @@ -1,8 +1,8 @@ -@ ProgramNode (location: (1,0)-(217,5)) -├── locals: [:bar, :baz, :qux, :b, :a, :foo, :x] +@ ProgramNode (location: (1,0)-(220,31)) +├── locals: [:bar, :baz, :qux, :b, :a, :foo, :x, :_a] └── statements: - @ StatementsNode (location: (1,0)-(217,5)) - └── body: (length: 180) + @ StatementsNode (location: (1,0)-(220,31)) + └── body: (length: 182) ├── @ MatchRequiredNode (location: (1,0)-(1,10)) │ ├── value: │ │ @ CallNode (location: (1,0)-(1,3)) @@ -4883,27 +4883,115 @@ │ │ └── operator_loc: (212,11)-(212,13) = "in" │ ├── opening_loc: (212,7)-(212,8) = "{" │ └── closing_loc: (212,18)-(212,19) = "}" - └── @ MultiWriteNode (location: (214,0)-(217,5)) - ├── lefts: (length: 2) - │ ├── @ LocalVariableTargetNode (location: (215,2)-(215,3)) - │ │ ├── name: :a - │ │ └── depth: 0 - │ └── @ LocalVariableTargetNode (location: (216,2)-(216,3)) - │ ├── name: :b - │ └── depth: 0 - ├── rest: ∅ - ├── rights: (length: 0) - ├── lparen_loc: (214,0)-(214,1) = "(" - ├── rparen_loc: (217,0)-(217,1) = ")" - ├── operator_loc: (217,2)-(217,3) = "=" - └── value: - @ CallNode (location: (217,4)-(217,5)) - ├── flags: variable_call, ignore_visibility - ├── receiver: ∅ - ├── call_operator_loc: ∅ - ├── name: :c - ├── message_loc: (217,4)-(217,5) = "c" - ├── opening_loc: ∅ - ├── arguments: ∅ - ├── closing_loc: ∅ - └── block: ∅ + ├── @ MultiWriteNode (location: (214,0)-(217,5)) + │ ├── lefts: (length: 2) + │ │ ├── @ LocalVariableTargetNode (location: (215,2)-(215,3)) + │ │ │ ├── name: :a + │ │ │ └── depth: 0 + │ │ └── @ LocalVariableTargetNode (location: (216,2)-(216,3)) + │ │ ├── name: :b + │ │ └── depth: 0 + │ ├── rest: ∅ + │ ├── rights: (length: 0) + │ ├── lparen_loc: (214,0)-(214,1) = "(" + │ ├── rparen_loc: (217,0)-(217,1) = ")" + │ ├── operator_loc: (217,2)-(217,3) = "=" + │ └── value: + │ @ CallNode (location: (217,4)-(217,5)) + │ ├── flags: variable_call, ignore_visibility + │ ├── receiver: ∅ + │ ├── call_operator_loc: ∅ + │ ├── name: :c + │ ├── message_loc: (217,4)-(217,5) = "c" + │ ├── opening_loc: ∅ + │ ├── arguments: ∅ + │ ├── closing_loc: ∅ + │ └── block: ∅ + ├── @ CaseMatchNode (location: (219,0)-(219,25)) + │ ├── predicate: + │ │ @ ParenthesesNode (location: (219,5)-(219,7)) + │ │ ├── body: ∅ + │ │ ├── opening_loc: (219,5)-(219,6) = "(" + │ │ └── closing_loc: (219,6)-(219,7) = ")" + │ ├── conditions: (length: 1) + │ │ └── @ InNode (location: (219,9)-(219,20)) + │ │ ├── pattern: + │ │ │ @ ArrayPatternNode (location: (219,12)-(219,20)) + │ │ │ ├── constant: ∅ + │ │ │ ├── requireds: (length: 2) + │ │ │ │ ├── @ LocalVariableTargetNode (location: (219,13)-(219,15)) + │ │ │ │ │ ├── name: :_a + │ │ │ │ │ └── depth: 0 + │ │ │ │ └── @ LocalVariableTargetNode (location: (219,17)-(219,19)) + │ │ │ │ ├── name: :_a + │ │ │ │ └── depth: 0 + │ │ │ ├── rest: ∅ + │ │ │ ├── posts: (length: 0) + │ │ │ ├── opening_loc: (219,12)-(219,13) = "[" + │ │ │ └── closing_loc: (219,19)-(219,20) = "]" + │ │ ├── statements: ∅ + │ │ ├── in_loc: (219,9)-(219,11) = "in" + │ │ └── then_loc: ∅ + │ ├── consequent: ∅ + │ ├── case_keyword_loc: (219,0)-(219,4) = "case" + │ └── end_keyword_loc: (219,22)-(219,25) = "end" + └── @ CaseMatchNode (location: (220,0)-(220,31)) + ├── predicate: + │ @ ParenthesesNode (location: (220,5)-(220,7)) + │ ├── body: ∅ + │ ├── opening_loc: (220,5)-(220,6) = "(" + │ └── closing_loc: (220,6)-(220,7) = ")" + ├── conditions: (length: 1) + │ └── @ InNode (location: (220,9)-(220,26)) + │ ├── pattern: + │ │ @ ArrayPatternNode (location: (220,12)-(220,26)) + │ │ ├── constant: ∅ + │ │ ├── requireds: (length: 2) + │ │ │ ├── @ HashPatternNode (location: (220,13)-(220,18)) + │ │ │ │ ├── constant: ∅ + │ │ │ │ ├── elements: (length: 1) + │ │ │ │ │ └── @ AssocNode (location: (220,14)-(220,17)) + │ │ │ │ │ ├── key: + │ │ │ │ │ │ @ SymbolNode (location: (220,14)-(220,16)) + │ │ │ │ │ │ ├── flags: forced_us_ascii_encoding + │ │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ │ ├── value_loc: (220,14)-(220,15) = "a" + │ │ │ │ │ │ ├── closing_loc: (220,15)-(220,16) = ":" + │ │ │ │ │ │ └── unescaped: "a" + │ │ │ │ │ ├── value: + │ │ │ │ │ │ @ IntegerNode (location: (220,16)-(220,17)) + │ │ │ │ │ │ ├── flags: decimal + │ │ │ │ │ │ └── value: 1 + │ │ │ │ │ └── operator_loc: ∅ + │ │ │ │ ├── rest: ∅ + │ │ │ │ ├── opening_loc: (220,13)-(220,14) = "{" + │ │ │ │ └── closing_loc: (220,17)-(220,18) = "}" + │ │ │ └── @ HashPatternNode (location: (220,20)-(220,25)) + │ │ │ ├── constant: ∅ + │ │ │ ├── elements: (length: 1) + │ │ │ │ └── @ AssocNode (location: (220,21)-(220,24)) + │ │ │ │ ├── key: + │ │ │ │ │ @ SymbolNode (location: (220,21)-(220,23)) + │ │ │ │ │ ├── flags: forced_us_ascii_encoding + │ │ │ │ │ ├── opening_loc: ∅ + │ │ │ │ │ ├── value_loc: (220,21)-(220,22) = "a" + │ │ │ │ │ ├── closing_loc: (220,22)-(220,23) = ":" + │ │ │ │ │ └── unescaped: "a" + │ │ │ │ ├── value: + │ │ │ │ │ @ IntegerNode (location: (220,23)-(220,24)) + │ │ │ │ │ ├── flags: decimal + │ │ │ │ │ └── value: 2 + │ │ │ │ └── operator_loc: ∅ + │ │ │ ├── rest: ∅ + │ │ │ ├── opening_loc: (220,20)-(220,21) = "{" + │ │ │ └── closing_loc: (220,24)-(220,25) = "}" + │ │ ├── rest: ∅ + │ │ ├── posts: (length: 0) + │ │ ├── opening_loc: (220,12)-(220,13) = "[" + │ │ └── closing_loc: (220,25)-(220,26) = "]" + │ ├── statements: ∅ + │ ├── in_loc: (220,9)-(220,11) = "in" + │ └── then_loc: ∅ + ├── consequent: ∅ + ├── case_keyword_loc: (220,0)-(220,4) = "case" + └── end_keyword_loc: (220,28)-(220,31) = "end" |