This commit is contained in:
Takashi Kokubun 2023-08-15 10:00:54 -07:00
Родитель 957cd369fa
Коммит 3873b1eb39
437 изменённых файлов: 9116 добавлений и 6733 удалений

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

@ -7,7 +7,7 @@ module YARP
class Source
attr_reader :source, :offsets
def initialize(source, offsets)
def initialize(source, offsets = compute_offsets(source))
@source = source
@offsets = offsets
end
@ -23,6 +23,14 @@ module YARP
def column(value)
value - offsets[line(value) - 1]
end
private
def compute_offsets(code)
offsets = [0]
code.b.scan("\n") { offsets << $~.end(0) }
offsets
end
end
# This represents a location in the source.
@ -101,6 +109,8 @@ module YARP
# This represents a comment that was encountered during parsing.
class Comment
TYPES = [:inline, :embdoc, :__END__]
attr_reader :type, :location
def initialize(type, location)
@ -141,6 +151,27 @@ module YARP
end
end
# A class that knows how to walk down the tree. None of the individual visit
# methods are implemented on this visitor, so it forces the consumer to
# implement each one that they need. For a default implementation that
# continues walking the tree, see the Visitor class.
class BasicVisitor
def visit(node)
node&.accept(self)
end
def visit_all(nodes)
nodes.map { |node| visit(node) }
end
def visit_child_nodes(node)
visit_all(node.child_nodes)
end
end
class Visitor < BasicVisitor
end
# This represents the result of a call to ::parse or ::parse_file. It contains
# the AST, any comments that were encounters, and any errors that were
# encountered.
@ -166,6 +197,45 @@ module YARP
def failure?
!success?
end
# Keep in sync with Java MarkNewlinesVisitor
class MarkNewlinesVisitor < YARP::Visitor
def initialize(newline_marked)
@newline_marked = newline_marked
end
def visit_block_node(node)
old_newline_marked = @newline_marked
@newline_marked = Array.new(old_newline_marked.size, false)
begin
super(node)
ensure
@newline_marked = old_newline_marked
end
end
alias_method :visit_lambda_node, :visit_block_node
def visit_if_node(node)
node.set_newline_flag(@newline_marked)
super(node)
end
alias_method :visit_unless_node, :visit_if_node
def visit_statements_node(node)
node.body.each do |child|
child.set_newline_flag(@newline_marked)
end
super(node)
end
end
private_constant :MarkNewlinesVisitor
def mark_newlines
newline_marked = Array.new(1 + @source.offsets.size, false)
visitor = MarkNewlinesVisitor.new(newline_marked)
value.accept(visitor)
value
end
end
# This represents a token from the Ruby source.
@ -207,10 +277,28 @@ module YARP
class Node
attr_reader :location
def newline?
@newline ? true : false
end
def set_newline_flag(newline_marked)
line = location.start_line
unless newline_marked[line]
newline_marked[line] = true
@newline = true
end
end
# Slice the location of the node from the source.
def slice
location.slice
end
def pretty_print(q)
q.group do
q.text(self.class.name.split("::").last)
location.pretty_print(q)
q.text("[Li:#{location.start_line}]") if newline?
q.text("(")
q.nest(2) do
deconstructed = deconstruct_keys([])
@ -233,9 +321,153 @@ module YARP
# This module is used for testing and debugging and is not meant to be used by
# consumers of this library.
module Debug
class ISeq
attr_reader :parts
def initialize(parts)
@parts = parts
end
def type
parts[0]
end
def local_table
parts[10]
end
def instructions
parts[13]
end
def each_child
instructions.each do |instruction|
# Only look at arrays. Other instructions are line numbers or
# tracepoint events.
next unless instruction.is_a?(Array)
instruction.each do |opnd|
# Only look at arrays. Other operands are literals.
next unless opnd.is_a?(Array)
# Only look at instruction sequences. Other operands are literals.
next unless opnd[0] == "YARVInstructionSequence/SimpleDataFormat"
yield ISeq.new(opnd)
end
end
end
end
# For the given source, compiles with CRuby and returns a list of all of the
# sets of local variables that were encountered.
def self.cruby_locals(source)
verbose = $VERBOSE
$VERBOSE = nil
begin
locals = []
stack = [ISeq.new(RubyVM::InstructionSequence.compile(source).to_a)]
while (iseq = stack.pop)
if iseq.type != :once
names = iseq.local_table
# CRuby will push on a special local variable when there are keyword
# arguments. We get rid of that here.
names = names.grep_v(Integer)
# TODO: We don't support numbered local variables yet, so we get rid
# of those here.
names = names.grep_v(/^_\d$/)
# Now push them onto the list of locals.
locals << names
end
iseq.each_child { |child| stack << child }
end
locals
ensure
$VERBOSE = verbose
end
end
# For the given source, parses with YARP and returns a list of all of the
# sets of local variables that were encountered.
def self.yarp_locals(source)
locals = []
stack = [YARP.parse(source).value]
while (node = stack.pop)
case node
when BlockNode, DefNode, LambdaNode
names = node.locals
params = node.parameters
params = params&.parameters unless node.is_a?(DefNode)
# YARP places parameters in the same order that they appear in the
# source. CRuby places them in the order that they need to appear
# according to their own internal calling convention. We mimic that
# order here so that we can compare properly.
if params
sorted = [
*params.requireds.grep(RequiredParameterNode).map(&:constant_id),
*params.optionals.map(&:constant_id),
*((params.rest.name ? params.rest.name.to_sym : :*) if params.rest && params.rest.operator != ","),
*params.posts.grep(RequiredParameterNode).map(&:constant_id),
*params.keywords.reject(&:value).map { |param| param.name.chomp(":").to_sym },
*params.keywords.select(&:value).map { |param| param.name.chomp(":").to_sym }
]
# TODO: When we get a ... parameter, we should be pushing * and &
# onto the local list. We don't do that yet, so we need to add them
# in here.
if params.keyword_rest.is_a?(ForwardingParameterNode)
sorted.push(:*, :&, :"...")
end
# Recurse down the parameter tree to find any destructured
# parameters and add them after the other parameters.
param_stack = params.requireds.concat(params.posts).grep(RequiredDestructuredParameterNode).reverse
while (param = param_stack.pop)
case param
when RequiredDestructuredParameterNode
param_stack.concat(param.parameters.reverse)
when RequiredParameterNode
sorted << param.constant_id
when SplatNode
sorted << param.expression.constant_id if param.expression
end
end
names = sorted.concat(names - sorted)
end
locals << names
when ClassNode, ModuleNode, ProgramNode, SingletonClassNode
locals << node.locals
when ForNode
locals << []
when PostExecutionNode
locals.push([], [])
end
stack.concat(node.child_nodes.compact)
end
locals
end
def self.newlines(source)
YARP.parse(source).source.offsets
end
def self.parse_serialize_file(filepath)
parse_serialize_file_metadata(filepath, [filepath.bytesize, filepath.b, 0].pack("LA*L"))
end
end
# Marking this as private so that consumers don't see it. It makes it a little
@ -250,4 +482,8 @@ require_relative "yarp/ripper_compat"
require_relative "yarp/serialize"
require_relative "yarp/pack"
require "yarp/yarp"
if RUBY_ENGINE == "ruby" and !ENV["YARP_FFI_BACKEND"]
require "yarp/yarp"
else
require "yarp/ffi"
end

211
lib/yarp/ffi.rb Normal file
Просмотреть файл

@ -0,0 +1,211 @@
# frozen_string_literal: true
# This file is responsible for mirroring the API provided by the C extension by
# using FFI to call into the shared library.
require "rbconfig"
require "ffi"
module YARP
BACKEND = :FFI
module LibRubyParser
extend FFI::Library
# Define the library that we will be pulling functions from. Note that this
# must align with the build shared library from make/rake.
ffi_lib File.expand_path("../../build/librubyparser.#{RbConfig::CONFIG["SOEXT"]}", __dir__)
# Convert a native C type declaration into a symbol that FFI understands.
# For example:
#
# const char * -> :pointer
# bool -> :bool
# size_t -> :size_t
# void -> :void
#
def self.resolve_type(type)
type = type.strip.delete_prefix("const ")
type.end_with?("*") ? :pointer : type.to_sym
end
# Read through the given header file and find the declaration of each of the
# given functions. For each one, define a function with the same name and
# signature as the C function.
def self.load_exported_functions_from(header, *functions)
File.foreach(File.expand_path("../../include/#{header}", __dir__)) do |line|
# We only want to attempt to load exported functions.
next unless line.start_with?("YP_EXPORTED_FUNCTION ")
# We only want to load the functions that we are interested in.
next unless functions.any? { |function| line.include?(function) }
# Parse the function declaration.
unless /^YP_EXPORTED_FUNCTION (?<return_type>.+) (?<name>\w+)\((?<arg_types>.+)\);$/ =~ line
raise "Could not parse #{line}"
end
# Delete the function from the list of functions we are looking for to
# mark it as having been found.
functions.delete(name)
# Split up the argument types into an array, ensure we handle the case
# where there are no arguments (by explicit void).
arg_types = arg_types.split(",").map(&:strip)
arg_types = [] if arg_types == %w[void]
# Resolve the type of the argument by dropping the name of the argument
# first if it is present.
arg_types.map! { |type| resolve_type(type.sub(/\w+$/, "")) }
# Attach the function using the FFI library.
attach_function name, arg_types, resolve_type(return_type)
end
# If we didn't find all of the functions, raise an error.
raise "Could not find functions #{functions.inspect}" unless functions.empty?
end
load_exported_functions_from(
"yarp.h",
"yp_version",
"yp_parse_serialize",
"yp_lex_serialize"
)
load_exported_functions_from(
"yarp/util/yp_buffer.h",
"yp_buffer_init",
"yp_buffer_free"
)
load_exported_functions_from(
"yarp/util/yp_string.h",
"yp_string_mapped_init",
"yp_string_free",
"yp_string_source",
"yp_string_length",
"yp_string_sizeof"
)
# This object represents a yp_buffer_t. Its structure must be kept in sync
# with the C version.
class YPBuffer < FFI::Struct
layout value: :pointer, length: :size_t, capacity: :size_t
# Read the contents of the buffer into a String object and return it.
def to_ruby_string
self[:value].read_string(self[:length])
end
end
# Initialize a new buffer and yield it to the block. The buffer will be
# automatically freed when the block returns.
def self.with_buffer(&block)
buffer = YPBuffer.new
begin
raise unless yp_buffer_init(buffer)
yield buffer
ensure
yp_buffer_free(buffer)
buffer.pointer.free
end
end
# This object represents a yp_string_t. We only use it as an opaque pointer,
# so it doesn't have to be an FFI::Struct.
class YPString
attr_reader :pointer
def initialize(pointer)
@pointer = pointer
end
def source
LibRubyParser.yp_string_source(pointer)
end
def length
LibRubyParser.yp_string_length(pointer)
end
def read
source.read_string(length)
end
end
# This is the size of a yp_string_t. It is returned by the yp_string_sizeof
# function which we call once to ensure we have sufficient space for the
# yp_string_t FFI pointer.
SIZEOF_YP_STRING = yp_string_sizeof
# Yields a yp_string_t pointer to the given block.
def self.with_string(filepath, &block)
string = FFI::MemoryPointer.new(SIZEOF_YP_STRING)
begin
raise unless yp_string_mapped_init(string, filepath)
yield YPString.new(string)
ensure
yp_string_free(string)
string.free
end
end
end
# Mark the LibRubyParser module as private as it should only be called through
# the YARP module.
private_constant :LibRubyParser
# The version constant is set by reading the result of calling yp_version.
VERSION = LibRubyParser.yp_version.read_string
def self.dump_internal(source, source_size, filepath)
LibRubyParser.with_buffer do |buffer|
metadata = [filepath.bytesize, filepath.b, 0].pack("LA*L") if filepath
LibRubyParser.yp_parse_serialize(source, source_size, buffer, metadata)
buffer.to_ruby_string
end
end
private_class_method :dump_internal
# Mirror the YARP.dump API by using the serialization API.
def self.dump(code, filepath = nil)
dump_internal(code, code.bytesize, filepath)
end
# Mirror the YARP.dump_file API by using the serialization API.
def self.dump_file(filepath)
LibRubyParser.with_string(filepath) do |string|
dump_internal(string.source, string.length, filepath)
end
end
# Mirror the YARP.lex API by using the serialization API.
def self.lex(code, filepath = nil)
LibRubyParser.with_buffer do |buffer|
LibRubyParser.yp_lex_serialize(code, code.bytesize, filepath, buffer)
source = Source.new(code)
Serialize.load_tokens(source, buffer.to_ruby_string)
end
end
# Mirror the YARP.lex_file API by using the serialization API.
def self.lex_file(filepath)
LibRubyParser.with_string(filepath) { |string| lex(string.read, filepath) }
end
# Mirror the YARP.parse API by using the serialization API.
def self.parse(code, filepath = nil)
YARP.load(code, dump(code, filepath))
end
# Mirror the YARP.parse_file API by using the serialization API. This uses
# native strings instead of Ruby strings because it allows us to use mmap when
# it is available.
def self.parse_file(filepath)
LibRubyParser.with_string(filepath) { |string| parse(string.read, filepath) }
end
end

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

@ -166,6 +166,7 @@ module YARP
STRING_END: :on_tstring_end,
SYMBOL_BEGIN: :on_symbeg,
TILDE: :on_op,
UAMPERSAND: :on_op,
UCOLON_COLON: :on_op,
UDOT_DOT: :on_op,
UDOT_DOT_DOT: :on_op,
@ -646,19 +647,34 @@ module YARP
# can shuffle around the token to match Ripper's output.
case state
when :default
# The default state is when there are no heredocs at all. In this
# state we can append the token to the list of tokens and move on.
tokens << token
# If we get the declaration of a heredoc, then we open a new heredoc
# and move into the heredoc_opened state.
if event == :on_heredoc_beg
state = :heredoc_opened
heredoc_stack.last << Heredoc.build(token)
end
when :heredoc_opened
# The heredoc_opened state is when we've seen the declaration of a
# heredoc and are now lexing the body of the heredoc. In this state we
# push tokens onto the most recently created heredoc.
heredoc_stack.last.last << token
case event
when :on_heredoc_beg
# If we receive a heredoc declaration while lexing the body of a
# heredoc, this means we have nested heredocs. In this case we'll
# push a new heredoc onto the stack and stay in the heredoc_opened
# state since we're now lexing the body of the new heredoc.
heredoc_stack << [Heredoc.build(token)]
when :on_heredoc_end
# If we receive the end of a heredoc, then we're done lexing the
# body of the heredoc. In this case we now have a completed heredoc
# but need to wait for the next newline to push it into the token
# stream.
state = :heredoc_closed
end
when :heredoc_closed
@ -733,8 +749,7 @@ module YARP
when :on_sp
# skip
when :on_tstring_content
if previous[1] == :on_tstring_content &&
(token[2].start_with?("\#$") || token[2].start_with?("\#@"))
if previous[1] == :on_tstring_content && (token[2].start_with?("\#$") || token[2].start_with?("\#@"))
previous[2] << token[2]
else
results << token

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

