зеркало из https://github.com/github/ruby.git
[ruby/prism] Move location to second position for node initializers
https://github.com/ruby/prism/commit/4cc0eda4ca
This commit is contained in:
Родитель
678dd769e5
Коммит
ca48fb76fb
|
@ -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"
|
||||||
|
|
Загрузка…
Ссылка в новой задаче