[ruby/prism] Move location to second position for node initializers

https://github.com/ruby/prism/commit/4cc0eda4ca
This commit is contained in:
Kevin Newton 2024-07-02 14:27:04 -04:00
Родитель 678dd769e5
Коммит ca48fb76fb
10 изменённых файлов: 364 добавлений и 152 удалений

Просмотреть файл

@ -2,11 +2,13 @@
module Prism module Prism
class DesugarAndWriteNode # :nodoc: 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 @node = node
@source = source @default_source = default_source
@read_class = read_class @read_class = read_class
@write_class = write_class @write_class = write_class
@arguments = arguments @arguments = arguments
@ -14,22 +16,30 @@ module Prism
# Desugar `x &&= y` to `x && x = y` # Desugar `x &&= y` to `x && x = y`
def compile def compile
AndNode.new( and_node(
source, location: node.location,
read_class.new(source, *arguments, node.name_loc), left: public_send(read_class, location: node.name_loc, **arguments),
write_class.new(source, *arguments, node.name_loc, node.value, node.operator_loc, node.location), right: public_send(
node.operator_loc, write_class,
node.location location: node.location,
**arguments,
name_loc: node.name_loc,
value: node.value,
operator_loc: node.operator_loc
),
operator_loc: node.operator_loc
) )
end end
end end
class DesugarOrWriteDefinedNode # :nodoc: class DesugarOrWriteDefinedNode # :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 @node = node
@source = source @default_source = default_source
@read_class = read_class @read_class = read_class
@write_class = write_class @write_class = write_class
@arguments = arguments @arguments = arguments
@ -37,35 +47,50 @@ module Prism
# Desugar `x ||= y` to `defined?(x) ? x : x = y` # Desugar `x ||= y` to `defined?(x) ? x : x = y`
def compile def compile
IfNode.new( if_node(
source, location: node.location,
node.operator_loc, if_keyword_loc: node.operator_loc,
DefinedNode.new(source, nil, read_class.new(source, *arguments, node.name_loc), nil, node.operator_loc, node.name_loc), predicate: defined_node(
node.operator_loc, location: node.name_loc,
StatementsNode.new(source, [read_class.new(source, *arguments, node.name_loc)], node.location), value: public_send(read_class, location: node.name_loc, **arguments),
ElseNode.new( keyword_loc: node.operator_loc
source,
node.operator_loc,
StatementsNode.new(
source,
[write_class.new(source, *arguments, node.name_loc, node.value, node.operator_loc, node.location)],
node.location
), ),
node.operator_loc, then_keyword_loc: node.operator_loc,
node.location statements: statements_node(
location: node.location,
body: [public_send(read_class, location: node.name_loc, **arguments)]
), ),
node.operator_loc, consequent: else_node(
node.location 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
)
]
),
end_keyword_loc: node.operator_loc
),
end_keyword_loc: node.operator_loc
) )
end end
end end
class DesugarOperatorWriteNode # :nodoc: 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 @node = node
@source = source @default_source = default_source
@read_class = read_class @read_class = read_class
@write_class = write_class @write_class = write_class
@arguments = arguments @arguments = arguments
@ -75,35 +100,41 @@ module Prism
def compile def compile
binary_operator_loc = node.binary_operator_loc.chop binary_operator_loc = node.binary_operator_loc.chop
write_class.new( public_send(
source, write_class,
*arguments, location: node.location,
node.name_loc, **arguments,
CallNode.new( name_loc: node.name_loc,
source, value: call_node(
0, location: node.location,
read_class.new(source, *arguments, node.name_loc), receiver: public_send(
nil, read_class,
binary_operator_loc.slice.to_sym, location: node.name_loc,
binary_operator_loc, **arguments
nil,
ArgumentsNode.new(source, 0, [node.value], node.value.location),
nil,
nil,
node.location
), ),
node.binary_operator_loc.copy(start_offset: node.binary_operator_loc.end_offset - 1, length: 1), name: binary_operator_loc.slice.to_sym,
node.location message_loc: binary_operator_loc,
arguments: arguments_node(
location: node.value.location,
arguments: [node.value]
)
),
operator_loc: node.binary_operator_loc.copy(
start_offset: node.binary_operator_loc.end_offset - 1,
length: 1
)
) )
end end
end end
class DesugarOrWriteNode # :nodoc: 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 @node = node
@source = source @default_source = default_source
@read_class = read_class @read_class = read_class
@write_class = write_class @write_class = write_class
@arguments = arguments @arguments = arguments
@ -111,12 +142,18 @@ module Prism
# Desugar `x ||= y` to `x || x = y` # Desugar `x ||= y` to `x || x = y`
def compile def compile
OrNode.new( or_node(
source, location: node.location,
read_class.new(source, *arguments, node.name_loc), left: public_send(read_class, location: node.name_loc, **arguments),
write_class.new(source, *arguments, node.name_loc, node.value, node.operator_loc, node.location), right: public_send(
node.operator_loc, write_class,
node.location location: node.location,
**arguments,
name_loc: node.name_loc,
value: node.value,
operator_loc: node.operator_loc
),
operator_loc: node.operator_loc
) )
end end
end end
@ -125,91 +162,91 @@ module Prism
class ClassVariableAndWriteNode class ClassVariableAndWriteNode
def desugar # :nodoc: 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
end end
class ClassVariableOrWriteNode class ClassVariableOrWriteNode
def desugar # :nodoc: 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
end end
class ClassVariableOperatorWriteNode class ClassVariableOperatorWriteNode
def desugar # :nodoc: 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
end end
class ConstantAndWriteNode class ConstantAndWriteNode
def desugar # :nodoc: 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
end end
class ConstantOrWriteNode class ConstantOrWriteNode
def desugar # :nodoc: 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
end end
class ConstantOperatorWriteNode class ConstantOperatorWriteNode
def desugar # :nodoc: 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
end end
class GlobalVariableAndWriteNode class GlobalVariableAndWriteNode
def desugar # :nodoc: 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
end end
class GlobalVariableOrWriteNode class GlobalVariableOrWriteNode
def desugar # :nodoc: 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
end end
class GlobalVariableOperatorWriteNode class GlobalVariableOperatorWriteNode
def desugar # :nodoc: 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
end end
class InstanceVariableAndWriteNode class InstanceVariableAndWriteNode
def desugar # :nodoc: 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
end end
class InstanceVariableOrWriteNode class InstanceVariableOrWriteNode
def desugar # :nodoc: 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
end end
class InstanceVariableOperatorWriteNode class InstanceVariableOperatorWriteNode
def desugar # :nodoc: 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
end end
class LocalVariableAndWriteNode class LocalVariableAndWriteNode
def desugar # :nodoc: 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
end end
class LocalVariableOrWriteNode class LocalVariableOrWriteNode
def desugar # :nodoc: 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
end end
class LocalVariableOperatorWriteNode class LocalVariableOperatorWriteNode
def desugar # :nodoc: 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
end end