@ -462,6 +462,10 @@ module YARP
visitor.visit_begin_node(self)
end
def set_newline_flag(newline_marked)
# Never mark BeginNode with a newline flag, mark children instead
end
# def child_nodes: () -> Array[nil | Node]
def child_nodes
[statements, rescue_clause, else_clause, ensure_clause]
@ -834,6 +838,16 @@ module YARP
def closing
closing_loc&.slice
end
# def safe_navigation?: () -> bool
def safe_navigation?
flags.anybits?(CallNodeFlags::SAFE_NAVIGATION)
end
# def variable_call?: () -> bool
def variable_call?
flags.anybits?(CallNodeFlags::VARIABLE_CALL)
end
end
# Represents the use of the `&&=` operator on a call.
@ -1724,13 +1738,16 @@ module YARP
end
end
# Represents writing to a constant.
# Represents writing to a constant path.
#
# Foo = 1
# ^^^^^^^
# ::Foo = 1
# ^^^^^^^^^
#
# Foo::Bar = 1
# ^^^^^^^^^^^^
#
# ::Foo::Bar = 1
# ^^^^^^^^^^^^^^
class ConstantPathWriteNode < Node
# attr_reader target: Node
attr_reader :target
@ -1802,6 +1819,57 @@ module YARP
end
end
# Represents writing to a constant.
#
# Foo = 1
# ^^^^^^^
class ConstantWriteNode < Node
# attr_reader name_loc: Location
attr_reader :name_loc
# attr_reader value: Node?
attr_reader :value
# attr_reader operator_loc: Location?
attr_reader :operator_loc
# def initialize: (name_loc: Location, value: Node?, operator_loc: Location?, location: Location) -> void
def initialize(name_loc, value, operator_loc, location)
@name_loc = name_loc
@value = value
@operator_loc = operator_loc
@location = location
end
# def accept: (visitor: Visitor) -> void
def accept(visitor)
visitor.visit_constant_write_node(self)
end
# def child_nodes: () -> Array[nil | Node]
def child_nodes
[value]
end
# def deconstruct: () -> Array[nil | Node]
alias deconstruct child_nodes
# def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
def deconstruct_keys(keys)
{ name_loc: name_loc, value: value, operator_loc: operator_loc, location: location }
end
# def name: () -> String
def name
name_loc.slice
end
# def operator: () -> String?
def operator
operator_loc&.slice
end
end
# Represents a method definition.
#
# def method
@ -2268,6 +2336,61 @@ module YARP
end
end
# Represents the use of the `..` or `...` operators to create flip flops.
#
# baz if foo .. bar
# ^^^^^^^^^^
class FlipFlopNode < Node
# attr_reader left: Node?
attr_reader :left
# attr_reader right: Node?
attr_reader :right
# attr_reader operator_loc: Location
attr_reader :operator_loc
# attr_reader flags: Integer
attr_reader :flags
# def initialize: (left: Node?, right: Node?, operator_loc: Location, flags: Integer, location: Location) -> void
def initialize(left, right, operator_loc, flags, location)
@left = left
@right = right
@operator_loc = operator_loc
@flags = flags
@location = location
end
# def accept: (visitor: Visitor) -> void
def accept(visitor)
visitor.visit_flip_flop_node(self)
end
# def child_nodes: () -> Array[nil | Node]
def child_nodes
[left, right]
end
# def deconstruct: () -> Array[nil | Node]
alias deconstruct child_nodes
# def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
def deconstruct_keys(keys)
{ left: left, right: right, operator_loc: operator_loc, flags: flags, location: location }
end
# def operator: () -> String
def operator
operator_loc.slice
end
# def exclude_end?: () -> bool
def exclude_end?
flags.anybits?(RangeFlags::EXCLUDE_END)
end
end
# Represents a floating point number literal.
#
# 1.0
@ -2851,6 +2974,10 @@ module YARP
visitor.visit_if_node(self)
end
def set_newline_flag(newline_marked)
predicate.set_newline_flag(newline_marked)
end
# def child_nodes: () -> Array[nil | Node]
def child_nodes
[predicate, statements, consequent]
@ -3255,6 +3382,11 @@ module YARP
visitor.visit_interpolated_regular_expression_node(self)
end
def set_newline_flag(newline_marked)
first = parts.first
first.set_newline_flag(newline_marked) if first
end
# def child_nodes: () -> Array[nil | Node]
def child_nodes
[*parts]
@ -3277,6 +3409,46 @@ module YARP
def closing
closing_loc.slice
end
# def ignore_case?: () -> bool
def ignore_case?
flags.anybits?(RegularExpressionFlags::IGNORE_CASE)
end
# def multi_line?: () -> bool
def multi_line?
flags.anybits?(RegularExpressionFlags::MULTI_LINE)
end
# def extended?: () -> bool
def extended?
flags.anybits?(RegularExpressionFlags::EXTENDED)
end
# def euc_jp?: () -> bool
def euc_jp?
flags.anybits?(RegularExpressionFlags::EUC_JP)
end
# def ascii_8bit?: () -> bool
def ascii_8bit?
flags.anybits?(RegularExpressionFlags::ASCII_8BIT)
end
# def windows_31j?: () -> bool
def windows_31j?
flags.anybits?(RegularExpressionFlags::WINDOWS_31J)
end
# def utf_8?: () -> bool
def utf_8?
flags.anybits?(RegularExpressionFlags::UTF_8)
end
# def once?: () -> bool
def once?
flags.anybits?(RegularExpressionFlags::ONCE)
end
end
# Represents a string literal that contains interpolation.
@ -3306,6 +3478,11 @@ module YARP
visitor.visit_interpolated_string_node(self)
end
def set_newline_flag(newline_marked)
first = parts.first
first.set_newline_flag(newline_marked) if first
end
# def child_nodes: () -> Array[nil | Node]
def child_nodes
[*parts]
@ -3357,6 +3534,11 @@ module YARP
visitor.visit_interpolated_symbol_node(self)
end
def set_newline_flag(newline_marked)
first = parts.first
first.set_newline_flag(newline_marked) if first
end
# def child_nodes: () -> Array[nil | Node]
def child_nodes
[*parts]
@ -3408,6 +3590,11 @@ module YARP
visitor.visit_interpolated_x_string_node(self)
end
def set_newline_flag(newline_marked)
first = parts.first
first.set_newline_flag(newline_marked) if first
end
# def child_nodes: () -> Array[nil | Node]
def child_nodes
[*parts]
@ -4454,6 +4641,10 @@ module YARP
visitor.visit_parentheses_node(self)
end
def set_newline_flag(newline_marked)
# Never mark ParenthesesNode with a newline flag, mark children instead
end
# def child_nodes: () -> Array[nil | Node]
def child_nodes
[statements]
@ -4787,6 +4978,11 @@ module YARP
def operator
operator_loc.slice
end
# def exclude_end?: () -> bool
def exclude_end?
flags.anybits?(RangeFlags::EXCLUDE_END)
end
end
# Represents a rational number literal.
@ -4913,6 +5109,46 @@ module YARP
def closing
closing_loc.slice
end
# def ignore_case?: () -> bool
def ignore_case?
flags.anybits?(RegularExpressionFlags::IGNORE_CASE)
end
# def multi_line?: () -> bool
def multi_line?
flags.anybits?(RegularExpressionFlags::MULTI_LINE)
end
# def extended?: () -> bool
def extended?
flags.anybits?(RegularExpressionFlags::EXTENDED)
end
# def euc_jp?: () -> bool
def euc_jp?
flags.anybits?(RegularExpressionFlags::EUC_JP)
end
# def ascii_8bit?: () -> bool
def ascii_8bit?
flags.anybits?(RegularExpressionFlags::ASCII_8BIT)
end
# def windows_31j?: () -> bool
def windows_31j?
flags.anybits?(RegularExpressionFlags::WINDOWS_31J)
end
# def utf_8?: () -> bool
def utf_8?
flags.anybits?(RegularExpressionFlags::UTF_8)
end
# def once?: () -> bool
def once?
flags.anybits?(RegularExpressionFlags::ONCE)
end
end
# Represents a destructured required parameter node.
@ -5028,6 +5264,10 @@ module YARP
visitor.visit_rescue_modifier_node(self)
end
def set_newline_flag(newline_marked)
expression.set_newline_flag(newline_marked)
end
# def child_nodes: () -> Array[nil | Node]
def child_nodes
[expression, rescue_expression]
@ -5067,8 +5307,8 @@ module YARP
# attr_reader operator_loc: Location?
attr_reader :operator_loc
# attr_reader exception: Node?
attr_reader :exception
# attr_reader reference: Node?
attr_reader :reference
# attr_reader statements: Node?
attr_reader :statements
@ -5076,12 +5316,12 @@ module YARP
# attr_reader consequent: Node?
attr_reader :consequent
# def initialize: (keyword_loc: Location, exceptions: Array[Node], operator_loc: Location?, exception: Node?, statements: Node?, consequent: Node?, location: Location) -> void
def initialize(keyword_loc, exceptions, operator_loc, exception, statements, consequent, location)
# def initialize: (keyword_loc: Location, exceptions: Array[Node], operator_loc: Location?, reference: Node?, statements: Node?, consequent: Node?, location: Location) -> void
def initialize(keyword_loc, exceptions, operator_loc, reference, statements, consequent, location)
@keyword_loc = keyword_loc
@exceptions = exceptions
@operator_loc = operator_loc
@exception = exception
@reference = reference
@statements = statements
@consequent = consequent
@location = location
@ -5094,7 +5334,7 @@ module YARP
# def child_nodes: () -> Array[nil | Node]
def child_nodes
[*exceptions, exception, statements, consequent]
[*exceptions, reference, statements, consequent]
end
# def deconstruct: () -> Array[nil | Node]
@ -5102,7 +5342,7 @@ module YARP
# def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
def deconstruct_keys(keys)
{ keyword_loc: keyword_loc, exceptions: exceptions, operator_loc: operator_loc, exception: exception, statements: statements, consequent: consequent, location: location }
{ keyword_loc: keyword_loc, exceptions: exceptions, operator_loc: operator_loc, reference: reference, statements: statements, consequent: consequent, location: location }
end
# def keyword: () -> String
@ -5841,6 +6081,10 @@ module YARP
visitor.visit_unless_node(self)
end
def set_newline_flag(newline_marked)
predicate.set_newline_flag(newline_marked)
end
# def child_nodes: () -> Array[nil | Node]
def child_nodes
[predicate, statements, consequent]
@ -5882,11 +6126,15 @@ module YARP
# attr_reader statements: Node?
attr_reader :statements
# def initialize: (keyword_loc: Location, predicate: Node, statements: Node?, location: Location) -> void
def initialize(keyword_loc, predicate, statements, location)
# attr_reader flags: Integer
attr_reader :flags
# def initialize: (keyword_loc: Location, predicate: Node, statements: Node?, flags: Integer, location: Location) -> void
def initialize(keyword_loc, predicate, statements, flags, location)
@keyword_loc = keyword_loc
@predicate = predicate
@statements = statements
@flags = flags
@location = location
end
@ -5895,6 +6143,10 @@ module YARP
visitor.visit_until_node(self)
end
def set_newline_flag(newline_marked)
predicate.set_newline_flag(newline_marked)
end
# def child_nodes: () -> Array[nil | Node]
def child_nodes
[predicate, statements]
@ -5905,13 +6157,18 @@ module YARP
# def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
def deconstruct_keys(keys)
{ keyword_loc: keyword_loc, predicate: predicate, statements: statements, location: location }
{ keyword_loc: keyword_loc, predicate: predicate, statements: statements, flags: flags, location: location }
end
# def keyword: () -> String
def keyword
keyword_loc.slice
end
# def begin_modifier?: () -> bool
def begin_modifier?
flags.anybits?(LoopFlags::BEGIN_MODIFIER)
end
end
# case true
@ -5977,11 +6234,15 @@ module YARP
# attr_reader statements: Node?
attr_reader :statements
# def initialize: (keyword_loc: Location, predicate: Node, statements: Node?, location: Location) -> void
def initialize(keyword_loc, predicate, statements, location)
# attr_reader flags: Integer
attr_reader :flags
# def initialize: (keyword_loc: Location, predicate: Node, statements: Node?, flags: Integer, location: Location) -> void
def initialize(keyword_loc, predicate, statements, flags, location)
@keyword_loc = keyword_loc
@predicate = predicate
@statements = statements
@flags = flags
@location = location
end
@ -5990,6 +6251,10 @@ module YARP
visitor.visit_while_node(self)
end
def set_newline_flag(newline_marked)
predicate.set_newline_flag(newline_marked)
end
# def child_nodes: () -> Array[nil | Node]
def child_nodes
[predicate, statements]
@ -6000,13 +6265,18 @@ module YARP
# def deconstruct_keys: (keys: Array[Symbol]) -> Hash[Symbol, nil | Node | Array[Node] | String | Token | Array[Token] | Location]
def deconstruct_keys(keys)
{ keyword_loc: keyword_loc, predicate: predicate, statements: statements, location: location }
{ keyword_loc: keyword_loc, predicate: predicate, statements: statements, flags: flags, location: location }
end
# def keyword: () -> String
def keyword
keyword_loc.slice
end
# def begin_modifier?: () -> bool
def begin_modifier?
flags.anybits?(LoopFlags::BEGIN_MODIFIER)
end
end
# Represents an xstring literal with no interpolation.
@ -6132,9 +6402,17 @@ module YARP
module CallNodeFlags
# &. operator
SAFE_NAVIGATION = 1 << 0
# a call that could have been a local variable
VARIABLE_CALL = 1 << 1
end
module RangeNodeFlags
module LoopFlags
# a loop after a begin statement, so the body is executed first before the condition
BEGIN_MODIFIER = 1 << 0
end
module RangeFlags
# ... operator
EXCLUDE_END = 1 << 0
end
@ -6165,24 +6443,6 @@ module YARP
ONCE = 1 << 7
end
# A class that knows how to walk down the tree. None of the individual visit
# methods are implemented on this visitor, so it forces the consumer to
# implement each one that they need. For a default implementation that
# continues walking the tree, see the Visitor class.
class BasicVisitor
def visit(node)
node&.accept(self)
end
def visit_all(nodes)
nodes.map { |node| visit(node) }
end
def visit_child_nodes(node)
visit_all(node.child_nodes)
end
end
class Visitor < BasicVisitor
# Visit a AliasNode node
alias visit_alias_node visit_child_nodes
@ -6292,6 +6552,9 @@ module YARP
# Visit a ConstantReadNode node
alias visit_constant_read_node visit_child_nodes
# Visit a ConstantWriteNode node
alias visit_constant_write_node visit_child_nodes
# Visit a DefNode node
alias visit_def_node visit_child_nodes
@ -6316,6 +6579,9 @@ module YARP
# Visit a FindPatternNode node
alias visit_find_pattern_node visit_child_nodes
# Visit a FlipFlopNode node
alias visit_flip_flop_node visit_child_nodes
# Visit a FloatNode node
alias visit_float_node visit_child_nodes
@ -6751,6 +7017,11 @@ module YARP
ConstantReadNode.new(location)
end
# Create a new ConstantWriteNode node
def ConstantWriteNode(name_loc, value, operator_loc, location = Location())
ConstantWriteNode.new(name_loc, value, operator_loc, location)
end
# Create a new DefNode node
def DefNode(name_loc, receiver, parameters, statements, locals, def_keyword_loc, operator_loc, lparen_loc, rparen_loc, equal_loc, end_keyword_loc, location = Location())
DefNode.new(name_loc, receiver, parameters, statements, locals, def_keyword_loc, operator_loc, lparen_loc, rparen_loc, equal_loc, end_keyword_loc, location)
@ -6791,6 +7062,11 @@ module YARP
FindPatternNode.new(constant, left, requireds, right, opening_loc, closing_loc, location)
end
# Create a new FlipFlopNode node
def FlipFlopNode(left, right, operator_loc, flags, location = Location())
FlipFlopNode.new(left, right, operator_loc, flags, location)
end
# Create a new FloatNode node
def FloatNode(location = Location())
FloatNode.new(location)
@ -7087,8 +7363,8 @@ module YARP
end
# Create a new RescueNode node
def RescueNode(keyword_loc, exceptions, operator_loc, exception, statements, consequent, location = Location())
RescueNode.new(keyword_loc, exceptions, operator_loc, exception, statements, consequent, location)
def RescueNode(keyword_loc, exceptions, operator_loc, reference, statements, consequent, location = Location())
RescueNode.new(keyword_loc, exceptions, operator_loc, reference, statements, consequent, location)
end
# Create a new RestParameterNode node
@ -7177,8 +7453,8 @@ module YARP
end
# Create a new UntilNode node
def UntilNode(keyword_loc, predicate, statements, location = Location())
UntilNode.new(keyword_loc, predicate, statements, location)
def UntilNode(keyword_loc, predicate, statements, flags, location = Location())
UntilNode.new(keyword_loc, predicate, statements, flags, location)
end
# Create a new WhenNode node
@ -7187,8 +7463,8 @@ module YARP
end
# Create a new WhileNode node
def WhileNode(keyword_loc, predicate, statements, location = Location())
WhileNode.new(keyword_loc, predicate, statements, location)
def WhileNode(keyword_loc, predicate, statements, flags, location = Location())
WhileNode.new(keyword_loc, predicate, statements, flags, location)
end
# Create a new XStringNode node

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

@ -7,45 +7,85 @@ if you are looking to modify the template
require "stringio"
# Polyfill for String#unpack1 with the offset parameter.
if String.instance_method(:unpack1).parameters.none? { |_, name| name == :offset }
String.prepend(
Module.new {
def unpack1(format, offset: 0)
offset == 0 ? super(format) : self[offset..].unpack1(format)
end
}
)
end
module YARP
module Serialize
def self.load(input, serialized)
io = StringIO.new(serialized)
io.set_encoding(Encoding::BINARY)
MAJOR_VERSION = 0
MINOR_VERSION = 7
PATCH_VERSION = 0
Loader.new(input, serialized, io).load
def self.load(input, serialized)
Loader.new(Source.new(input), serialized).load
end
def self.load_tokens(source, serialized)
Loader.new(source, serialized).load_tokens
end
class Loader
attr_reader :encoding, :input, :serialized, :io
attr_reader :constant_pool_offset, :constant_pool, :source
def initialize(input, serialized, io)
def initialize(source, serialized)
@encoding = Encoding::UTF_8
@input = input.dup
@input = source.source.dup
@serialized = serialized
@io = io
@io = StringIO.new(serialized)
@io.set_encoding(Encoding::BINARY)
@constant_pool_offset = nil
@constant_pool = nil
offsets = [0]
input.b.scan("\n") { offsets << $~.end(0) }
@source = Source.new(input, offsets)
@source = source
end
def load_tokens
tokens = []
while type = TOKEN_TYPES.fetch(load_varint)
start = load_varint
length = load_varint
lex_state = load_varint
location = Location.new(@source, start, length)
tokens << [YARP::Token.new(type, location.slice, location), lex_state]
end
comments = load_varint.times.map { Comment.new(Comment::TYPES.fetch(load_varint), load_location) }
errors = load_varint.times.map { ParseError.new(load_string, load_location) }
warnings = load_varint.times.map { ParseWarning.new(load_string, load_location) }
raise "Expected to consume all bytes while deserializing" unless @io.eof?
YARP::ParseResult.new(tokens, comments, errors, warnings, @source)
end
def load
io.read(4) => "YARP"
io.read(3).unpack("C3") => [0, 4, 0]
raise "Invalid serialization" if io.read(4) != "YARP"
raise "Invalid serialization" if io.read(3).unpack("C3") != [MAJOR_VERSION, MINOR_VERSION, PATCH_VERSION]
@encoding = Encoding.find(io.read(load_varint))
@input = input.force_encoding(@encoding).freeze
comments = load_varint.times.map { Comment.new(Comment::TYPES.fetch(io.getbyte), load_location) }
errors = load_varint.times.map { ParseError.new(load_string, load_location) }
warnings = load_varint.times.map { ParseWarning.new(load_string, load_location) }
@constant_pool_offset = io.read(4).unpack1("L")
@constant_pool = Array.new(load_varint, nil)
load_node
ast = load_node
YARP::ParseResult.new(ast, comments, errors, warnings, @source)
end
private
@ -184,188 +224,359 @@ module YARP
when 36 then
ConstantReadNode.new(location)
when 37 then
ConstantWriteNode.new(load_location, load_optional_node, load_optional_location, location)
when 38 then
load_serialized_length
DefNode.new(load_location, load_optional_node, load_optional_node, load_optional_node, Array.new(load_varint) { load_constant }, load_location, load_optional_location, load_optional_location, load_optional_location, load_optional_location, load_optional_location, location)
when 38 then
DefinedNode.new(load_optional_location, load_node, load_optional_location, load_location, location)
when 39 then
ElseNode.new(load_location, load_optional_node, load_optional_location, location)
DefinedNode.new(load_optional_location, load_node, load_optional_location, load_location, location)
when 40 then
EmbeddedStatementsNode.new(load_location, load_optional_node, load_location, location)
ElseNode.new(load_location, load_optional_node, load_optional_location, location)
when 41 then
EmbeddedVariableNode.new(load_location, load_node, location)
EmbeddedStatementsNode.new(load_location, load_optional_node, load_location, location)
when 42 then
EnsureNode.new(load_location, load_optional_node, load_location, location)
EmbeddedVariableNode.new(load_location, load_node, location)
when 43 then
FalseNode.new(location)
EnsureNode.new(load_location, load_optional_node, load_location, location)
when 44 then
FindPatternNode.new(load_optional_node, load_node, Array.new(load_varint) { load_node }, load_node, load_optional_location, load_optional_location, location)
FalseNode.new(location)
when 45 then
FloatNode.new(location)
FindPatternNode.new(load_optional_node, load_node, Array.new(load_varint) { load_node }, load_node, load_optional_location, load_optional_location, location)
when 46 then
ForNode.new(load_node, load_node, load_optional_node, load_location, load_location, load_optional_location, load_location, location)
FlipFlopNode.new(load_optional_node, load_optional_node, load_location, load_varint, location)
when 47 then
ForwardingArgumentsNode.new(location)
FloatNode.new(location)
when 48 then
ForwardingParameterNode.new(location)
ForNode.new(load_node, load_node, load_optional_node, load_location, load_location, load_optional_location, load_location, location)
when 49 then
ForwardingSuperNode.new(load_optional_node, location)
ForwardingArgumentsNode.new(location)
when 50 then
GlobalVariableOperatorAndWriteNode.new(load_location, load_location, load_node, location)
ForwardingParameterNode.new(location)
when 51 then
GlobalVariableOperatorOrWriteNode.new(load_location, load_location, load_node, location)
ForwardingSuperNode.new(load_optional_node, location)
when 52 then
GlobalVariableOperatorWriteNode.new(load_location, load_location, load_node, load_constant, location)
GlobalVariableOperatorAndWriteNode.new(load_location, load_location, load_node, location)
when 53 then
GlobalVariableReadNode.new(location)
GlobalVariableOperatorOrWriteNode.new(load_location, load_location, load_node, location)
when 54 then
GlobalVariableWriteNode.new(load_location, load_optional_location, load_optional_node, location)
GlobalVariableOperatorWriteNode.new(load_location, load_location, load_node, load_constant, location)
when 55 then
HashNode.new(load_location, Array.new(load_varint) { load_node }, load_location, location)
GlobalVariableReadNode.new(location)
when 56 then
HashPatternNode.new(load_optional_node, Array.new(load_varint) { load_node }, load_optional_node, load_optional_location, load_optional_location, location)
GlobalVariableWriteNode.new(load_location, load_optional_location, load_optional_node, location)
when 57 then
IfNode.new(load_optional_location, load_node, load_optional_node, load_optional_node, load_optional_location, location)
HashNode.new(load_location, Array.new(load_varint) { load_node }, load_location, location)
when 58 then
ImaginaryNode.new(load_node, location)
HashPatternNode.new(load_optional_node, Array.new(load_varint) { load_node }, load_optional_node, load_optional_location, load_optional_location, location)
when 59 then
InNode.new(load_node, load_optional_node, load_location, load_optional_location, location)
IfNode.new(load_optional_location, load_node, load_optional_node, load_optional_node, load_optional_location, location)
when 60 then
InstanceVariableOperatorAndWriteNode.new(load_location, load_location, load_node, location)
ImaginaryNode.new(load_node, location)
when 61 then
InstanceVariableOperatorOrWriteNode.new(load_location, load_location, load_node, location)
InNode.new(load_node, load_optional_node, load_location, load_optional_location, location)
when 62 then
InstanceVariableOperatorWriteNode.new(load_location, load_location, load_node, load_constant, location)
InstanceVariableOperatorAndWriteNode.new(load_location, load_location, load_node, location)
when 63 then
InstanceVariableReadNode.new(location)
InstanceVariableOperatorOrWriteNode.new(load_location, load_location, load_node, location)
when 64 then
InstanceVariableWriteNode.new(load_location, load_optional_node, load_optional_location, location)
InstanceVariableOperatorWriteNode.new(load_location, load_location, load_node, load_constant, location)
when 65 then
IntegerNode.new(location)
InstanceVariableReadNode.new(location)
when 66 then
InterpolatedRegularExpressionNode.new(load_location, Array.new(load_varint) { load_node }, load_location, load_varint, location)
InstanceVariableWriteNode.new(load_location, load_optional_node, load_optional_location, location)
when 67 then
InterpolatedStringNode.new(load_optional_location, Array.new(load_varint) { load_node }, load_optional_location, location)
IntegerNode.new(location)
when 68 then
InterpolatedSymbolNode.new(load_optional_location, Array.new(load_varint) { load_node }, load_optional_location, location)
InterpolatedRegularExpressionNode.new(load_location, Array.new(load_varint) { load_node }, load_location, load_varint, location)
when 69 then
InterpolatedXStringNode.new(load_location, Array.new(load_varint) { load_node }, load_location, location)
InterpolatedStringNode.new(load_optional_location, Array.new(load_varint) { load_node }, load_optional_location, location)
when 70 then
KeywordHashNode.new(Array.new(load_varint) { load_node }, location)
InterpolatedSymbolNode.new(load_optional_location, Array.new(load_varint) { load_node }, load_optional_location, location)
when 71 then
KeywordParameterNode.new(load_location, load_optional_node, location)
InterpolatedXStringNode.new(load_location, Array.new(load_varint) { load_node }, load_location, location)
when 72 then
KeywordRestParameterNode.new(load_location, load_optional_location, location)
KeywordHashNode.new(Array.new(load_varint) { load_node }, location)
when 73 then
LambdaNode.new(Array.new(load_varint) { load_constant }, load_location, load_optional_node, load_optional_node, location)
KeywordParameterNode.new(load_location, load_optional_node, location)
when 74 then
LocalVariableOperatorAndWriteNode.new(load_location, load_location, load_node, load_constant, location)
KeywordRestParameterNode.new(load_location, load_optional_location, location)
when 75 then
LocalVariableOperatorOrWriteNode.new(load_location, load_location, load_node, load_constant, location)
LambdaNode.new(Array.new(load_varint) { load_constant }, load_location, load_optional_node, load_optional_node, location)
when 76 then
LocalVariableOperatorWriteNode.new(load_location, load_location, load_node, load_constant, load_constant, location)
LocalVariableOperatorAndWriteNode.new(load_location, load_location, load_node, load_constant, location)
when 77 then
LocalVariableReadNode.new(load_constant, load_varint, location)
LocalVariableOperatorOrWriteNode.new(load_location, load_location, load_node, load_constant, location)
when 78 then
LocalVariableWriteNode.new(load_constant, load_varint, load_optional_node, load_location, load_optional_location, location)
LocalVariableOperatorWriteNode.new(load_location, load_location, load_node, load_constant, load_constant, location)
when 79 then
MatchPredicateNode.new(load_node, load_node, load_location, location)
LocalVariableReadNode.new(load_constant, load_varint, location)
when 80 then
MatchRequiredNode.new(load_node, load_node, load_location, location)
LocalVariableWriteNode.new(load_constant, load_varint, load_optional_node, load_location, load_optional_location, location)
when 81 then
MissingNode.new(location)
MatchPredicateNode.new(load_node, load_node, load_location, location)
when 82 then
ModuleNode.new(Array.new(load_varint) { load_constant }, load_location, load_node, load_optional_node, load_location, location)
MatchRequiredNode.new(load_node, load_node, load_location, location)
when 83 then
MultiWriteNode.new(Array.new(load_varint) { load_node }, load_optional_location, load_optional_node, load_optional_location, load_optional_location, location)
MissingNode.new(location)
when 84 then
NextNode.new(load_optional_node, load_location, location)
ModuleNode.new(Array.new(load_varint) { load_constant }, load_location, load_node, load_optional_node, load_location, location)
when 85 then
NilNode.new(location)
MultiWriteNode.new(Array.new(load_varint) { load_node }, load_optional_location, load_optional_node, load_optional_location, load_optional_location, location)
when 86 then
NoKeywordsParameterNode.new(load_location, load_location, location)
NextNode.new(load_optional_node, load_location, location)
when 87 then
NumberedReferenceReadNode.new(location)
NilNode.new(location)
when 88 then
OptionalParameterNode.new(load_constant, load_location, load_location, load_node, location)
NoKeywordsParameterNode.new(load_location, load_location, location)
when 89 then
OrNode.new(load_node, load_node, load_location, location)
NumberedReferenceReadNode.new(location)
when 90 then
ParametersNode.new(Array.new(load_varint) { load_node }, Array.new(load_varint) { load_node }, Array.new(load_varint) { load_node }, load_optional_node, Array.new(load_varint) { load_node }, load_optional_node, load_optional_node, location)
OptionalParameterNode.new(load_constant, load_location, load_location, load_node, location)
when 91 then
ParenthesesNode.new(load_optional_node, load_location, load_location, location)
OrNode.new(load_node, load_node, load_location, location)
when 92 then
PinnedExpressionNode.new(load_node, load_location, load_location, load_location, location)
ParametersNode.new(Array.new(load_varint) { load_node }, Array.new(load_varint) { load_node }, Array.new(load_varint) { load_node }, load_optional_node, Array.new(load_varint) { load_node }, load_optional_node, load_optional_node, location)
when 93 then
PinnedVariableNode.new(load_node, load_location, location)
ParenthesesNode.new(load_optional_node, load_location, load_location, location)
when 94 then
PostExecutionNode.new(load_optional_node, load_location, load_location, load_location, location)
PinnedExpressionNode.new(load_node, load_location, load_location, load_location, location)
when 95 then
PreExecutionNode.new(load_optional_node, load_location, load_location, load_location, location)
PinnedVariableNode.new(load_node, load_location, location)
when 96 then
ProgramNode.new(Array.new(load_varint) { load_constant }, load_node, location)
PostExecutionNode.new(load_optional_node, load_location, load_location, load_location, location)
when 97 then
RangeNode.new(load_optional_node, load_optional_node, load_location, load_varint, location)
PreExecutionNode.new(load_optional_node, load_location, load_location, load_location, location)
when 98 then
RationalNode.new(load_node, location)
ProgramNode.new(Array.new(load_varint) { load_constant }, load_node, location)
when 99 then
RedoNode.new(location)
RangeNode.new(load_optional_node, load_optional_node, load_location, load_varint, location)
when 100 then
RegularExpressionNode.new(load_location, load_location, load_location, load_string, load_varint, location)
RationalNode.new(load_node, location)
when 101 then
RequiredDestructuredParameterNode.new(Array.new(load_varint) { load_node }, load_location, load_location, location)
RedoNode.new(location)
when 102 then
RequiredParameterNode.new(load_constant, location)
RegularExpressionNode.new(load_location, load_location, load_location, load_string, load_varint, location)
when 103 then
RescueModifierNode.new(load_node, load_location, load_node, location)
RequiredDestructuredParameterNode.new(Array.new(load_varint) { load_node }, load_location, load_location, location)
when 104 then
RescueNode.new(load_location, Array.new(load_varint) { load_node }, load_optional_location, load_optional_node, load_optional_node, load_optional_node, location)
RequiredParameterNode.new(load_constant, location)
when 105 then
RestParameterNode.new(load_location, load_optional_location, location)
RescueModifierNode.new(load_node, load_location, load_node, location)
when 106 then
RetryNode.new(location)
RescueNode.new(load_location, Array.new(load_varint) { load_node }, load_optional_location, load_optional_node, load_optional_node, load_optional_node, location)
when 107 then
ReturnNode.new(load_location, load_optional_node, location)
RestParameterNode.new(load_location, load_optional_location, location)
when 108 then
SelfNode.new(location)
RetryNode.new(location)
when 109 then
SingletonClassNode.new(Array.new(load_varint) { load_constant }, load_location, load_location, load_node, load_optional_node, load_location, location)
ReturnNode.new(load_location, load_optional_node, location)
when 110 then
SourceEncodingNode.new(location)
SelfNode.new(location)
when 111 then
SourceFileNode.new(load_string, location)
SingletonClassNode.new(Array.new(load_varint) { load_constant }, load_location, load_location, load_node, load_optional_node, load_location, location)
when 112 then
SourceLineNode.new(location)
SourceEncodingNode.new(location)
when 113 then
SplatNode.new(load_location, load_optional_node, location)
SourceFileNode.new(load_string, location)
when 114 then
StatementsNode.new(Array.new(load_varint) { load_node }, location)
SourceLineNode.new(location)
when 115 then
StringConcatNode.new(load_node, load_node, location)
SplatNode.new(load_location, load_optional_node, location)
when 116 then
StringNode.new(load_optional_location, load_location, load_optional_location, load_string, location)
StatementsNode.new(Array.new(load_varint) { load_node }, location)
when 117 then
SuperNode.new(load_location, load_optional_location, load_optional_node, load_optional_location, load_optional_node, location)
StringConcatNode.new(load_node, load_node, location)
when 118 then
SymbolNode.new(load_optional_location, load_location, load_optional_location, load_string, location)
StringNode.new(load_optional_location, load_location, load_optional_location, load_string, location)
when 119 then
TrueNode.new(location)
SuperNode.new(load_location, load_optional_location, load_optional_node, load_optional_location, load_optional_node, location)
when 120 then
UndefNode.new(Array.new(load_varint) { load_node }, load_location, location)
SymbolNode.new(load_optional_location, load_location, load_optional_location, load_string, location)
when 121 then
UnlessNode.new(load_location, load_node, load_optional_node, load_optional_node, load_optional_location, location)
TrueNode.new(location)
when 122 then
UntilNode.new(load_location, load_node, load_optional_node, location)
UndefNode.new(Array.new(load_varint) { load_node }, load_location, location)
when 123 then
WhenNode.new(load_location, Array.new(load_varint) { load_node }, load_optional_node, location)
UnlessNode.new(load_location, load_node, load_optional_node, load_optional_node, load_optional_location, location)
when 124 then
WhileNode.new(load_location, load_node, load_optional_node, location)
UntilNode.new(load_location, load_node, load_optional_node, load_varint, location)
when 125 then
XStringNode.new(load_location, load_location, load_location, load_string, location)
WhenNode.new(load_location, Array.new(load_varint) { load_node }, load_optional_node, location)
when 126 then
WhileNode.new(load_location, load_node, load_optional_node, load_varint, location)
when 127 then
XStringNode.new(load_location, load_location, load_location, load_string, location)
when 128 then
YieldNode.new(load_location, load_optional_location, load_optional_node, load_optional_location, location)
end
end
end
TOKEN_TYPES = [
nil,
:EOF,
:MISSING,
:NOT_PROVIDED,
:AMPERSAND,
:AMPERSAND_AMPERSAND,
:AMPERSAND_AMPERSAND_EQUAL,
:AMPERSAND_DOT,
:AMPERSAND_EQUAL,
:BACKTICK,
:BACK_REFERENCE,
:BANG,
:BANG_EQUAL,
:BANG_TILDE,
:BRACE_LEFT,
:BRACE_RIGHT,
:BRACKET_LEFT,
:BRACKET_LEFT_ARRAY,
:BRACKET_LEFT_RIGHT,
:BRACKET_LEFT_RIGHT_EQUAL,
:BRACKET_RIGHT,
:CARET,
:CARET_EQUAL,
:CHARACTER_LITERAL,
:CLASS_VARIABLE,
:COLON,
:COLON_COLON,
:COMMA,
:COMMENT,
:CONSTANT,
:DOT,
:DOT_DOT,
:DOT_DOT_DOT,
:EMBDOC_BEGIN,
:EMBDOC_END,
:EMBDOC_LINE,
:EMBEXPR_BEGIN,
:EMBEXPR_END,
:EMBVAR,
:EQUAL,
:EQUAL_EQUAL,
:EQUAL_EQUAL_EQUAL,
:EQUAL_GREATER,
:EQUAL_TILDE,
:FLOAT,
:FLOAT_IMAGINARY,
:FLOAT_RATIONAL,
:FLOAT_RATIONAL_IMAGINARY,
:GLOBAL_VARIABLE,
:GREATER,
:GREATER_EQUAL,
:GREATER_GREATER,
:GREATER_GREATER_EQUAL,
:HEREDOC_END,
:HEREDOC_START,
:IDENTIFIER,
:IGNORED_NEWLINE,
:INSTANCE_VARIABLE,
:INTEGER,
:INTEGER_IMAGINARY,
:INTEGER_RATIONAL,
:INTEGER_RATIONAL_IMAGINARY,
:KEYWORD_ALIAS,
:KEYWORD_AND,
:KEYWORD_BEGIN,
:KEYWORD_BEGIN_UPCASE,
:KEYWORD_BREAK,
:KEYWORD_CASE,
:KEYWORD_CLASS,
:KEYWORD_DEF,
:KEYWORD_DEFINED,
:KEYWORD_DO,
:KEYWORD_DO_LOOP,
:KEYWORD_ELSE,
:KEYWORD_ELSIF,
:KEYWORD_END,
:KEYWORD_END_UPCASE,
:KEYWORD_ENSURE,
:KEYWORD_FALSE,
:KEYWORD_FOR,
:KEYWORD_IF,
:KEYWORD_IF_MODIFIER,
:KEYWORD_IN,
:KEYWORD_MODULE,
:KEYWORD_NEXT,
:KEYWORD_NIL,
:KEYWORD_NOT,
:KEYWORD_OR,
:KEYWORD_REDO,
:KEYWORD_RESCUE,
:KEYWORD_RESCUE_MODIFIER,
:KEYWORD_RETRY,
:KEYWORD_RETURN,
:KEYWORD_SELF,
:KEYWORD_SUPER,
:KEYWORD_THEN,
:KEYWORD_TRUE,
:KEYWORD_UNDEF,
:KEYWORD_UNLESS,
:KEYWORD_UNLESS_MODIFIER,
:KEYWORD_UNTIL,
:KEYWORD_UNTIL_MODIFIER,
:KEYWORD_WHEN,
:KEYWORD_WHILE,
:KEYWORD_WHILE_MODIFIER,
:KEYWORD_YIELD,
:KEYWORD___ENCODING__,
:KEYWORD___FILE__,
:KEYWORD___LINE__,
:LABEL,
:LABEL_END,
:LAMBDA_BEGIN,
:LESS,
:LESS_EQUAL,
:LESS_EQUAL_GREATER,
:LESS_LESS,
:LESS_LESS_EQUAL,
:MINUS,
:MINUS_EQUAL,
:MINUS_GREATER,
:NEWLINE,
:NUMBERED_REFERENCE,
:PARENTHESIS_LEFT,
:PARENTHESIS_LEFT_PARENTHESES,
:PARENTHESIS_RIGHT,
:PERCENT,
:PERCENT_EQUAL,
:PERCENT_LOWER_I,
:PERCENT_LOWER_W,
:PERCENT_LOWER_X,
:PERCENT_UPPER_I,
:PERCENT_UPPER_W,
:PIPE,
:PIPE_EQUAL,
:PIPE_PIPE,
:PIPE_PIPE_EQUAL,
:PLUS,
:PLUS_EQUAL,
:QUESTION_MARK,
:REGEXP_BEGIN,
:REGEXP_END,
:SEMICOLON,
:SLASH,
:SLASH_EQUAL,
:STAR,
:STAR_EQUAL,
:STAR_STAR,
:STAR_STAR_EQUAL,
:STRING_BEGIN,
:STRING_CONTENT,
:STRING_END,
:SYMBOL_BEGIN,
:TILDE,
:UAMPERSAND,
:UCOLON_COLON,
:UDOT_DOT,
:UDOT_DOT_DOT,
:UMINUS,
:UMINUS_NUM,
:UPLUS,
:USTAR,
:USTAR_STAR,
:WORDS_SEP,
:__END__,
]
end
end

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