Просмотреть файл

@ -69,11 +69,11 @@ module Prism
def to_interpolated def to_interpolated
InterpolatedStringNode.new( InterpolatedStringNode.new(
source, source,
location,
frozen? ? InterpolatedStringNodeFlags::FROZEN : 0, frozen? ? InterpolatedStringNodeFlags::FROZEN : 0,
opening_loc, opening_loc,
[copy(opening_loc: nil, closing_loc: nil, location: content_loc)], [copy(location: content_loc, opening_loc: nil, closing_loc: nil)],
closing_loc, closing_loc
location
) )
end end
end end
@ -86,10 +86,10 @@ module Prism
def to_interpolated def to_interpolated
InterpolatedXStringNode.new( InterpolatedXStringNode.new(
source, source,
location,
opening_loc, opening_loc,
[StringNode.new(source, 0, nil, content_loc, nil, unescaped, content_loc)], [StringNode.new(source, content_loc, 0, nil, content_loc, nil, unescaped)],
closing_loc, closing_loc
location
) )
end end
end end
@ -115,9 +115,9 @@ module Prism
deprecated("value", "numerator", "denominator") deprecated("value", "numerator", "denominator")
if denominator == 1 if denominator == 1
IntegerNode.new(source, flags, numerator, location.chop) IntegerNode.new(source, location.chop, flags, numerator)
else else
FloatNode.new(source, numerator.to_f / denominator, location.chop) FloatNode.new(source, location.chop, numerator.to_f / denominator)
end end
end end
end end
@ -195,7 +195,7 @@ module Prism
# continue to supply that API. # continue to supply that API.
def child def child
deprecated("name", "name_loc") 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
end end
@ -231,7 +231,7 @@ module Prism
# continue to supply that API. # continue to supply that API.
def child def child
deprecated("name", "name_loc") 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
end end