@ -2,7 +2,7 @@
Gem::Specification.new do |spec|
spec.name = "yarp"
spec.version = "0.4.0"
spec.version = "0.7.0"
spec.authors = ["Shopify"]
spec.email = ["ruby@shopify.com"]
@ -10,27 +10,27 @@ Gem::Specification.new do |spec|
spec.homepage = "https://github.com/ruby/yarp"
spec.license = "MIT"
spec.required_ruby_version = ">= 3.0.0"
spec.require_paths = ["lib"]
spec.files = [
"CHANGELOG.md",
"CODE_OF_CONDUCT.md",
"CONTRIBUTING.md",
"LICENSE.md",
"Makefile.in",
"Makefile",
"README.md",
"config.h.in",
"config.yml",
"configure",
"docs/build_system.md",
"docs/building.md",
"docs/configuration.md",
"docs/design.md",
"docs/encoding.md",
"docs/extension.md",
"docs/fuzzing.md",
"docs/heredocs.md",
"docs/mapping.md",
"docs/ripper.md",
"docs/ruby_api.md",
"docs/serialization.md",
"docs/testing.md",
"ext/yarp/api_node.c",
@ -59,38 +59,20 @@ Gem::Specification.new do |spec|
"include/yarp/util/yp_strpbrk.h",
"include/yarp/version.h",
"lib/yarp.rb",
"lib/yarp/ffi.rb",
"lib/yarp/lex_compat.rb",
"lib/yarp/node.rb",
"lib/yarp/pack.rb",
"lib/yarp/ripper_compat.rb",
"lib/yarp/serialize.rb",
"src/diagnostic.c",
"src/enc/ascii.c",
"src/enc/big5.c",
"src/enc/euc_jp.c",
"src/enc/gbk.c",
"src/enc/iso_8859_1.c",
"src/enc/iso_8859_10.c",
"src/enc/iso_8859_11.c",
"src/enc/iso_8859_13.c",
"src/enc/iso_8859_14.c",
"src/enc/iso_8859_15.c",
"src/enc/iso_8859_16.c",
"src/enc/iso_8859_2.c",
"src/enc/iso_8859_3.c",
"src/enc/iso_8859_4.c",
"src/enc/iso_8859_5.c",
"src/enc/iso_8859_6.c",
"src/enc/iso_8859_7.c",
"src/enc/iso_8859_8.c",
"src/enc/iso_8859_9.c",
"src/enc/koi8_r.c",
"src/enc/shared.c",
"src/enc/shift_jis.c",
"src/enc/unicode.c",
"src/enc/windows_1251.c",
"src/enc/windows_1252.c",
"src/enc/windows_31j.c",
"src/enc/yp_big5.c",
"src/enc/yp_euc_jp.c",
"src/enc/yp_gbk.c",
"src/enc/yp_shift_jis.c",
"src/enc/yp_tables.c",
"src/enc/yp_unicode.c",
"src/enc/yp_windows_31j.c",
"src/node.c",
"src/pack.c",
"src/prettyprint.c",

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

@ -1,78 +0,0 @@
# frozen_string_literal: true
require "yarp_test_helper"
class NewlineTest < Test::Unit::TestCase
class NewlineVisitor < YARP::Visitor
attr_reader :source, :newlines
def initialize(source)
@source = source
@newlines = []
end
def visit(node)
newlines << source.line(node.location.start_offset) if node&.newline?
super(node)
end
end
root = File.dirname(__dir__)
Dir["{lib,test}/**/*.rb", base: root].each do |relative|
filepath = File.join(root, relative)
define_method "test_newline_flags_#{relative}" do
source = File.read(filepath, binmode: true, external_encoding: Encoding::UTF_8)
expected = rubyvm_lines(source)
result = YARP.parse_file(filepath)
assert_empty result.errors
result.mark_newlines
visitor = NewlineVisitor.new(result.source)
result.value.accept(visitor)
actual = visitor.newlines
if relative == "lib/yarp/serialize.rb"
# while (b = io.getbyte) >= 128 has 2 newline flags
line_number = source.lines.index { |line| line.include?('while (b = io.getbyte) >= 128') } + 1
expected.delete_at(expected.index(line_number))
elsif relative == "lib/yarp/lex_compat.rb"
# extra flag for: dedent_next =\n ((token.event: due to bytecode order
actual.delete(520)
# different line for: token =\n case event: due to bytecode order
actual.delete(577)
expected.delete(578)
# extra flag for: lex_state =\n if RIPPER: due to bytecode order
actual.delete(610)
# extra flag for: (token[2].start_with?("\#$") || token[2].start_with?("\#@"))
# unclear when ParenthesesNode should allow a second flag on the same line or not
actual.delete(737)
end
assert_equal expected, actual
end
end
private
def ignore_warnings
previous_verbosity = $VERBOSE
$VERBOSE = nil
yield
ensure
$VERBOSE = previous_verbosity
end
def rubyvm_lines(source)
queue = [ignore_warnings { RubyVM::InstructionSequence.compile(source) }]
lines = []
while iseq = queue.shift
lines.concat(iseq.trace_points.filter_map { |line, event| line if event == :line })
iseq.each_child { |insn| queue << insn unless insn.label.start_with?("ensure in ") }
end
lines.sort
end
end

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

@ -30,6 +30,7 @@ class EncodingTest < Test::Unit::TestCase
sjis
us-ascii
utf-8
utf8-mac
windows-31j
windows-1251
windows-1252

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

@ -294,28 +294,10 @@ class ErrorsTest < Test::Unit::TestCase
nil,
Location(),
Location(),
ArgumentsNode(
[KeywordHashNode(
[AssocSplatNode(
CallNode(
nil,
nil,
Location(),
nil,
nil,
nil,
nil,
0,
"kwargs"
),
Location()
)]
),
SplatNode(
Location(),
CallNode(nil, nil, Location(), nil, nil, nil, nil, 0, "args")
)]
),
ArgumentsNode([
KeywordHashNode([AssocSplatNode(expression("kwargs"), Location())]),
SplatNode(Location(), expression("args"))
]),
Location(),
nil,
0,
@ -362,19 +344,16 @@ class ErrorsTest < Test::Unit::TestCase
nil,
Location(),
Location(),
ArgumentsNode(
[KeywordHashNode(
[AssocNode(
SymbolNode(nil, Location(), Location(), "foo"),
CallNode(nil, nil, Location(), nil, nil, nil, nil, 0, "bar"),
nil
)]
),
SplatNode(
Location(),
CallNode(nil, nil, Location(), nil, nil, nil, nil, 0, "args")
)]
),
ArgumentsNode([
KeywordHashNode(
[AssocNode(
SymbolNode(nil, Location(), Location(), "foo"),
expression("bar"),
nil
)]
),
SplatNode(Location(), expression("args"))
]),
Location(),
nil,
0,
@ -1005,23 +984,27 @@ class ErrorsTest < Test::Unit::TestCase
end
def test_duplicated_parameter_names
expected = DefNode(
Location(),
nil,
ParametersNode([RequiredParameterNode(:a), RequiredParameterNode(:b), RequiredParameterNode(:a)], [], [], nil, [], nil, nil),
nil,
[:a, :b],
Location(),
nil,
Location(),
Location(),
nil,
Location()
)
# For some reason, Ripper reports no error for Ruby 3.0 when you have
# duplicated parameter names for positional parameters.
unless RUBY_VERSION < "3.1.0"
expected = DefNode(
Location(),
nil,
ParametersNode([RequiredParameterNode(:a), RequiredParameterNode(:b), RequiredParameterNode(:a)], [], [], nil, [], nil, nil),
nil,
[:a, :b],
Location(),
nil,
Location(),
Location(),
nil,
Location()
)
assert_errors expected, "def foo(a,b,a);end", [
["Duplicated parameter name.", 12..13]
]
assert_errors expected, "def foo(a,b,a);end", [
["Duplicated parameter name.", 12..13]
]
end
expected = DefNode(
Location(),

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

@ -16,6 +16,8 @@ a.(1, 2, 3)
a::b
a::b c
foo.bar = 1
a?
@ -80,6 +82,8 @@ foo(
b: :c,
)
foo &:block
foo a: true, b: false, &:block
some_func 1, kwarg: 2
@ -137,3 +141,7 @@ foo :a,
A {} + A {}
lst << A {}
"#{ join (" ") }"
"#{(v)}"

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

@ -11,3 +11,5 @@ empty??nil:nil
a??nil:nil
a ?var1 : var2
nil??_a =2:1

86
test/yarp/locals_test.rb Normal file
Просмотреть файл

@ -0,0 +1,86 @@
# frozen_string_literal: true
# This test is going to use the RubyVM::InstructionSequence class to compile
# local tables and compare against them to ensure we have the same locals in the
# same order. This is important to guarantee that we compile indices correctly
# on CRuby (in terms of compatibility).
#
# There have also been changes made in other versions of Ruby, so we only want
# to test on the most recent versions.
return if !defined?(RubyVM::InstructionSequence) || RUBY_VERSION < "3.2"
require "yarp_test_helper"
class LocalsTest < Test::Unit::TestCase
invalid = []
todos = []
# Invalid break
invalid << "break.txt"
invalid << "if.txt"
invalid << "rescue.txt"
invalid << "seattlerb/block_break.txt"
invalid << "unless.txt"
invalid << "whitequark/break.txt"
invalid << "whitequark/break_block.txt"
# Invalid next
invalid << "next.txt"
invalid << "seattlerb/block_next.txt"
invalid << "unparser/corpus/literal/control.txt"
invalid << "whitequark/next.txt"
invalid << "whitequark/next_block.txt"
# Invalid redo
invalid << "keywords.txt"
invalid << "whitequark/redo.txt"
# Invalid retry
invalid << "whitequark/retry.txt"
# Invalid yield
invalid << "seattlerb/dasgn_icky2.txt"
invalid << "seattlerb/yield_arg.txt"
invalid << "seattlerb/yield_call_assocs.txt"
invalid << "seattlerb/yield_empty_parens.txt"
invalid << "unparser/corpus/literal/yield.txt"
invalid << "whitequark/args_assocs.txt"
invalid << "whitequark/args_assocs_legacy.txt"
invalid << "whitequark/yield.txt"
invalid << "yield.txt"
# Dead code eliminated
invalid << "whitequark/ruby_bug_10653.txt"
# case :a
# in Symbol(*lhs, x, *rhs)
# end
todos << "seattlerb/case_in.txt"
# <<~HERE
# #{<<~THERE}
# THERE
# HERE
todos << "seattlerb/heredoc_nested.txt"
base = File.join(__dir__, "fixtures")
skips = invalid | todos
Dir["**/*.txt", base: base].each do |relative|
next if skips.include?(relative)
filepath = File.join(base, relative)
define_method("test_#{relative}") { assert_locals(filepath) }
end
private
def assert_locals(filepath)
source = File.read(filepath)
expected = YARP.const_get(:Debug).cruby_locals(source)
actual = YARP.const_get(:Debug).yarp_locals(source)
assert_equal(expected, actual)
end
end

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

@ -2,6 +2,8 @@
require "yarp_test_helper"
return if YARP::BACKEND == :FFI
class MemsizeTest < Test::Unit::TestCase
def test_memsize
result = YARP.const_get(:Debug).memsize("2 + 3")

100
test/yarp/newline_test.rb Normal file
Просмотреть файл

@ -0,0 +1,100 @@
# frozen_string_literal: true
require "yarp_test_helper"
return unless defined?(RubyVM::InstructionSequence)
# It is useful to have a diff even if the strings to compare are big
# However, ruby/ruby does not have a version of Test::Unit with access to
# max_diff_target_string_size
if defined?(Test::Unit::Assertions::AssertionMessage)
Test::Unit::Assertions::AssertionMessage.max_diff_target_string_size = 5000
end
class NewlineTest < Test::Unit::TestCase
class NewlineVisitor < YARP::Visitor
attr_reader :source, :newlines
def initialize(source)
@source = source
@newlines = []
end
def visit(node)
newlines << source.line(node.location.start_offset) if node&.newline?
super(node)
end
end
base = File.dirname(__dir__)
Dir["{lib,test}/**/*.rb", base: base].each do |relative|
define_method("test_newline_flags_#{relative}") do
assert_newlines(base, relative)
end
end
private
def assert_newlines(base, relative)
filepath = File.join(base, relative)
source = File.read(filepath, binmode: true, external_encoding: Encoding::UTF_8)
expected = rubyvm_lines(source)
result = YARP.parse_file(filepath)
assert_empty result.errors
result.mark_newlines
visitor = NewlineVisitor.new(result.source)
result.value.accept(visitor)
actual = visitor.newlines
source.each_line.with_index(1) do |line, line_number|
# Lines like `while (foo = bar)` result in two line flags in the bytecode
# but only one newline flag in the AST. We need to remove the extra line
# flag from the bytecode to make the test pass.
if line.match?(/while \(/)
index = expected.index(line_number)
expected.delete_at(index) if index
end
# Lines like `foo =` where the value is on the next line result in another
# line flag in the bytecode but only one newline flag in the AST.
if line.match?(/^\s+\w+ =$/)
if source.lines[line_number].match?(/^\s+case/)
actual[actual.index(line_number)] += 1
else
actual.delete_at(actual.index(line_number))
end
end
if line.match?(/^\s+\w+ = \[$/)
if !expected.include?(line_number) && !expected.include?(line_number + 2)
actual[actual.index(line_number)] += 1
end
end
end
assert_equal expected, actual
end
def ignore_warnings
previous_verbosity = $VERBOSE
$VERBOSE = nil
yield
ensure
$VERBOSE = previous_verbosity
end
def rubyvm_lines(source)
queue = [ignore_warnings { RubyVM::InstructionSequence.compile(source) }]
lines = []
while iseq = queue.shift
lines.concat(iseq.trace_points.filter_map { |line, event| line if event == :line })
iseq.each_child { |insn| queue << insn unless insn.label.start_with?("ensure in ") }
end
lines.sort
end
end

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

@ -0,0 +1,26 @@
# frozen_string_literal: true
require "yarp_test_helper"
return if YARP::BACKEND == :FFI
class ParseSerializeTest < Test::Unit::TestCase
def test_parse_serialize
dumped = YARP.const_get(:Debug).parse_serialize_file(__FILE__)
result = YARP.load(File.read(__FILE__), dumped)
assert_kind_of YARP::ParseResult, result, "Expected the return value to be a ParseResult"
assert_equal __FILE__, find_file_node(result)&.filepath, "Expected the filepath to be set correctly"
end
private
def find_file_node(result)
queue = [result.value]
while (node = queue.shift)
return node if node.is_a?(YARP::SourceFileNode)
queue.concat(node.child_nodes.compact)
end
end
end

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

@ -18,47 +18,30 @@ class ParseTest < Test::Unit::TestCase
ignore_warnings { Encoding.default_external = @previous_default_external }
end
def test_Ruby_3_2_plus
assert_operator RUBY_VERSION, :>=, "3.2.0", "ParseTest requires Ruby 3.2+"
end
def test_empty_string
result = YARP.parse("")
assert_equal [], result.value.statements.body
end
known_failures = %w[
seattlerb/heredoc_nested.txt
]
if RUBY_VERSION < "3.3.0"
known_failures << "seattlerb/pct_w_heredoc_interp_nested.txt"
end
def find_source_file_node(node)
if node.is_a?(YARP::SourceFileNode)
node
else
node && node.child_nodes.each do |child_node|
source_file_node = find_source_file_node(child_node)
return source_file_node if source_file_node
end
end
end
def test_parse_takes_file_path
filepath = "filepath.rb"
parsed_result = YARP.parse("def foo; __FILE__; end", filepath)
result = YARP.parse("def foo; __FILE__; end", filepath)
assert_equal filepath, find_source_file_node(parsed_result.value).filepath
assert_equal filepath, find_source_file_node(result.value).filepath
end
# To accurately compare against Ripper, we need to make sure that we're
# running on Ruby 3.2+.
check_ripper = RUBY_VERSION >= "3.2.0"
base = File.join(__dir__, "fixtures")
Dir["**/*.txt", base: base].each do |relative|
next if known_failures.include?(relative)
# These fail on TruffleRuby due to a difference in Symbol#inspect: :测试 vs :"测试"
next if RUBY_ENGINE == "truffleruby" and %w[seattlerb/bug202.txt seattlerb/magic_encoding_comment.txt].include?(relative)
filepath = File.join(base, relative)
snapshot = File.expand_path(File.join("snapshots", relative), __dir__)
directory = File.dirname(snapshot)
FileUtils.mkdir_p(directory) unless File.directory?(directory)
@ -69,7 +52,7 @@ class ParseTest < Test::Unit::TestCase
# Make sure that it can be correctly parsed by Ripper. If it can't, then we have a fixture
# that is invalid Ruby.
refute_nil Ripper.sexp_raw(source)
refute_nil Ripper.sexp_raw(source) if check_ripper
# Next, assert that there were no errors during parsing.
result = YARP.parse(source, relative)
@ -99,25 +82,35 @@ class ParseTest < Test::Unit::TestCase
# Next, assert that the value can be serialized and deserialized without
# changing the shape of the tree.
assert_equal_nodes(result.value, YARP.load(source, YARP.dump(source, relative)))
assert_equal_nodes(result.value, YARP.load(source, YARP.dump(source, relative)).value)
# Next, assert that the newlines are in the expected places.
expected_newlines = [0]
source.b.scan("\n") { expected_newlines << $~.offset(0)[0] + 1 }
assert_equal expected_newlines, YARP.const_get(:Debug).newlines(source)
# This file has changed behavior in Ripper in Ruby 3.3, so we skip it if
# we're on an earlier version.
return if relative == "seattlerb/pct_w_heredoc_interp_nested.txt" && RUBY_VERSION < "3.3.0"
# It seems like there are some oddities with nested heredocs and ripper.
# Waiting for feedback on https://bugs.ruby-lang.org/issues/19838.
return if relative == "seattlerb/heredoc_nested.txt"
# Finally, assert that we can lex the source and get the same tokens as
# Ripper.
lex_result = YARP.lex_compat(source)
assert_equal [], lex_result.errors
tokens = lex_result.value
begin
YARP.lex_ripper(source).zip(tokens).each do |(ripper, yarp)|
assert_equal ripper, yarp
if check_ripper
begin
YARP.lex_ripper(source).zip(tokens).each do |(ripper, yarp)|
assert_equal ripper, yarp
end
rescue SyntaxError
raise ArgumentError, "Test file has invalid syntax #{filepath}"
end
rescue SyntaxError
raise ArgumentError, "Test file has invalid syntax #{filepath}"
end
end
end
@ -137,13 +130,21 @@ class ParseTest < Test::Unit::TestCase
result = YARP.parse(snippet, relative)
assert_empty result.errors
assert_equal_nodes(result.value, YARP.load(snippet, YARP.dump(snippet, relative)))
assert_equal_nodes(result.value, YARP.load(snippet, YARP.dump(snippet, relative)).value)
end
end
end
private
def find_source_file_node(program)
queue = [program]
while (node = queue.shift)
return node if node.is_a?(YARP::SourceFileNode)
queue.concat(node.child_nodes.compact)
end
end
def ignore_warnings
previous_verbosity = $VERBOSE
$VERBOSE = nil

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

@ -2,6 +2,8 @@
require "yarp_test_helper"
return if YARP::BACKEND == :FFI
class RegexpTest < Test::Unit::TestCase
##############################################################################
# These tests test the actual use case of extracting named capture groups

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

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

@ -8,7 +8,7 @@ ProgramNode(0...39)(
nil,
ArgumentsNode(4...8)(
[CallNode(4...8)(
CallNode(5...8)(nil, nil, (5...8), nil, nil, nil, nil, 0, "bar"),
CallNode(5...8)(nil, nil, (5...8), nil, nil, nil, nil, 2, "bar"),
nil,
(4...5),
nil,
@ -26,7 +26,7 @@ ProgramNode(0...39)(
),
CallNode(10...18)(
CallNode(10...14)(
CallNode(11...14)(nil, nil, (11...14), nil, nil, nil, nil, 0, "foo"),
CallNode(11...14)(nil, nil, (11...14), nil, nil, nil, nil, 2, "foo"),
nil,
(10...11),
nil,
@ -40,7 +40,7 @@ ProgramNode(0...39)(
(14...15),
nil,
ArgumentsNode(15...18)(
[CallNode(15...18)(nil, nil, (15...18), nil, nil, nil, nil, 0, "bar")]
[CallNode(15...18)(nil, nil, (15...18), nil, nil, nil, nil, 2, "bar")]
),
nil,
nil,
@ -49,7 +49,7 @@ ProgramNode(0...39)(
),
CallNode(20...29)(
CallNode(20...24)(
CallNode(21...24)(nil, nil, (21...24), nil, nil, nil, nil, 0, "foo"),
CallNode(21...24)(nil, nil, (21...24), nil, nil, nil, nil, 2, "foo"),
nil,
(20...21),
nil,
@ -63,7 +63,7 @@ ProgramNode(0...39)(
(24...26),
nil,
ArgumentsNode(26...29)(
[CallNode(26...29)(nil, nil, (26...29), nil, nil, nil, nil, 0, "bar")]
[CallNode(26...29)(nil, nil, (26...29), nil, nil, nil, nil, 2, "bar")]
),
nil,
nil,
@ -85,7 +85,7 @@ ProgramNode(0...39)(
nil,
nil,
nil,
0,
2,
"bar"
),
nil,

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

@ -4,19 +4,19 @@ ProgramNode(0...511)(
[ArrayNode(0...4)(
[SplatNode(1...3)(
(1...2),
CallNode(2...3)(nil, nil, (2...3), nil, nil, nil, nil, 0, "a")
CallNode(2...3)(nil, nil, (2...3), nil, nil, nil, nil, 2, "a")
)],
(0...1),
(3...4)
),
CallNode(6...29)(
CallNode(6...9)(nil, nil, (6...9), nil, nil, nil, nil, 0, "foo"),
CallNode(6...9)(nil, nil, (6...9), nil, nil, nil, nil, 2, "foo"),
nil,
(9...19),
(9...10),
ArgumentsNode(10...29)(
[CallNode(10...13)(nil, nil, (10...13), nil, nil, nil, nil, 0, "bar"),
CallNode(15...18)(nil, nil, (15...18), nil, nil, nil, nil, 0, "baz"),
[CallNode(10...13)(nil, nil, (10...13), nil, nil, nil, nil, 2, "bar"),
CallNode(15...18)(nil, nil, (15...18), nil, nil, nil, nil, 2, "baz"),
ArrayNode(22...29)(
[IntegerNode(22...23)(),
IntegerNode(25...26)(),
@ -75,7 +75,7 @@ ProgramNode(0...511)(
nil,
nil,
nil,
0,
2,
"foo"
),
CallNode(108...111)(
@ -86,7 +86,7 @@ ProgramNode(0...511)(
nil,
nil,
nil,
0,
2,
"bar"
),
(105...107)
@ -105,7 +105,7 @@ ProgramNode(0...511)(
nil,
nil,
nil,
0,
2,
"foo"
),
nil,
@ -120,7 +120,7 @@ ProgramNode(0...511)(
nil,
nil,
nil,
0,
2,
"bar"
)]
),
@ -141,7 +141,7 @@ ProgramNode(0...511)(
nil,
nil,
nil,
0,
2,
"baz"
),
CallNode(130...133)(
@ -152,7 +152,7 @@ ProgramNode(0...511)(
nil,
nil,
nil,
0,
2,
"qux"
)]
),
@ -171,7 +171,7 @@ ProgramNode(0...511)(
nil,
nil,
nil,
0,
2,
"foo"
),
nil,
@ -186,7 +186,7 @@ ProgramNode(0...511)(
nil,
nil,
nil,
0,
2,
"bar"
)]
),
@ -207,7 +207,7 @@ ProgramNode(0...511)(
nil,
nil,
nil,
0,
2,
"baz"
)]
),
@ -226,7 +226,7 @@ ProgramNode(0...511)(
nil,
nil,
nil,
0,
2,
"foo"
),
nil,
@ -241,7 +241,7 @@ ProgramNode(0...511)(
nil,
nil,
nil,
0,
2,
"bar"
),
CallNode(164...167)(
@ -252,7 +252,7 @@ ProgramNode(0...511)(
nil,
nil,
nil,
0,
2,
"baz"
)]
),
@ -270,7 +270,7 @@ ProgramNode(0...511)(
nil,
nil,
nil,
0,
2,
"foo"
),
nil,
@ -285,7 +285,7 @@ ProgramNode(0...511)(
nil,
nil,
nil,
0,
2,
"bar"
),
CallNode(179...182)(
@ -296,7 +296,7 @@ ProgramNode(0...511)(
nil,
nil,
nil,
0,
2,
"baz"
),
CallNode(186...189)(
@ -307,7 +307,7 @@ ProgramNode(0...511)(
nil,
nil,
nil,
0,
2,
"qux"
)]
),
@ -326,7 +326,7 @@ ProgramNode(0...511)(
nil,
nil,
nil,
0,
2,
"foo"
),
nil,
@ -347,7 +347,7 @@ ProgramNode(0...511)(
nil,
nil,
nil,
0,
2,
"bar"
),
nil,
@ -377,7 +377,7 @@ ProgramNode(0...511)(
nil,
nil,
nil,
0,
2,
"foo"
),
nil,
@ -393,7 +393,7 @@ ProgramNode(0...511)(
nil,
nil,
nil,
0,
2,
"bar"
),
nil,
@ -408,7 +408,7 @@ ProgramNode(0...511)(
nil,
nil,
nil,
0,
2,
"baz"
),
CallNode(229...232)(
@ -419,7 +419,7 @@ ProgramNode(0...511)(
nil,
nil,
nil,
0,
2,
"qux"
)]
),
@ -443,7 +443,7 @@ ProgramNode(0...511)(
nil,
nil,
nil,
0,
2,
"foo"
),
nil,
@ -458,7 +458,7 @@ ProgramNode(0...511)(
nil,
nil,
nil,
0,
2,
"bar"
)]
),
@ -476,7 +476,7 @@ ProgramNode(0...511)(
nil,
nil,
nil,
0,
2,
"foo"
),
nil,
@ -491,7 +491,7 @@ ProgramNode(0...511)(
nil,
nil,
nil,
0,
2,
"bar"
),
CallNode(256...259)(
@ -502,7 +502,7 @@ ProgramNode(0...511)(
nil,
nil,
nil,
0,
2,
"baz"
)]
),
@ -532,7 +532,7 @@ ProgramNode(0...511)(
nil,
nil,
nil,
0,
2,
"kw"
),
(270...272)
@ -553,7 +553,7 @@ ProgramNode(0...511)(
nil,
nil,
nil,
0,
2,
"kw"
),
(281...283)
@ -574,7 +574,7 @@ ProgramNode(0...511)(
nil,
nil,
nil,
0,
2,
"kw"
),
(292...294)
@ -592,7 +592,7 @@ ProgramNode(0...511)(
nil,
nil,
nil,
0,
2,
"kw"
),
(304...306)
@ -612,7 +612,7 @@ ProgramNode(0...511)(
nil,
nil,
nil,
0,
2,
"foo"
),
CallNode(322...325)(
@ -623,7 +623,7 @@ ProgramNode(0...511)(
nil,
nil,
nil,
0,
2,
"bar"
),
(319...321)

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

@ -4,14 +4,14 @@ ProgramNode(0...94)(
[BeginNode(0...20)(
(0...5),
StatementsNode(6...7)(
[CallNode(6...7)(nil, nil, (6...7), nil, nil, nil, nil, 0, "a")]
[CallNode(6...7)(nil, nil, (6...7), nil, nil, nil, nil, 2, "a")]
),
nil,
nil,
EnsureNode(8...20)(
(8...14),
StatementsNode(15...16)(
[CallNode(15...16)(nil, nil, (15...16), nil, nil, nil, nil, 0, "b")]
[CallNode(15...16)(nil, nil, (15...16), nil, nil, nil, nil, 2, "b")]
),
(17...20)
),
@ -20,14 +20,14 @@ ProgramNode(0...94)(
BeginNode(22...46)(
(22...27),
StatementsNode(29...30)(
[CallNode(29...30)(nil, nil, (29...30), nil, nil, nil, nil, 0, "a")]
[CallNode(29...30)(nil, nil, (29...30), nil, nil, nil, nil, 2, "a")]
),
nil,
nil,
EnsureNode(32...46)(
(32...38),
StatementsNode(40...41)(
[CallNode(40...41)(nil, nil, (40...41), nil, nil, nil, nil, 0, "b")]
[CallNode(40...41)(nil, nil, (40...41), nil, nil, nil, nil, 2, "b")]
),
(43...46)
),
@ -36,14 +36,14 @@ ProgramNode(0...94)(
BeginNode(48...70)(
(48...53),
StatementsNode(54...55)(
[CallNode(54...55)(nil, nil, (54...55), nil, nil, nil, nil, 0, "a")]
[CallNode(54...55)(nil, nil, (54...55), nil, nil, nil, nil, 2, "a")]
),
nil,
nil,
EnsureNode(57...70)(
(57...63),
StatementsNode(64...65)(
[CallNode(64...65)(nil, nil, (64...65), nil, nil, nil, nil, 0, "b")]
[CallNode(64...65)(nil, nil, (64...65), nil, nil, nil, nil, 2, "b")]
),
(67...70)
),
@ -52,14 +52,14 @@ ProgramNode(0...94)(
BeginNode(72...94)(
(72...77),
StatementsNode(78...79)(
[CallNode(78...79)(nil, nil, (78...79), nil, nil, nil, nil, 0, "a")]
[CallNode(78...79)(nil, nil, (78...79), nil, nil, nil, nil, 2, "a")]
),
nil,
nil,
EnsureNode(81...94)(
(81...87),
StatementsNode(88...89)(
[CallNode(88...89)(nil, nil, (88...89), nil, nil, nil, nil, 0, "b")]
[CallNode(88...89)(nil, nil, (88...89), nil, nil, nil, nil, 2, "b")]
),
(91...94)
),

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

@ -4,7 +4,7 @@ ProgramNode(0...578)(
[BeginNode(0...33)(
(0...5),
StatementsNode(7...8)(
[CallNode(7...8)(nil, nil, (7...8), nil, nil, nil, nil, 0, "a")]
[CallNode(7...8)(nil, nil, (7...8), nil, nil, nil, nil, 2, "a")]
),
RescueNode(10...19)(
(10...16),
@ -12,14 +12,14 @@ ProgramNode(0...578)(
nil,
nil,
StatementsNode(18...19)(
[CallNode(18...19)(nil, nil, (18...19), nil, nil, nil, nil, 0, "b")]
[CallNode(18...19)(nil, nil, (18...19), nil, nil, nil, nil, 2, "b")]
),
nil
),
ElseNode(21...33)(
(21...25),
StatementsNode(27...28)(
[CallNode(27...28)(nil, nil, (27...28), nil, nil, nil, nil, 0, "c")]
[CallNode(27...28)(nil, nil, (27...28), nil, nil, nil, nil, 2, "c")]
),
(30...33)
),
@ -29,7 +29,7 @@ ProgramNode(0...578)(
BeginNode(35...79)(
(35...40),
StatementsNode(42...43)(
[CallNode(42...43)(nil, nil, (42...43), nil, nil, nil, nil, 0, "a")]
[CallNode(42...43)(nil, nil, (42...43), nil, nil, nil, nil, 2, "a")]
),
RescueNode(45...54)(
(45...51),
@ -37,21 +37,21 @@ ProgramNode(0...578)(
nil,
nil,
StatementsNode(53...54)(
[CallNode(53...54)(nil, nil, (53...54), nil, nil, nil, nil, 0, "b")]
[CallNode(53...54)(nil, nil, (53...54), nil, nil, nil, nil, 2, "b")]
),
nil
),
ElseNode(56...71)(
(56...60),
StatementsNode(62...63)(
[CallNode(62...63)(nil, nil, (62...63), nil, nil, nil, nil, 0, "c")]
[CallNode(62...63)(nil, nil, (62...63), nil, nil, nil, nil, 2, "c")]
),
(65...71)
),
EnsureNode(65...79)(
(65...71),
StatementsNode(73...74)(
[CallNode(73...74)(nil, nil, (73...74), nil, nil, nil, nil, 0, "d")]
[CallNode(73...74)(nil, nil, (73...74), nil, nil, nil, nil, 2, "d")]
),
(76...79)
),
@ -60,7 +60,7 @@ ProgramNode(0...578)(
BeginNode(81...92)(
(81...86),
StatementsNode(87...88)(
[CallNode(87...88)(nil, nil, (87...88), nil, nil, nil, nil, 0, "a")]
[CallNode(87...88)(nil, nil, (87...88), nil, nil, nil, nil, 2, "a")]
),
nil,
nil,
@ -78,7 +78,7 @@ ProgramNode(0...578)(
nil,
nil,
nil,
0,
2,
"a"
)]
),
@ -98,7 +98,7 @@ ProgramNode(0...578)(
nil,
nil,
nil,
0,
2,
"a"
)]
),
@ -118,7 +118,7 @@ ProgramNode(0...578)(
nil,
nil,
nil,
0,
2,
"a"
)]
),
@ -138,7 +138,7 @@ ProgramNode(0...578)(
nil,
nil,
nil,
0,
2,
"a"
)]
),
@ -156,7 +156,7 @@ ProgramNode(0...578)(
nil,
nil,
nil,
0,
2,
"b"
)]
),
@ -174,7 +174,7 @@ ProgramNode(0...578)(
nil,
nil,
nil,
0,
2,
"c"
)]
),
@ -192,7 +192,7 @@ ProgramNode(0...578)(
nil,
nil,
nil,
0,
2,
"d"
)]
),
@ -215,7 +215,7 @@ ProgramNode(0...578)(
nil,
nil,
nil,
0,
2,
"a"
)]
),
@ -233,7 +233,7 @@ ProgramNode(0...578)(
nil,
nil,
nil,
0,
2,
"b"
)]
),
@ -251,7 +251,7 @@ ProgramNode(0...578)(
nil,
nil,
nil,
0,
2,
"c"
)]
),
@ -273,7 +273,7 @@ ProgramNode(0...578)(
nil,
nil,
nil,
0,
2,
"a"
)]
),
@ -291,7 +291,7 @@ ProgramNode(0...578)(
nil,
nil,
nil,
0,
2,
"b"
)]
),
@ -309,7 +309,7 @@ ProgramNode(0...578)(
nil,
nil,
nil,
0,
2,
"b"
)]
),
@ -329,7 +329,7 @@ ProgramNode(0...578)(
nil,
nil,
nil,
0,
2,
"a"
)]
),
@ -347,7 +347,7 @@ ProgramNode(0...578)(
nil,
nil,
nil,
0,
2,
"b"
)]
),
@ -368,7 +368,7 @@ ProgramNode(0...578)(
nil,
nil,
nil,
0,
2,
"a"
)]
),
@ -386,7 +386,7 @@ ProgramNode(0...578)(
nil,
nil,
nil,
0,
2,
"b"
)]
),
@ -407,7 +407,7 @@ ProgramNode(0...578)(
nil,
nil,
nil,
0,
2,
"a"
)]
),
@ -425,7 +425,7 @@ ProgramNode(0...578)(
nil,
nil,
nil,
0,
2,
"b"
)]
),
@ -446,7 +446,7 @@ ProgramNode(0...578)(
nil,
nil,
nil,
0,
2,
"a"
)]
),
@ -464,7 +464,7 @@ ProgramNode(0...578)(
nil,
nil,
nil,
0,
2,
"b"
)]
),
@ -485,7 +485,7 @@ ProgramNode(0...578)(
nil,
nil,
nil,
0,
2,
"a"
)]
),
@ -503,7 +503,7 @@ ProgramNode(0...578)(
nil,
nil,
nil,
0,
2,
"b"
)]
),
@ -524,7 +524,7 @@ ProgramNode(0...578)(
nil,
nil,
nil,
0,
2,
"a"
)]
),
@ -542,7 +542,7 @@ ProgramNode(0...578)(
nil,
nil,
nil,
0,
2,
"b"
)]
),
@ -563,7 +563,7 @@ ProgramNode(0...578)(
nil,
nil,
nil,
0,
2,
"a"
)]
),
@ -581,7 +581,7 @@ ProgramNode(0...578)(
nil,
nil,
nil,
0,
2,
"b"
)]
),

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