Просмотреть файл

@ -10,7 +10,11 @@ module Prism
# specialized and more performant `ASCIISource` if no multibyte characters # specialized and more performant `ASCIISource` if no multibyte characters
# are present in the source code. # are present in the source code.
def self.for(source, start_line = 1, offsets = []) 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 end
# The source code that this source object represents. # The source code that this source object represents.
@ -87,7 +91,12 @@ module Prism
# encodings, it is not captured here. # encodings, it is not captured here.
def code_units_offset(byte_offset, encoding) def code_units_offset(byte_offset, encoding)
byteslice = (source.byteslice(0, byte_offset) or raise).encode(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 end
# Returns the column number in code units for the given encoding for the # Returns the column number in code units for the given encoding for the

Просмотреть файл

@ -4,13 +4,18 @@ require "stringio"
module Prism module Prism
class ParseResult < Result 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 class Errors
# The parse result that contains the errors.
attr_reader :parse_result attr_reader :parse_result
# Initialize a new set of errors from the given parse result.
def initialize(parse_result) def initialize(parse_result)
@parse_result = parse_result @parse_result = parse_result
end end
# Formats the errors in a human-readable way and return them as a string.
def format def format
error_lines = {} error_lines = {}
parse_result.errors.each do |error| parse_result.errors.each do |error|

Просмотреть файл

@ -177,7 +177,10 @@ pm_ast_new(const pm_parser_t *parser, const pm_node_t *node, rb_encoding *encodi
// source // source
argv[0] = 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 %> // <%= field.name %>
<%- case field -%> <%- case field -%>
@ -232,9 +235,6 @@ pm_ast_new(const pm_parser_t *parser, const pm_node_t *node, rb_encoding *encodi
<%- end -%> <%- end -%>
<%- 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 %>)); rb_ary_push(value_stack, rb_class_new_instance(<%= node.fields.length + 2 %>, argv, rb_cPrism<%= node.name %>));
break; break;
} }

Просмотреть файл

@ -5,45 +5,118 @@ module Prism
# source = Prism::Source.for("[1]") # source = Prism::Source.for("[1]")
# #
# Prism::ArrayNode.new( # Prism::ArrayNode.new(
# source,
# Prism::Location.new(source, 0, 3),
# 0,
# [ # [
# Prism::IntegerNode.new( # Prism::IntegerNode.new(
# Prism::IntegerBaseFlags::DECIMAL, # source,
# 1,
# Prism::Location.new(source, 1, 1), # Prism::Location.new(source, 1, 1),
# source # Prism::IntegerBaseFlags::DECIMAL,
# 1
# ) # )
# ], # ],
# Prism::Location.new(source, 0, 1), # Prism::Location.new(source, 0, 1),
# Prism::Location.new(source, 2, 1), # Prism::Location.new(source, 2, 1)
# source
# ) # )
# #
# you could instead write: # you could instead write:
# #
# source = Prism::Source.for("[1]") # class Builder
# include Prism::DSL
# #
# ArrayNode( # attr_reader :default_source
# IntegerNode(Prism::IntegerBaseFlags::DECIMAL, 1, Location(source, 1, 1)), source), #
# Location(source, 0, 1), # def initialize
# Location(source, 2, 1), # @default_source = source("[1]")
# source # end
#
# 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 writing tests, but can also be used # This is mostly helpful in the context of generating trees programmatically.
# to generate trees programmatically.
module DSL 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 # Create a new Source object.
def Location(source = nil, start_offset = 0, length = 0) def source(string)
Location.new(source, start_offset, length) # steep:ignore 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 end
<%- nodes.each do |node| -%> <%- nodes.each do |node| -%>
# Create a new <%= node.name %> node # Create a new <%= node.name %> node.
def <%= node.name %>(<%= (node.fields.map(&:name) + ["source = nil, location = Location()"]).join(", ") %>) def <%= node.human %>(<%= ["source: default_source", "location: default_location", *node.fields.map { |field|
<%= node.name %>.new(<%= ["source", *node.fields.map(&:name), "location"].join(", ") %>) 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
<%- 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
end end

Просмотреть файл

@ -166,8 +166,8 @@ module Prism
#<%= line %> #<%= line %>
<%- end -%> <%- end -%>
class <%= node.name -%> < Node class <%= node.name -%> < Node
# def initialize: (<%= (node.fields.map { |field| "#{field.rbs_class} #{field.name}" } + ["Location location"]).join(", ") %>) -> void # Initialize a new <%= node.name %> node.
def initialize(source, <%= (node.fields.map(&:name) + ["location"]).join(", ") %>) def initialize(<%= ["source", "location", *node.fields.map(&:name)].join(", ") %>)
@source = source @source = source
@location = location @location = location
<%- node.fields.each do |field| -%> <%- node.fields.each do |field| -%>
@ -228,9 +228,9 @@ module Prism
}.compact.join(", ") %>] #: Array[Prism::node | Location] }.compact.join(", ") %>] #: Array[Prism::node | Location]
end end
# def copy: (<%= (node.fields.map { |field| "?#{field.name}: #{field.rbs_class}" } + ["?location: Location"]).join(", ") %>) -> <%= node.name %> # def copy: (<%= (["?location: Location"] + node.fields.map { |field| "?#{field.name}: #{field.rbs_class}" }).join(", ") %>) -> <%= node.name %>
def copy(<%= (node.fields.map(&:name) + ["location"]).map { |field| "#{field}: self.#{field}" }.join(", ") %>) def copy(<%= (["location"] + node.fields.map(&:name)).map { |field| "#{field}: self.#{field}" }.join(", ") %>)
<%= node.name %>.new(<%= ["source", *node.fields.map(&:name), "location"].join(", ") %>) <%= node.name %>.new(<%= ["source", "location", *node.fields.map(&:name)].join(", ") %>)
end end
# def deconstruct: () -> Array[nil | Node] # def deconstruct: () -> Array[nil | Node]

Просмотреть файл

@ -319,7 +319,7 @@ module Prism
end end
end end
if RUBY_ENGINE == 'ruby' if RUBY_ENGINE == "ruby"
def load_node def load_node
type = io.getbyte type = io.getbyte
location = load_location location = load_location
@ -330,8 +330,7 @@ module Prism
<%- if node.needs_serialized_length? -%> <%- if node.needs_serialized_length? -%>
load_uint32 load_uint32
<%- end -%> <%- end -%>
<%= node.name %>.new( <%= node.name %>.new(<%= ["source", "location", *node.fields.map { |field|
source, <%= (node.fields.map { |field|
case field case field
when Prism::Template::NodeField then "load_node" when Prism::Template::NodeField then "load_node"
when Prism::Template::OptionalNodeField then "load_optional_node" when Prism::Template::OptionalNodeField then "load_optional_node"
@ -348,7 +347,7 @@ module Prism
when Prism::Template::DoubleField then "load_double" when Prism::Template::DoubleField then "load_double"
else raise else raise
end end
} + ["location"]).join(", ") -%>) }].join(", ") -%>)
<%- end -%> <%- end -%>
end end
end end
@ -367,8 +366,7 @@ module Prism
<%- if node.needs_serialized_length? -%> <%- if node.needs_serialized_length? -%>
load_uint32 load_uint32
<%- end -%> <%- end -%>
<%= node.name %>.new( <%= node.name %>.new(<%= ["source", "location", *node.fields.map { |field|
source, <%= (node.fields.map { |field|
case field case field
when Prism::Template::NodeField then "load_node" when Prism::Template::NodeField then "load_node"
when Prism::Template::OptionalNodeField then "load_optional_node" when Prism::Template::OptionalNodeField then "load_optional_node"
@ -385,7 +383,7 @@ module Prism
when Prism::Template::DoubleField then "load_double" when Prism::Template::DoubleField then "load_double"
else raise else raise
end end
} + ["location"]).join(", ") -%>) }].join(", ") -%>)
}, },
<%- end -%> <%- end -%>
] ]

Просмотреть файл

@ -1,2 +1,4 @@
<<~FOO.foo <<~FOO.foo
^~~ unterminated heredoc; can't find string "FOO" anywhere before EOF ^~~ unterminated heredoc; can't find string "FOO" anywhere before EOF
^~~ unterminated heredoc; can't find string "FOO" anywhere before EOF

Просмотреть файл

@ -1,8 +1,8 @@
@ ProgramNode (location: (1,0)-(217,5)) @ ProgramNode (location: (1,0)-(220,31))
├── locals: [:bar, :baz, :qux, :b, :a, :foo, :x] ├── locals: [:bar, :baz, :qux, :b, :a, :foo, :x, :_a]
└── statements: └── statements:
@ StatementsNode (location: (1,0)-(217,5)) @ StatementsNode (location: (1,0)-(220,31))
└── body: (length: 180) └── body: (length: 182)
├── @ MatchRequiredNode (location: (1,0)-(1,10)) ├── @ MatchRequiredNode (location: (1,0)-(1,10))
│ ├── value: │ ├── value:
│ │ @ CallNode (location: (1,0)-(1,3)) │ │ @ CallNode (location: (1,0)-(1,3))
@ -4883,27 +4883,115 @@
│ │ └── operator_loc: (212,11)-(212,13) = "in" │ │ └── operator_loc: (212,11)-(212,13) = "in"
│ ├── opening_loc: (212,7)-(212,8) = "{" │ ├── opening_loc: (212,7)-(212,8) = "{"
│ └── closing_loc: (212,18)-(212,19) = "}" │ └── closing_loc: (212,18)-(212,19) = "}"
└── @ MultiWriteNode (location: (214,0)-(217,5)) ├── @ MultiWriteNode (location: (214,0)-(217,5))
├── lefts: (length: 2) │ ├── lefts: (length: 2)
│ ├── @ LocalVariableTargetNode (location: (215,2)-(215,3)) │ │ ├── @ LocalVariableTargetNode (location: (215,2)-(215,3))
│ │ ├── name: :a │ │ │ ├── name: :a
│ │ │ └── depth: 0
│ │ └── @ LocalVariableTargetNode (location: (216,2)-(216,3))
│ │ ├── name: :b
│ │ └── depth: 0 │ │ └── depth: 0
│ └── @ LocalVariableTargetNode (location: (216,2)-(216,3)) │ ├── rest: ∅
│ ├── name: :b │ ├── rights: (length: 0)
│ └── depth: 0 │ ├── lparen_loc: (214,0)-(214,1) = "("
├── rest: ∅ │ ├── rparen_loc: (217,0)-(217,1) = ")"
├── rights: (length: 0) │ ├── operator_loc: (217,2)-(217,3) = "="
├── lparen_loc: (214,0)-(214,1) = "(" │ └── value:
├── rparen_loc: (217,0)-(217,1) = ")" │ @ CallNode (location: (217,4)-(217,5))
├── operator_loc: (217,2)-(217,3) = "=" │ ├── flags: variable_call, ignore_visibility
└── value: │ ├── receiver: ∅
@ CallNode (location: (217,4)-(217,5)) │ ├── call_operator_loc: ∅
├── flags: variable_call, ignore_visibility │ ├── name: :c
├── receiver: ∅ │ ├── message_loc: (217,4)-(217,5) = "c"
├── call_operator_loc: ∅ │ ├── opening_loc: ∅
├── name: :c │ ├── arguments: ∅
├── message_loc: (217,4)-(217,5) = "c" │ ├── closing_loc: ∅
├── opening_loc: ∅ │ └── block: ∅
├── arguments: ∅ ├── @ CaseMatchNode (location: (219,0)-(219,25))
├── closing_loc: ∅ │ ├── predicate:
└── block: ∅ │ │ @ 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"