@ -2,12 +2,12 @@ ProgramNode(0...402)(
[:fork],
StatementsNode(0...402)(
[CallNode(0...16)(
CallNode(0...3)(nil, nil, (0...3), nil, nil, nil, nil, 0, "foo"),
CallNode(0...3)(nil, nil, (0...3), nil, nil, nil, nil, 2, "foo"),
nil,
(3...8),
(3...4),
ArgumentsNode(4...7)(
[CallNode(4...7)(nil, nil, (4...7), nil, nil, nil, nil, 0, "bar")]
[CallNode(4...7)(nil, nil, (4...7), nil, nil, nil, nil, 2, "bar")]
),
(7...8),
BlockNode(9...16)(
@ -22,7 +22,7 @@ ProgramNode(0...402)(
nil,
nil,
nil,
0,
2,
"baz"
)]
),
@ -33,12 +33,12 @@ ProgramNode(0...402)(
"[]"
),
CallNode(18...37)(
CallNode(18...21)(nil, nil, (18...21), nil, nil, nil, nil, 0, "foo"),
CallNode(18...21)(nil, nil, (18...21), nil, nil, nil, nil, 2, "foo"),
nil,
(21...26),
(21...22),
ArgumentsNode(22...25)(
[CallNode(22...25)(nil, nil, (22...25), nil, nil, nil, nil, 0, "bar")]
[CallNode(22...25)(nil, nil, (22...25), nil, nil, nil, nil, 2, "bar")]
),
(25...26),
BlockNode(27...37)(
@ -53,7 +53,7 @@ ProgramNode(0...402)(
nil,
nil,
nil,
0,
2,
"baz"
)]
),
@ -64,7 +64,7 @@ ProgramNode(0...402)(
"[]"
),
CallNode(39...74)(
CallNode(39...40)(nil, nil, (39...40), nil, nil, nil, nil, 0, "x"),
CallNode(39...40)(nil, nil, (39...40), nil, nil, nil, nil, 2, "x"),
(40...41),
(41...47),
(47...48),
@ -119,7 +119,7 @@ ProgramNode(0...402)(
(88...91),
nil,
ArgumentsNode(92...109)(
[CallNode(92...95)(nil, nil, (92...95), nil, nil, nil, nil, 0, "bar"),
[CallNode(92...95)(nil, nil, (92...95), nil, nil, nil, nil, 2, "bar"),
ParenthesesNode(97...109)(
StatementsNode(98...108)(
[CallNode(98...108)(
@ -157,7 +157,7 @@ ProgramNode(0...402)(
nil,
nil,
nil,
0,
2,
"bar"
)]
),
@ -186,7 +186,7 @@ ProgramNode(0...402)(
nil,
nil,
nil,
0,
2,
"baz"
)]
),
@ -226,7 +226,7 @@ ProgramNode(0...402)(
nil,
nil,
nil,
0,
2,
"b"
),
nil,
@ -342,7 +342,7 @@ ProgramNode(0...402)(
nil,
nil,
nil,
0,
2,
"foo"
),
nil,
@ -357,7 +357,7 @@ ProgramNode(0...402)(
nil,
nil,
nil,
0,
2,
"bar"
)]
),
@ -374,7 +374,7 @@ ProgramNode(0...402)(
nil,
nil,
nil,
0,
2,
"baz"
)]
),

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

@ -4,20 +4,20 @@ ProgramNode(0...24)(
[LocalVariableOperatorAndWriteNode(0...7)(
(0...1),
(2...5),
CallNode(6...7)(nil, nil, (6...7), nil, nil, nil, nil, 0, "b"),
CallNode(6...7)(nil, nil, (6...7), nil, nil, nil, nil, 2, "b"),
:a
),
LocalVariableOperatorWriteNode(9...15)(
(9...10),
(11...13),
CallNode(14...15)(nil, nil, (14...15), nil, nil, nil, nil, 0, "b"),
CallNode(14...15)(nil, nil, (14...15), nil, nil, nil, nil, 2, "b"),
:a,
:+
),
LocalVariableOperatorOrWriteNode(17...24)(
(17...18),
(19...22),
CallNode(23...24)(nil, nil, (23...24), nil, nil, nil, nil, 0, "b"),
CallNode(23...24)(nil, nil, (23...24), nil, nil, nil, nil, 2, "b"),
:a
)]
)

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

@ -70,7 +70,7 @@ ProgramNode(0...272)(
nil,
nil,
nil,
0,
2,
"foo"
)
)],
@ -106,7 +106,7 @@ ProgramNode(0...272)(
nil,
nil,
nil,
0,
2,
"this"
),
[WhenNode(147...167)(
@ -131,7 +131,7 @@ ProgramNode(0...272)(
nil,
nil,
nil,
0,
2,
"foo"
),
nil,
@ -146,7 +146,7 @@ ProgramNode(0...272)(
nil,
nil,
nil,
0,
2,
"bar"
)]
),
@ -173,7 +173,7 @@ ProgramNode(0...272)(
nil,
nil,
nil,
0,
2,
"a"
)],
nil
@ -191,7 +191,7 @@ ProgramNode(0...272)(
nil,
nil,
nil,
0,
2,
"type"
),
[WhenNode(246...253)(

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

@ -80,7 +80,7 @@ ProgramNode(0...370)(
nil,
nil,
nil,
0,
2,
"foo"
),
nil,
@ -158,7 +158,7 @@ ProgramNode(0...370)(
nil,
nil,
nil,
0,
2,
"foo"
),
(232...233),
@ -186,7 +186,7 @@ ProgramNode(0...370)(
nil,
nil,
nil,
0,
2,
"foo"
),
(254...255),

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

@ -1,12 +1,12 @@
ProgramNode(0...118)(
[],
StatementsNode(0...118)(
[CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 0, "a"),
CallNode(13...14)(nil, nil, (13...14), nil, nil, nil, nil, 0, "b"),
CallNode(16...17)(nil, nil, (16...17), nil, nil, nil, nil, 0, "c"),
CallNode(28...29)(nil, nil, (28...29), nil, nil, nil, nil, 0, "d"),
[CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 2, "a"),
CallNode(13...14)(nil, nil, (13...14), nil, nil, nil, nil, 2, "b"),
CallNode(16...17)(nil, nil, (16...17), nil, nil, nil, nil, 2, "c"),
CallNode(28...29)(nil, nil, (28...29), nil, nil, nil, nil, 2, "d"),
CallNode(31...47)(
CallNode(31...32)(nil, nil, (31...32), nil, nil, nil, nil, 0, "e"),
CallNode(31...32)(nil, nil, (31...32), nil, nil, nil, nil, 2, "e"),
(45...46),
(46...47),
nil,
@ -17,7 +17,7 @@ ProgramNode(0...118)(
"f"
),
CallNode(49...64)(
CallNode(49...50)(nil, nil, (49...50), nil, nil, nil, nil, 0, "g"),
CallNode(49...50)(nil, nil, (49...50), nil, nil, nil, nil, 2, "g"),
(62...63),
(63...64),
nil,
@ -28,7 +28,7 @@ ProgramNode(0...118)(
"h"
),
CallNode(66...80)(
CallNode(66...67)(nil, nil, (66...67), nil, nil, nil, nil, 0, "i"),
CallNode(66...67)(nil, nil, (66...67), nil, nil, nil, nil, 2, "i"),
(78...79),
(79...80),
nil,
@ -39,7 +39,7 @@ ProgramNode(0...118)(
"j"
),
CallNode(82...98)(
CallNode(82...83)(nil, nil, (82...83), nil, nil, nil, nil, 0, "k"),
CallNode(82...83)(nil, nil, (82...83), nil, nil, nil, nil, 2, "k"),
(96...97),
(97...98),
nil,
@ -50,7 +50,7 @@ ProgramNode(0...118)(
"l"
),
CallNode(100...118)(
CallNode(100...101)(nil, nil, (100...101), nil, nil, nil, nil, 0, "m"),
CallNode(100...101)(nil, nil, (100...101), nil, nil, nil, nil, 2, "m"),
(115...117),
(117...118),
nil,

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

@ -16,7 +16,7 @@ ProgramNode(0...715)(
(10...12)
),
ConstantPathNode(15...19)(
CallNode(15...16)(nil, nil, (15...16), nil, nil, nil, nil, 0, "a"),
CallNode(15...16)(nil, nil, (15...16), nil, nil, nil, nil, 2, "a"),
ConstantReadNode(18...19)(),
(16...18)
),
@ -715,7 +715,7 @@ ProgramNode(0...715)(
CallNode(615...620)(
ConstantReadNode(615...616)(),
(616...618),
(619...620),
(618...619),
nil,
ArgumentsNode(619...620)(
[CallNode(619...620)(
@ -726,19 +726,19 @@ ProgramNode(0...715)(
nil,
nil,
nil,
0,
2,
"i"
)]
),
nil,
nil,
0,
"i"
"%"
),
CallNode(622...627)(
ConstantReadNode(622...623)(),
(623...625),
(626...627),
(625...626),
nil,
ArgumentsNode(626...627)(
[CallNode(626...627)(
@ -749,19 +749,19 @@ ProgramNode(0...715)(
nil,
nil,
nil,
0,
2,
"w"
)]
),
nil,
nil,
0,
"w"
"%"
),
CallNode(629...634)(
ConstantReadNode(629...630)(),
(630...632),
(633...634),
(632...633),
nil,
ArgumentsNode(633...634)(
[CallNode(633...634)(
@ -772,36 +772,36 @@ ProgramNode(0...715)(
nil,
nil,
nil,
0,
2,
"x"
)]
),
nil,
nil,
0,
"x"
"%"
),
CallNode(636...641)(
ConstantReadNode(636...637)(),
(637...639),
(640...641),
(639...640),
nil,
ArgumentsNode(640...641)([ConstantReadNode(640...641)()]),
nil,
nil,
0,
"I"
"%"
),
CallNode(643...648)(
ConstantReadNode(643...644)(),
(644...646),
(647...648),
(646...647),
nil,
ArgumentsNode(647...648)([ConstantReadNode(647...648)()]),
nil,
nil,
0,
"W"
"%"
),
CallNode(650...654)(
ConstantReadNode(650...651)(),

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

@ -41,7 +41,7 @@ ProgramNode(0...231)(
nil,
nil,
nil,
0,
2,
"b"
)]
),
@ -74,7 +74,7 @@ ProgramNode(0...231)(
nil,
nil,
nil,
0,
2,
"b"
)]
),
@ -97,7 +97,7 @@ ProgramNode(0...231)(
nil,
nil,
nil,
0,
2,
"b"
)]
),

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

@ -21,8 +21,8 @@ ProgramNode(0...78)(
DefinedNode(45...66)(
(53...54),
AndNode(54...65)(
CallNode(54...57)(nil, nil, (54...57), nil, nil, nil, nil, 0, "foo"),
CallNode(62...65)(nil, nil, (62...65), nil, nil, nil, nil, 0, "bar"),
CallNode(54...57)(nil, nil, (54...57), nil, nil, nil, nil, 2, "foo"),
CallNode(62...65)(nil, nil, (62...65), nil, nil, nil, nil, 2, "bar"),
(58...61)
),
(65...66),

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

@ -6,13 +6,13 @@ ProgramNode(0...120)(
HashNode(9...27)(
(9...10),
[AssocNode(11...17)(
CallNode(11...12)(nil, nil, (11...12), nil, nil, nil, nil, 0, "a"),
CallNode(16...17)(nil, nil, (16...17), nil, nil, nil, nil, 0, "b"),
CallNode(11...12)(nil, nil, (11...12), nil, nil, nil, nil, 2, "a"),
CallNode(16...17)(nil, nil, (16...17), nil, nil, nil, nil, 2, "b"),
(13...15)
),
AssocNode(19...25)(
CallNode(19...20)(nil, nil, (19...20), nil, nil, nil, nil, 0, "c"),
CallNode(24...25)(nil, nil, (24...25), nil, nil, nil, nil, 0, "d"),
CallNode(19...20)(nil, nil, (19...20), nil, nil, nil, nil, 2, "c"),
CallNode(24...25)(nil, nil, (24...25), nil, nil, nil, nil, 2, "d"),
(21...23)
)],
(26...27)
@ -20,12 +20,12 @@ ProgramNode(0...120)(
HashNode(29...44)(
(29...30),
[AssocNode(31...37)(
CallNode(31...32)(nil, nil, (31...32), nil, nil, nil, nil, 0, "a"),
CallNode(36...37)(nil, nil, (36...37), nil, nil, nil, nil, 0, "b"),
CallNode(31...32)(nil, nil, (31...32), nil, nil, nil, nil, 2, "a"),
CallNode(36...37)(nil, nil, (36...37), nil, nil, nil, nil, 2, "b"),
(33...35)
),
AssocSplatNode(39...42)(
CallNode(41...42)(nil, nil, (41...42), nil, nil, nil, nil, 0, "c"),
CallNode(41...42)(nil, nil, (41...42), nil, nil, nil, nil, 2, "c"),
(39...41)
)],
(43...44)
@ -34,12 +34,12 @@ ProgramNode(0...120)(
(46...47),
[AssocNode(54...58)(
SymbolNode(54...56)(nil, (54...55), (55...56), "a"),
CallNode(57...58)(nil, nil, (57...58), nil, nil, nil, nil, 0, "b"),
CallNode(57...58)(nil, nil, (57...58), nil, nil, nil, nil, 2, "b"),
nil
),
AssocNode(66...70)(
SymbolNode(66...68)(nil, (66...67), (67...68), "c"),
CallNode(69...70)(nil, nil, (69...70), nil, nil, nil, nil, 0, "d"),
CallNode(69...70)(nil, nil, (69...70), nil, nil, nil, nil, 2, "d"),
nil
)],
(78...79)
@ -48,16 +48,16 @@ ProgramNode(0...120)(
(81...82),
[AssocNode(83...87)(
SymbolNode(83...85)(nil, (83...84), (84...85), "a"),
CallNode(86...87)(nil, nil, (86...87), nil, nil, nil, nil, 0, "b"),
CallNode(86...87)(nil, nil, (86...87), nil, nil, nil, nil, 2, "b"),
nil
),
AssocNode(89...93)(
SymbolNode(89...91)(nil, (89...90), (90...91), "c"),
CallNode(92...93)(nil, nil, (92...93), nil, nil, nil, nil, 0, "d"),
CallNode(92...93)(nil, nil, (92...93), nil, nil, nil, nil, 2, "d"),
nil
),
AssocSplatNode(95...98)(
CallNode(97...98)(nil, nil, (97...98), nil, nil, nil, nil, 0, "e"),
CallNode(97...98)(nil, nil, (97...98), nil, nil, nil, nil, 2, "e"),
(95...97)
),
AssocNode(100...104)(
@ -70,7 +70,7 @@ ProgramNode(0...120)(
nil,
nil,
nil,
0,
2,
"g"
),
nil

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

@ -80,7 +80,7 @@ ProgramNode(0...382)(
nil,
nil,
nil,
0,
2,
"exit_loop"
),
StatementsNode(188...196)(
@ -102,7 +102,7 @@ ProgramNode(0...382)(
nil,
nil,
nil,
0,
2,
"foo"
),
StatementsNode(214...217)(
@ -114,7 +114,7 @@ ProgramNode(0...382)(
nil,
nil,
nil,
0,
2,
"bar"
)]
),
@ -123,7 +123,7 @@ ProgramNode(0...382)(
),
IfNode(223...234)(
(230...232),
CallNode(233...234)(nil, nil, (233...234), nil, nil, nil, nil, 0, "c"),
CallNode(233...234)(nil, nil, (233...234), nil, nil, nil, nil, 2, "c"),
StatementsNode(223...229)(
[IfNode(223...229)(
(225...227),
@ -135,7 +135,7 @@ ProgramNode(0...382)(
nil,
nil,
nil,
0,
2,
"b"
),
StatementsNode(223...224)(
@ -147,7 +147,7 @@ ProgramNode(0...382)(
nil,
nil,
nil,
0,
2,
"a"
)]
),
@ -196,7 +196,7 @@ ProgramNode(0...382)(
nil,
nil,
nil,
0,
2,
"type"
),
IntegerNode(272...273)(),
@ -214,7 +214,7 @@ ProgramNode(0...382)(
nil,
nil,
nil,
0,
2,
"type"
),
ConstantReadNode(288...289)(),

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

@ -45,7 +45,7 @@ ProgramNode(0...51)(
nil,
nil,
nil,
0,
2,
"a"
)]
),
@ -83,7 +83,7 @@ ProgramNode(0...51)(
nil,
nil,
nil,
0,
2,
"b"
),
nil,

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -94,7 +94,7 @@ ProgramNode(0...1194)(
nil,
nil,
nil,
0,
2,
"b"
),
(101...102),
@ -121,7 +121,7 @@ ProgramNode(0...1194)(
nil,
nil,
nil,
0,
2,
"a"
),
(116...117),
@ -186,7 +186,7 @@ ProgramNode(0...1194)(
),
DefNode(177...188)(
(183...184),
CallNode(181...182)(nil, nil, (181...182), nil, nil, nil, nil, 0, "a"),
CallNode(181...182)(nil, nil, (181...182), nil, nil, nil, nil, 2, "a"),
nil,
nil,
[],
@ -847,7 +847,7 @@ ProgramNode(0...1194)(
nil,
nil,
nil,
0,
2,
"b"
),
(769...770),
@ -935,7 +935,7 @@ ProgramNode(0...1194)(
nil,
nil,
nil,
0,
2,
"b"
),
(833...834),
@ -1052,7 +1052,7 @@ ProgramNode(0...1194)(
nil,
nil,
nil,
0,
2,
"bar"
),
(957...959)
@ -1066,7 +1066,7 @@ ProgramNode(0...1194)(
nil,
nil,
nil,
0,
2,
"baz"
),
(964...966)
@ -1080,7 +1080,7 @@ ProgramNode(0...1194)(
nil,
nil,
nil,
0,
2,
"qux"
),
(971...973)
@ -1339,7 +1339,7 @@ ProgramNode(0...1194)(
nil,
nil,
nil,
0,
2,
"item"
),
nil,

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

@ -30,7 +30,7 @@ ProgramNode(0...140)(
nil,
nil,
nil,
0,
2,
"bbb"
)]
),
@ -43,7 +43,7 @@ ProgramNode(0...140)(
[],
(40...46),
ConstantPathNode(47...51)(
CallNode(47...48)(nil, nil, (47...48), nil, nil, nil, nil, 0, "m"),
CallNode(47...48)(nil, nil, (47...48), nil, nil, nil, nil, 2, "m"),
ConstantReadNode(50...51)(),
(48...50)
),

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

@ -215,7 +215,7 @@ ProgramNode(0...434)(
),
DefNode(195...206)(
(201...202),
CallNode(199...200)(nil, nil, (199...200), nil, nil, nil, nil, 0, "a"),
CallNode(199...200)(nil, nil, (199...200), nil, nil, nil, nil, 2, "a"),
nil,
nil,
[],

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

@ -3,7 +3,7 @@ ProgramNode(0...190)(
StatementsNode(0...190)(
[AndNode(0...19)(
CallNode(0...7)(
CallNode(4...7)(nil, nil, (4...7), nil, nil, nil, nil, 0, "foo"),
CallNode(4...7)(nil, nil, (4...7), nil, nil, nil, nil, 2, "foo"),
nil,
(0...3),
nil,
@ -14,7 +14,7 @@ ProgramNode(0...190)(
"!"
),
CallNode(12...19)(
CallNode(16...19)(nil, nil, (16...19), nil, nil, nil, nil, 0, "bar"),
CallNode(16...19)(nil, nil, (16...19), nil, nil, nil, nil, 2, "bar"),
nil,
(12...15),
nil,
@ -28,8 +28,8 @@ ProgramNode(0...190)(
),
CallNode(21...37)(
AndNode(25...36)(
CallNode(25...28)(nil, nil, (25...28), nil, nil, nil, nil, 0, "foo"),
CallNode(33...36)(nil, nil, (33...36), nil, nil, nil, nil, 0, "bar"),
CallNode(25...28)(nil, nil, (25...28), nil, nil, nil, nil, 2, "foo"),
CallNode(33...36)(nil, nil, (33...36), nil, nil, nil, nil, 2, "bar"),
(29...32)
),
nil,
@ -42,7 +42,7 @@ ProgramNode(0...190)(
"!"
),
CallNode(39...46)(
CallNode(43...46)(nil, nil, (43...46), nil, nil, nil, nil, 0, "foo"),
CallNode(43...46)(nil, nil, (43...46), nil, nil, nil, nil, 2, "foo"),
nil,
(39...42),
nil,
@ -54,7 +54,7 @@ ProgramNode(0...190)(
),
AndNode(48...69)(
CallNode(48...55)(
CallNode(52...55)(nil, nil, (52...55), nil, nil, nil, nil, 0, "foo"),
CallNode(52...55)(nil, nil, (52...55), nil, nil, nil, nil, 2, "foo"),
nil,
(48...51),
nil,
@ -65,7 +65,7 @@ ProgramNode(0...190)(
"!"
),
CallNode(60...69)(
CallNode(66...69)(nil, nil, (66...69), nil, nil, nil, nil, 0, "bar"),
CallNode(66...69)(nil, nil, (66...69), nil, nil, nil, nil, 2, "bar"),
nil,
(60...63),
nil,
@ -79,7 +79,7 @@ ProgramNode(0...190)(
),
AndNode(72...97)(
CallNode(72...79)(
CallNode(76...79)(nil, nil, (76...79), nil, nil, nil, nil, 0, "foo"),
CallNode(76...79)(nil, nil, (76...79), nil, nil, nil, nil, 2, "foo"),
nil,
(72...75),
nil,
@ -90,7 +90,7 @@ ProgramNode(0...190)(
"!"
),
CallNode(88...97)(
CallNode(94...97)(nil, nil, (94...97), nil, nil, nil, nil, 0, "bar"),
CallNode(94...97)(nil, nil, (94...97), nil, nil, nil, nil, 2, "bar"),
nil,
(88...91),
nil,
@ -112,7 +112,7 @@ ProgramNode(0...190)(
nil,
nil,
nil,
0,
2,
"foo"
),
nil,
@ -133,7 +133,7 @@ ProgramNode(0...190)(
nil,
nil,
nil,
0,
2,
"bar"
),
nil,
@ -156,7 +156,7 @@ ProgramNode(0...190)(
nil,
nil,
nil,
0,
2,
"foo"
),
nil,
@ -177,7 +177,7 @@ ProgramNode(0...190)(
nil,
nil,
nil,
0,
2,
"foo"
),
nil,
@ -190,7 +190,7 @@ ProgramNode(0...190)(
"!"
),
CallNode(158...172)(
RangeNode(162...172)(
FlipFlopNode(162...172)(
CallNode(162...165)(
nil,
nil,
@ -214,7 +214,7 @@ ProgramNode(0...190)(
"bar"
),
(166...168),
2
0
),
nil,
(158...161),
@ -228,7 +228,7 @@ ProgramNode(0...190)(
CallNode(174...190)(
ParenthesesNode(178...190)(
StatementsNode(179...189)(
[RangeNode(179...189)(
[FlipFlopNode(179...189)(
CallNode(179...182)(
nil,
nil,
@ -252,7 +252,7 @@ ProgramNode(0...190)(
"bar"
),
(183...185),
2
0
)]
),
(178...179),

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

@ -22,45 +22,13 @@ ProgramNode(0...161)(
IntegerNode(82...85)(),
ImaginaryNode(87...89)(IntegerNode(87...88)()),
RationalNode(91...93)(IntegerNode(91...92)()),
CallNode(95...97)(
IntegerNode(96...97)(),
nil,
(95...96),
nil,
nil,
nil,
nil,
0,
"-@"
),
IntegerNode(95...97)(),
ImaginaryNode(99...102)(RationalNode(99...101)(IntegerNode(99...100)())),
ImaginaryNode(104...109)(RationalNode(104...108)(FloatNode(104...107)())),
CallNode(111...115)(
ImaginaryNode(112...115)(
RationalNode(112...114)(IntegerNode(112...113)())
),
nil,
(111...112),
nil,
nil,
nil,
nil,
0,
"-@"
),
CallNode(117...123)(
ImaginaryNode(118...123)(
RationalNode(118...122)(FloatNode(118...121)())
),
nil,
(117...118),
nil,
nil,
nil,
nil,
0,
"-@"
ImaginaryNode(111...115)(
RationalNode(111...114)(IntegerNode(111...113)())
),
ImaginaryNode(117...123)(RationalNode(117...122)(FloatNode(117...121)())),
RationalNode(125...129)(IntegerNode(125...128)()),
ImaginaryNode(131...135)(IntegerNode(131...134)()),
ImaginaryNode(137...142)(

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -51,7 +51,7 @@ ProgramNode(0...266)(
(71...73),
nil,
StatementsNode(76...79)(
[CallNode(76...79)(nil, nil, (76...79), nil, nil, nil, nil, 0, "foo")]
[CallNode(76...79)(nil, nil, (76...79), nil, nil, nil, nil, 2, "foo")]
)
),
LambdaNode(83...98)(
@ -59,7 +59,7 @@ ProgramNode(0...266)(
(83...85),
nil,
StatementsNode(90...93)(
[CallNode(90...93)(nil, nil, (90...93), nil, nil, nil, nil, 0, "foo")]
[CallNode(90...93)(nil, nil, (90...93), nil, nil, nil, nil, 2, "foo")]
)
),
LambdaNode(100...129)(

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

@ -22,7 +22,7 @@ ProgramNode(0...85)(
1
),
CallNode(22...31)(
CallNode(22...25)(nil, nil, (22...25), nil, nil, nil, nil, 0, "foo"),
CallNode(22...25)(nil, nil, (22...25), nil, nil, nil, nil, 2, "foo"),
nil,
(25...31),
(25...26),
@ -48,7 +48,7 @@ ProgramNode(0...85)(
nil,
nil,
nil,
0,
2,
"bar"
),
(40...43),
@ -85,7 +85,7 @@ ProgramNode(0...85)(
nil,
nil,
nil,
0,
2,
"bar"
),
(71...73),

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

@ -40,7 +40,7 @@ ProgramNode(0...278)(
nil,
nil,
nil,
0,
2,
"bbb"
)]
),
@ -71,7 +71,7 @@ ProgramNode(0...278)(
nil,
nil,
nil,
0,
2,
"baz"
)]
),

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

@ -2,12 +2,12 @@ ProgramNode(0...316)(
[:a],
StatementsNode(0...316)(
[RescueModifierNode(0...14)(
CallNode(0...3)(nil, nil, (0...3), nil, nil, nil, nil, 0, "foo"),
CallNode(0...3)(nil, nil, (0...3), nil, nil, nil, nil, 2, "foo"),
(4...10),
NilNode(11...14)()
),
RescueModifierNode(16...30)(
CallNode(16...19)(nil, nil, (16...19), nil, nil, nil, nil, 0, "foo"),
CallNode(16...19)(nil, nil, (16...19), nil, nil, nil, nil, 2, "foo"),
(20...26),
NilNode(27...30)()
),
@ -27,7 +27,7 @@ ProgramNode(0...316)(
NilNode(81...84)()
),
RescueModifierNode(86...105)(
CallNode(86...89)(nil, nil, (86...89), nil, nil, nil, nil, 0, "foo"),
CallNode(86...89)(nil, nil, (86...89), nil, nil, nil, nil, 2, "foo"),
(90...96),
OrNode(97...105)(
NilNode(97...100)(),
@ -44,7 +44,7 @@ ProgramNode(0...316)(
nil,
nil,
nil,
0,
2,
"foo"
),
(111...117),
@ -71,7 +71,7 @@ ProgramNode(0...316)(
nil,
nil,
nil,
0,
2,
"a"
)]
),
@ -87,7 +87,7 @@ ProgramNode(0...316)(
nil,
nil,
nil,
0,
2,
"b"
)
)],
@ -139,7 +139,7 @@ ProgramNode(0...316)(
nil,
nil,
nil,
0,
2,
"y"
)]
),
@ -201,7 +201,7 @@ ProgramNode(0...316)(
nil,
nil,
nil,
0,
2,
"foo"
),
(225...231),
@ -219,7 +219,7 @@ ProgramNode(0...316)(
nil,
nil,
nil,
0,
2,
"bar"
)]
),

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

@ -2,7 +2,7 @@ ProgramNode(0...13)(
[],
StatementsNode(0...13)(
[CallNode(0...13)(
CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 0, "a"),
CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 2, "a"),
nil,
(1...9),
(1...2),

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

@ -23,7 +23,7 @@ ProgramNode(0...42)(
nil,
nil,
nil,
0,
2,
"from"
),
CallNode(21...23)(
@ -34,7 +34,7 @@ ProgramNode(0...42)(
nil,
nil,
nil,
0,
2,
"to"
),
(18...20),

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

@ -2,7 +2,7 @@ ProgramNode(0...7)(
[],
StatementsNode(0...7)(
[CallNode(0...7)(
CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 0, "a"),
CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 2, "a"),
(1...2),
(2...3),
nil,

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

@ -20,7 +20,7 @@ ProgramNode(0...8)(
nil,
nil,
nil,
0,
2,
"y"
)]
),

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

@ -4,10 +4,10 @@ ProgramNode(0...14)(
[RangeNode(0...4)(nil, IntegerNode(2...4)(), (0...2), 0),
RangeNode(7...10)(
nil,
CallNode(9...10)(nil, nil, (9...10), nil, nil, nil, nil, 0, "a"),
CallNode(9...10)(nil, nil, (9...10), nil, nil, nil, nil, 2, "a"),
(7...9),
0
),
CallNode(13...14)(nil, nil, (13...14), nil, nil, nil, nil, 0, "c")]
CallNode(13...14)(nil, nil, (13...14), nil, nil, nil, nil, 2, "c")]
)
)

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

@ -4,10 +4,10 @@ ProgramNode(0...16)(
[RangeNode(0...5)(nil, IntegerNode(3...5)(), (0...3), 1),
RangeNode(8...12)(
nil,
CallNode(11...12)(nil, nil, (11...12), nil, nil, nil, nil, 0, "a"),
CallNode(11...12)(nil, nil, (11...12), nil, nil, nil, nil, 2, "a"),
(8...11),
1
),
CallNode(15...16)(nil, nil, (15...16), nil, nil, nil, nil, 0, "c")]
CallNode(15...16)(nil, nil, (15...16), nil, nil, nil, nil, 2, "c")]
)
)

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

@ -17,7 +17,7 @@ ProgramNode(0...26)(
nil,
nil,
nil,
0,
2,
"arg"
)]
),

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

@ -28,7 +28,7 @@ ProgramNode(0...30)(
nil,
nil,
nil,
0,
2,
"d"
)]
),
@ -47,7 +47,7 @@ ProgramNode(0...30)(
"a"
),
CallNode(20...30)(
CallNode(20...21)(nil, nil, (20...21), nil, nil, nil, nil, 0, "e"),
CallNode(20...21)(nil, nil, (20...21), nil, nil, nil, nil, 2, "e"),
(21...22),
(22...23),
nil,

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

@ -3,7 +3,7 @@ ProgramNode(0...31)(
StatementsNode(0...31)(
[CallNode(0...31)(
CallNode(0...16)(
CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 0, "a"),
CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 2, "a"),
(1...2),
(2...3),
nil,
@ -33,7 +33,7 @@ ProgramNode(0...31)(
nil,
nil,
nil,
0,
2,
"d"
)]
),
@ -65,7 +65,7 @@ ProgramNode(0...31)(
(24...25)
),
StatementsNode(26...27)(
[CallNode(26...27)(nil, nil, (26...27), nil, nil, nil, nil, 0, "g")]
[CallNode(26...27)(nil, nil, (26...27), nil, nil, nil, nil, 2, "g")]
),
(19...21),
(28...31)

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

@ -3,7 +3,7 @@ ProgramNode(0...33)(
StatementsNode(0...33)(
[CallNode(0...33)(
CallNode(0...16)(
CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 0, "a"),
CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 2, "a"),
(1...2),
(2...3),
nil,
@ -33,7 +33,7 @@ ProgramNode(0...33)(
nil,
nil,
nil,
0,
2,
"d"
)]
),
@ -47,7 +47,7 @@ ProgramNode(0...33)(
(17...18),
nil,
ArgumentsNode(19...20)(
[CallNode(19...20)(nil, nil, (19...20), nil, nil, nil, nil, 0, "f")]
[CallNode(19...20)(nil, nil, (19...20), nil, nil, nil, nil, 2, "f")]
),
nil,
BlockNode(21...33)(
@ -67,7 +67,7 @@ ProgramNode(0...33)(
(26...27)
),
StatementsNode(28...29)(
[CallNode(28...29)(nil, nil, (28...29), nil, nil, nil, nil, 0, "h")]
[CallNode(28...29)(nil, nil, (28...29), nil, nil, nil, nil, 2, "h")]
),
(21...23),
(30...33)

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

@ -3,12 +3,12 @@ ProgramNode(0...15)(
StatementsNode(0...15)(
[CallNode(0...15)(
CallNode(0...12)(
CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 0, "a"),
CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 2, "a"),
(1...2),
(2...3),
nil,
ArgumentsNode(4...5)(
[CallNode(4...5)(nil, nil, (4...5), nil, nil, nil, nil, 0, "c")]
[CallNode(4...5)(nil, nil, (4...5), nil, nil, nil, nil, 2, "c")]
),
nil,
BlockNode(6...12)([], nil, nil, (6...8), (9...12)),

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

@ -3,12 +3,12 @@ ProgramNode(0...14)(
StatementsNode(0...14)(
[CallNode(0...14)(
CallNode(0...12)(
CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 0, "a"),
CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 2, "a"),
(1...2),
(2...3),
nil,
ArgumentsNode(4...5)(
[CallNode(4...5)(nil, nil, (4...5), nil, nil, nil, nil, 0, "c")]
[CallNode(4...5)(nil, nil, (4...5), nil, nil, nil, nil, 2, "c")]
),
nil,
BlockNode(6...12)([], nil, nil, (6...8), (9...12)),

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

@ -9,7 +9,7 @@ ProgramNode(0...16)(
ArgumentsNode(2...5)(
[ParenthesesNode(2...5)(
StatementsNode(3...4)(
[CallNode(3...4)(nil, nil, (3...4), nil, nil, nil, nil, 0, "b")]
[CallNode(3...4)(nil, nil, (3...4), nil, nil, nil, nil, 2, "b")]
),
(2...3),
(4...5)
@ -21,7 +21,7 @@ ProgramNode(0...16)(
"a"
),
CallNode(6...16)(
CallNode(6...7)(nil, nil, (6...7), nil, nil, nil, nil, 0, "c"),
CallNode(6...7)(nil, nil, (6...7), nil, nil, nil, nil, 2, "c"),
(7...8),
(8...9),
nil,

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

@ -14,7 +14,7 @@ ProgramNode(0...17)(
"a"
),
(11...13),
(16...17),
(13...14),
nil,
ArgumentsNode(15...17)(
[SymbolNode(15...17)((15...16), (16...17), nil, "d")]
@ -22,7 +22,7 @@ ProgramNode(0...17)(
nil,
nil,
0,
"d"
"c"
)]
)
)

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

@ -17,7 +17,7 @@ ProgramNode(0...25)(
nil,
nil,
nil,
0,
2,
"arg"
)]
),

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

@ -18,7 +18,7 @@ ProgramNode(0...27)(
nil,
nil,
nil,
0,
2,
"arg"
)]
),

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

@ -3,14 +3,14 @@ ProgramNode(0...20)(
StatementsNode(0...20)(
[IfNode(0...9)(
nil,
CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 0, "a"),
CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 2, "a"),
StatementsNode(4...6)(
[StringNode(4...6)((4...5), (5...5), (5...6), "")]
),
ElseNode(6...9)(
(6...7),
StatementsNode(8...9)(
[CallNode(8...9)(nil, nil, (8...9), nil, nil, nil, nil, 0, "b")]
[CallNode(8...9)(nil, nil, (8...9), nil, nil, nil, nil, 2, "b")]
),
nil
),
@ -18,14 +18,14 @@ ProgramNode(0...20)(
),
IfNode(11...20)(
nil,
CallNode(11...12)(nil, nil, (11...12), nil, nil, nil, nil, 0, "a"),
CallNode(11...12)(nil, nil, (11...12), nil, nil, nil, nil, 2, "a"),
StatementsNode(15...17)(
[StringNode(15...17)((15...16), (16...16), (16...17), "")]
),
ElseNode(17...20)(
(17...18),
StatementsNode(19...20)(
[CallNode(19...20)(nil, nil, (19...20), nil, nil, nil, nil, 0, "b")]
[CallNode(19...20)(nil, nil, (19...20), nil, nil, nil, nil, 2, "b")]
),
nil
),

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

@ -4,7 +4,7 @@ ProgramNode(0...15)(
[BeginNode(0...15)(
(0...5),
StatementsNode(8...11)(
[CallNode(8...11)(nil, nil, (8...11), nil, nil, nil, nil, 0, "foo")]
[CallNode(8...11)(nil, nil, (8...11), nil, nil, nil, nil, 2, "foo")]
),
nil,
nil,

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

@ -21,7 +21,7 @@ ProgramNode(0...28)(
nil,
nil,
nil,
0,
2,
"a"
),
(15...16),

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

@ -30,7 +30,7 @@ ProgramNode(0...16)(
(11...12)
),
StatementsNode(13...14)(
[CallNode(13...14)(nil, nil, (13...14), nil, nil, nil, nil, 0, "d")]
[CallNode(13...14)(nil, nil, (13...14), nil, nil, nil, nil, 2, "d")]
),
(2...3),
(15...16)

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

@ -18,7 +18,7 @@ ProgramNode(0...24)(
nil,
nil,
nil,
0,
2,
"dir"
)]
),

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

@ -2,7 +2,7 @@ ProgramNode(0...6)(
[],
StatementsNode(0...6)(
[CallNode(0...6)(
CallNode(4...5)(nil, nil, (4...5), nil, nil, nil, nil, 0, "a"),
CallNode(4...5)(nil, nil, (4...5), nil, nil, nil, nil, 2, "a"),
nil,
(0...3),
(3...4),

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

@ -5,7 +5,7 @@ ProgramNode(0...18)(
(0...1),
(2...5),
RescueModifierNode(6...18)(
CallNode(6...7)(nil, nil, (6...7), nil, nil, nil, nil, 0, "b"),
CallNode(6...7)(nil, nil, (6...7), nil, nil, nil, nil, 2, "b"),
(8...14),
NilNode(15...18)()
),

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

@ -7,7 +7,7 @@ ProgramNode(0...9)(
(0...1),
(1...2),
ArgumentsNode(2...8)(
[CallNode(2...3)(nil, nil, (2...3), nil, nil, nil, nil, 0, "b"),
[CallNode(2...3)(nil, nil, (2...3), nil, nil, nil, nil, 2, "b"),
KeywordHashNode(5...8)(
[AssocSplatNode(5...8)(IntegerNode(7...8)(), (5...7))]
)]

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

@ -22,7 +22,7 @@ ProgramNode(0...31)(
nil,
nil,
nil,
0,
2,
"k"
)]
),

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

@ -2,13 +2,13 @@ ProgramNode(0...9)(
[],
StatementsNode(0...9)(
[CallNode(0...9)(
CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 0, "a"),
CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 2, "a"),
(1...2),
(2...3),
nil,
ArgumentsNode(4...9)(
[CallNode(4...9)(
CallNode(4...5)(nil, nil, (4...5), nil, nil, nil, nil, 0, "c"),
CallNode(4...5)(nil, nil, (4...5), nil, nil, nil, nil, 2, "c"),
(5...6),
(6...7),
nil,

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

@ -3,7 +3,7 @@ ProgramNode(0...7)(
StatementsNode(0...7)(
[CallNode(0...7)(
CallNode(2...7)(
CallNode(2...3)(nil, nil, (2...3), nil, nil, nil, nil, 0, "a"),
CallNode(2...3)(nil, nil, (2...3), nil, nil, nil, nil, 2, "a"),
(3...4),
(4...5),
nil,

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

@ -19,7 +19,7 @@ ProgramNode(0...22)(
nil,
nil,
nil,
0,
2,
"b"
),
(9...10),

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

@ -8,7 +8,7 @@ ProgramNode(0...7)(
(1...2),
ArgumentsNode(2...6)(
[BlockArgumentNode(2...6)(
CallNode(3...6)(nil, nil, (3...6), nil, nil, nil, nil, 0, "blk"),
CallNode(3...6)(nil, nil, (3...6), nil, nil, nil, nil, 2, "blk"),
(2...3)
)]
),

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

@ -2,7 +2,7 @@ ProgramNode(0...7)(
[],
StatementsNode(0...7)(
[CallNode(0...7)(
CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 0, "a"),
CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 2, "a"),
(1...2),
(2...7),
nil,

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

@ -3,7 +3,7 @@ ProgramNode(0...7)(
StatementsNode(0...7)(
[CallNode(0...7)(
CallNode(0...4)(
CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 0, "a"),
CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 2, "a"),
(2...3),
(3...4),
nil,

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

@ -3,7 +3,7 @@ ProgramNode(0...11)(
StatementsNode(0...11)(
[CallNode(0...11)(
CallNode(0...4)(
CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 0, "a"),
CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 2, "a"),
(2...3),
(3...4),
nil,

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

@ -3,7 +3,7 @@ ProgramNode(0...7)(
StatementsNode(0...7)(
[CallNode(0...7)(
CallNode(0...4)(
CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 0, "a"),
CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 2, "a"),
(1...2),
(3...4),
nil,

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

@ -478,7 +478,7 @@ ProgramNode(0...746)(
nil,
nil,
nil,
0,
2,
"a"
),
(604...605),

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

@ -1,22 +1,6 @@
ProgramNode(0...10)(
[],
StatementsNode(0...10)(
[IfNode(0...10)(
(0...2),
CallNode(3...5)(
IntegerNode(4...5)(),
nil,
(3...4),
nil,
nil,
nil,
nil,
0,
"-@"
),
nil,
nil,
(7...10)
)]
[IfNode(0...10)((0...2), IntegerNode(3...5)(), nil, nil, (7...10))]
)
)

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

@ -14,7 +14,7 @@ ProgramNode(0...17)(
nil,
nil,
nil,
0,
2,
"system"
)]
),

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

@ -14,7 +14,7 @@ ProgramNode(0...19)(
nil,
nil,
nil,
0,
2,
"system"
)]
),

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

@ -21,7 +21,7 @@ ProgramNode(0...30)(
nil,
nil,
nil,
0,
2,
"x"
),
(15...16),

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

@ -3,7 +3,7 @@ ProgramNode(0...35)(
StatementsNode(0...35)(
[DefNode(0...35)(
(6...17),
CallNode(4...5)(nil, nil, (4...5), nil, nil, nil, nil, 0, "x"),
CallNode(4...5)(nil, nil, (4...5), nil, nil, nil, nil, 2, "x"),
nil,
StatementsNode(20...35)(
[CallNode(20...35)(

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

@ -3,7 +3,7 @@ ProgramNode(0...45)(
StatementsNode(0...45)(
[DefNode(0...45)(
(6...17),
CallNode(4...5)(nil, nil, (4...5), nil, nil, nil, nil, 0, "x"),
CallNode(4...5)(nil, nil, (4...5), nil, nil, nil, nil, 2, "x"),
nil,
StatementsNode(20...45)(
[CallNode(20...45)(

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

@ -13,7 +13,7 @@ ProgramNode(0...33)(
"a"
),
CallNode(4...33)(
CallNode(4...5)(nil, nil, (4...5), nil, nil, nil, nil, 0, "a"),
CallNode(4...5)(nil, nil, (4...5), nil, nil, nil, nil, 2, "a"),
(5...6),
(6...7),
nil,

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

@ -2,7 +2,7 @@ ProgramNode(0...3)(
[],
StatementsNode(0...3)(
[RangeNode(0...3)(
CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 0, "a"),
CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 2, "a"),
nil,
(1...3),
0

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

@ -2,7 +2,7 @@ ProgramNode(0...4)(
[],
StatementsNode(0...4)(
[RangeNode(0...4)(
CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 0, "a"),
CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 2, "a"),
nil,
(1...4),
1

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

@ -13,7 +13,7 @@ ProgramNode(0...12)(
EmbeddedStatementsNode(7...11)(
(7...9),
StatementsNode(9...10)(
[CallNode(9...10)(nil, nil, (9...10), nil, nil, nil, nil, 0, "b")]
[CallNode(9...10)(nil, nil, (9...10), nil, nil, nil, nil, 2, "b")]
),
(10...11)
)],

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

@ -14,7 +14,7 @@ ProgramNode(0...11)(
nil,
nil,
nil,
0,
2,
"field"
)]
),

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

@ -1,10 +1,4 @@
ProgramNode(0...17)(
[],
StatementsNode(0...17)(
[InterpolatedSymbolNode(0...17)(
(0...2),
[StringNode(2...16)(nil, (2...16), nil, "Varietà")],
(16...17)
)]
)
StatementsNode(0...17)([SymbolNode(0...17)(nil, (2...16), nil, "Varietà")])
)

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

@ -2,16 +2,8 @@ ProgramNode(0...32)(
[],
StatementsNode(0...32)(
[AliasNode(0...17)(
InterpolatedSymbolNode(6...11)(
(6...8),
[StringNode(8...10)(nil, (8...10), nil, "<<")],
(10...11)
),
InterpolatedSymbolNode(12...17)(
(12...14),
[StringNode(14...16)(nil, (14...16), nil, ">>")],
(16...17)
),
SymbolNode(6...11)(nil, (8...10), nil, "<<"),
SymbolNode(12...17)(nil, (14...16), nil, ">>"),
(0...5)
),
AliasNode(19...32)(

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

@ -2,12 +2,12 @@ ProgramNode(0...29)(
[],
StatementsNode(0...29)(
[CallNode(0...29)(
CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 0, "h"),
CallNode(0...1)(nil, nil, (0...1), nil, nil, nil, nil, 2, "h"),
nil,
(1...4),
(1...2),
ArgumentsNode(2...29)(
[CallNode(2...3)(nil, nil, (2...3), nil, nil, nil, nil, 0, "k"),
[CallNode(2...3)(nil, nil, (2...3), nil, nil, nil, nil, 2, "k"),
BeginNode(5...29)(
(5...10),
StatementsNode(18...20)([IntegerNode(18...20)()]),

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

@ -6,14 +6,14 @@ ProgramNode(0...10)(
[EmbeddedStatementsNode(1...5)(
(1...3),
StatementsNode(3...4)(
[CallNode(3...4)(nil, nil, (3...4), nil, nil, nil, nil, 0, "a")]
[CallNode(3...4)(nil, nil, (3...4), nil, nil, nil, nil, 2, "a")]
),
(4...5)
),
EmbeddedStatementsNode(5...9)(
(5...7),
StatementsNode(7...8)(
[CallNode(7...8)(nil, nil, (7...8), nil, nil, nil, nil, 0, "b")]
[CallNode(7...8)(nil, nil, (7...8), nil, nil, nil, nil, 2, "b")]
),
(8...9)
)],

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

@ -6,7 +6,7 @@ ProgramNode(0...8)(
[EmbeddedStatementsNode(1...5)(
(1...3),
StatementsNode(3...4)(
[CallNode(3...4)(nil, nil, (3...4), nil, nil, nil, nil, 0, "a")]
[CallNode(3...4)(nil, nil, (3...4), nil, nil, nil, nil, 2, "a")]
),
(4...5)
),

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

@ -8,7 +8,7 @@ ProgramNode(0...5)(
(2...3),
nil,
ArgumentsNode(4...5)(
[CallNode(4...5)(nil, nil, (4...5), nil, nil, nil, nil, 0, "b")]
[CallNode(4...5)(nil, nil, (4...5), nil, nil, nil, nil, 2, "b")]
),
nil,
nil,

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

@ -3,11 +3,11 @@ ProgramNode(0...16)(
StatementsNode(0...16)(
[IfNode(0...16)(
(0...2),
RangeNode(3...7)(
CallNode(3...4)(nil, nil, (3...4), nil, nil, nil, nil, 0, "a"),
CallNode(6...7)(nil, nil, (6...7), nil, nil, nil, nil, 0, "b"),
FlipFlopNode(3...7)(
CallNode(3...4)(nil, nil, (3...4), nil, nil, nil, nil, 2, "a"),
CallNode(6...7)(nil, nil, (6...7), nil, nil, nil, nil, 2, "b"),
(4...6),
2
0
),
nil,
nil,

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

@ -0,0 +1,27 @@
ProgramNode(0...23)(
[],
StatementsNode(0...23)(
[ArrayNode(0...23)(
[InterpolatedStringNode(1...21)(
(1...4),
[EmbeddedStatementsNode(6...12)(
(6...8),
StatementsNode(8...17)(
[InterpolatedStringNode(8...17)(
(8...11),
[StringNode(13...15)(nil, (13...15), nil, "b\n")],
(15...17)
)]
),
(11...12)
),
StringNode(12...13)(nil, (12...13), nil, "\n"),
StringNode(17...19)(nil, (17...19), nil, "a\n")],
(19...21)
),
IntegerNode(21...22)()],
(0...1),
(22...23)
)]
)
)

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

@ -25,7 +25,7 @@ ProgramNode(0...20)(
nil,
nil,
nil,
0,
2,
"bar"
)]
),

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

@ -17,7 +17,7 @@ ProgramNode(0...104)(
"p"
),
CallNode(16...21)(
CallNode(16...17)(nil, nil, (16...17), nil, nil, nil, nil, 0, "a"),
CallNode(16...17)(nil, nil, (16...17), nil, nil, nil, nil, 2, "a"),
(17...18),
(18...19),
nil,
@ -28,7 +28,7 @@ ProgramNode(0...104)(
"b"
),
CallNode(24...32)(
CallNode(24...25)(nil, nil, (24...25), nil, nil, nil, nil, 0, "c"),
CallNode(24...25)(nil, nil, (24...25), nil, nil, nil, nil, 2, "c"),
(25...26),
(26...27),
nil,
@ -41,7 +41,7 @@ ProgramNode(0...104)(
"d"
),
CallNode(35...40)(
CallNode(35...36)(nil, nil, (35...36), nil, nil, nil, nil, 0, "e"),
CallNode(35...36)(nil, nil, (35...36), nil, nil, nil, nil, 2, "e"),
(36...37),
(37...38),
nil,
@ -52,7 +52,7 @@ ProgramNode(0...104)(
"f"
),
CallNode(43...51)(
CallNode(43...44)(nil, nil, (43...44), nil, nil, nil, nil, 0, "g"),
CallNode(43...44)(nil, nil, (43...44), nil, nil, nil, nil, 2, "g"),
(44...45),
(45...46),
nil,
@ -76,7 +76,7 @@ ProgramNode(0...104)(
"p"
),
CallNode(61...67)(
CallNode(61...62)(nil, nil, (61...62), nil, nil, nil, nil, 0, "a"),
CallNode(61...62)(nil, nil, (61...62), nil, nil, nil, nil, 2, "a"),
(62...63),
(63...64),
(64...65),
@ -87,7 +87,7 @@ ProgramNode(0...104)(
"b"
),
CallNode(70...79)(
CallNode(70...71)(nil, nil, (70...71), nil, nil, nil, nil, 0, "c"),
CallNode(70...71)(nil, nil, (70...71), nil, nil, nil, nil, 2, "c"),
(71...72),
(72...73),
(73...74),
@ -100,7 +100,7 @@ ProgramNode(0...104)(
"d"
),
CallNode(82...88)(
CallNode(82...83)(nil, nil, (82...83), nil, nil, nil, nil, 0, "e"),
CallNode(82...83)(nil, nil, (82...83), nil, nil, nil, nil, 2, "e"),
(83...84),
(84...85),
(85...86),
@ -111,7 +111,7 @@ ProgramNode(0...104)(
"f"
),
CallNode(91...100)(
CallNode(91...92)(nil, nil, (91...92), nil, nil, nil, nil, 0, "g"),
CallNode(91...92)(nil, nil, (91...92), nil, nil, nil, nil, 2, "g"),
(92...93),
(93...94),
(94...95),

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

@ -47,6 +47,6 @@ ProgramNode(0...48)(
nil,
(43...46)
),
CallNode(47...48)(nil, nil, (47...48), nil, nil, nil, nil, 0, "a")]
CallNode(47...48)(nil, nil, (47...48), nil, nil, nil, nil, 2, "a")]
)
)

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше