diff options
77 files changed, 4707 insertions, 5236 deletions
diff --git a/lib/yarp.rb b/lib/yarp.rb index dd790434cc..01c0d5ec71 100644 --- a/lib/yarp.rb +++ b/lib/yarp.rb @@ -1,17 +1,79 @@ # frozen_string_literal: true module YARP - # This represents a location in the source corresponding to a node or token. + # This represents a source of Ruby code that has been parsed. It is used in + # conjunction with locations to allow them to resolve line numbers and source + # ranges. + class Source + attr_reader :source, :offsets + + def initialize(source, offsets) + @source = source + @offsets = offsets + end + + def slice(offset, length) + source.byteslice(offset, length) + end + + def line(value) + offsets.bsearch_index { |offset| offset > value } || offsets.length + end + + def column(value) + value - offsets[line(value) - 1] + end + end + + # This represents a location in the source. class Location - attr_reader :start_offset, :length + # A Source object that is used to determine more information from the given + # offset and length. + private attr_reader :source + + # The byte offset from the beginning of the source where this location + # starts. + attr_reader :start_offset - def initialize(start_offset, length) + # The length of this location in bytes. + attr_reader :length + + def initialize(source, start_offset, length) + @source = source @start_offset = start_offset @length = length end + # The source code that this location represents. + def slice + source.slice(start_offset, length) + end + + # The byte offset from the beginning of the source where this location ends. def end_offset - @start_offset + @length + start_offset + length + end + + # The line number where this location starts. + def start_line + source.line(start_offset) + end + + # The line number where this location ends. + def end_line + source.line(end_offset - 1) + end + + # The column number in bytes where this location starts from the start of + # the line. + def start_column + source.column(start_offset) + end + + # The column number in bytes where this location ends from the start of the + # line. + def end_column + source.column(end_offset - 1) end def deconstruct_keys(keys) @@ -101,21 +163,12 @@ module YARP # This represents a token from the Ruby source. class Token - attr_reader :type, :value, :start_offset, :length + attr_reader :type, :value, :location - def initialize(type, value, start_offset, length) + def initialize(type, value, location) @type = type @value = value - @start_offset = start_offset - @length = length - end - - def end_offset - @start_offset + @length - end - - def location - Location.new(@start_offset, @length) + @location = location end def deconstruct_keys(keys) @@ -143,20 +196,12 @@ module YARP # This represents a node in the tree. class Node - attr_reader :start_offset, :length - - def end_offset - @start_offset + @length - end - - def location - Location.new(@start_offset, @length) - end + attr_reader :location def pretty_print(q) q.group do q.text(self.class.name.split("::").last) - self.location.pretty_print(q) + location.pretty_print(q) q.text("(") q.nest(2) do deconstructed = deconstruct_keys([]) @@ -171,67 +216,10 @@ 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 - - # This lexes with the Ripper lex. It drops any space events but otherwise - # returns the same tokens. - # [raises SyntaxError] if the syntax in source is invalid - def self.lex_ripper(source) - previous = [] - results = [] - - Ripper.lex(source, raise_errors: true).each do |token| - case token[1] - when :on_sp - # skip - when :on_tstring_content - if previous[1] == :on_tstring_content && - (token[2].start_with?("\#$") || token[2].start_with?("\#@")) - previous[2] << token[2] - else - results << token - previous = token - end - when :on_words_sep - if previous[1] == :on_words_sep - previous[2] << token[2] - else - results << token - previous = token - end - else - results << token - previous = token - end - end - - results - end - # Load the serialized AST using the source as a reference into a tree. def self.load(source, serialized) Serialize.load(source, serialized) end - - def self.parse(source, filepath=nil) - _parse(source, filepath) - end end require_relative "yarp/lex_compat" @@ -240,9 +228,3 @@ require_relative "yarp/ripper_compat" require_relative "yarp/serialize" require_relative "yarp/pack" require "yarp.so" - -module YARP - class << self - private :_parse - end -end diff --git a/lib/yarp/lex_compat.rb b/lib/yarp/lex_compat.rb index a72f8c0aeb..a455d9c6fa 100644 --- a/lib/yarp/lex_compat.rb +++ b/lib/yarp/lex_compat.rb @@ -534,12 +534,11 @@ module YARP end end - attr_reader :source, :offsets, :filepath + attr_reader :source, :filepath def initialize(source, filepath = "") @source = source @filepath = filepath || "" - @offsets = find_offsets(source) end def result @@ -561,7 +560,8 @@ module YARP result_value[0][0].value.prepend("\xEF\xBB\xBF") if bom result_value.each_with_index do |(token, lex_state), index| - (lineno, column) = find_location(token.location.start_offset) + lineno = token.location.start_line + column = token.location.start_column column -= index == 0 ? 6 : 3 if bom && lineno == 1 event = RIPPER.fetch(token.type) @@ -702,38 +702,6 @@ module YARP ParseResult.new(tokens, result.comments, result.errors, result.warnings) end - - private - - # YARP keeps locations around in the form of ranges of byte offsets from the - # start of the file. Ripper keeps locations around in the form of line and - # column numbers. To match the output, we keep a cache of the offsets at the - # beginning of each line. - def find_offsets(source) - last_offset = 0 - offsets = [0] - - source.each_line do |line| - last_offset += line.bytesize - offsets << last_offset - end - - offsets - end - - # Given a byte offset, find the line number and column number that it maps - # to. We use a binary search over the cached offsets to find the line number - # that the offset is on, and then subtract the offset of the previous line - # to find the column number. - def find_location(value) - line_number = offsets.bsearch_index { |offset| offset > value } - line_offset = offsets[line_number - 1] if line_number - - [ - line_number || offsets.length - 1, - value - (line_offset || offsets.last) - ] - end end # The constant that wraps the behavior of the lexer to match Ripper's output @@ -746,4 +714,39 @@ module YARP def self.lex_compat(source, filepath = "") LexCompat.new(source, filepath).result end + + # This lexes with the Ripper lex. It drops any space events but otherwise + # returns the same tokens. Raises SyntaxError if the syntax in source is + # invalid. + def self.lex_ripper(source) + previous = [] + results = [] + + Ripper.lex(source, raise_errors: true).each do |token| + case token[1] + when :on_sp + # skip + when :on_tstring_content + if previous[1] == :on_tstring_content && + (token[2].start_with?("\#$") || token[2].start_with?("\#@")) + previous[2] << token[2] + else + results << token + previous = token + end + when :on_words_sep + if previous[1] == :on_words_sep + previous[2] << token[2] + else + results << token + previous = token + end + else + results << token + previous = token + end + end + + results + end end diff --git a/lib/yarp/node.rb b/lib/yarp/node.rb index f6f9136cd1..393030d12d 100644 --- a/lib/yarp/node.rb +++ b/lib/yarp/node.rb @@ -20,13 +20,12 @@ module YARP # attr_reader keyword_loc: Location attr_reader :keyword_loc - # def initialize: (new_name: Node, old_name: Node, keyword_loc: Location, start_offset: Integer, length: Integer) -> void - def initialize(new_name, old_name, keyword_loc, start_offset, length) + # def initialize: (new_name: Node, old_name: Node, keyword_loc: Location, location: Location) -> void + def initialize(new_name, old_name, keyword_loc, location) @new_name = new_name @old_name = old_name @keyword_loc = keyword_loc - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -46,6 +45,11 @@ module YARP def deconstruct_keys(keys) { new_name: new_name, old_name: old_name, keyword_loc: keyword_loc, location: location } end + + # def keyword: () -> String + def keyword + keyword_loc.slice + end end # Represents an alternation pattern in pattern matching. @@ -62,13 +66,12 @@ module YARP # attr_reader operator_loc: Location attr_reader :operator_loc - # def initialize: (left: Node, right: Node, operator_loc: Location, start_offset: Integer, length: Integer) -> void - def initialize(left, right, operator_loc, start_offset, length) + # def initialize: (left: Node, right: Node, operator_loc: Location, location: Location) -> void + def initialize(left, right, operator_loc, location) @left = left @right = right @operator_loc = operator_loc - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -88,6 +91,11 @@ module YARP def deconstruct_keys(keys) { left: left, right: right, operator_loc: operator_loc, location: location } end + + # def operator: () -> String + def operator + operator_loc.slice + end end # Represents the use of the `&&` operator or the `and` keyword. @@ -104,13 +112,12 @@ module YARP # attr_reader operator_loc: Location attr_reader :operator_loc - # def initialize: (left: Node, right: Node, operator_loc: Location, start_offset: Integer, length: Integer) -> void - def initialize(left, right, operator_loc, start_offset, length) + # def initialize: (left: Node, right: Node, operator_loc: Location, location: Location) -> void + def initialize(left, right, operator_loc, location) @left = left @right = right @operator_loc = operator_loc - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -130,6 +137,11 @@ module YARP def deconstruct_keys(keys) { left: left, right: right, operator_loc: operator_loc, location: location } end + + # def operator: () -> String + def operator + operator_loc.slice + end end # Represents a set of arguments to a method or a keyword. @@ -140,11 +152,10 @@ module YARP # attr_reader arguments: Array[Node] attr_reader :arguments - # def initialize: (arguments: Array[Node], start_offset: Integer, length: Integer) -> void - def initialize(arguments, start_offset, length) + # def initialize: (arguments: Array[Node], location: Location) -> void + def initialize(arguments, location) @arguments = arguments - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -181,13 +192,12 @@ module YARP # attr_reader closing_loc: Location? attr_reader :closing_loc - # def initialize: (elements: Array[Node], opening_loc: Location?, closing_loc: Location?, start_offset: Integer, length: Integer) -> void - def initialize(elements, opening_loc, closing_loc, start_offset, length) + # def initialize: (elements: Array[Node], opening_loc: Location?, closing_loc: Location?, location: Location) -> void + def initialize(elements, opening_loc, closing_loc, location) @elements = elements @opening_loc = opening_loc @closing_loc = closing_loc - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -207,6 +217,16 @@ module YARP def deconstruct_keys(keys) { elements: elements, opening_loc: opening_loc, closing_loc: closing_loc, location: location } end + + # def opening: () -> String? + def opening + opening_loc&.slice + end + + # def closing: () -> String? + def closing + closing_loc&.slice + end end # Represents an array pattern in pattern matching. @@ -244,16 +264,15 @@ module YARP # attr_reader closing_loc: Location? attr_reader :closing_loc - # def initialize: (constant: Node?, requireds: Array[Node], rest: Node?, posts: Array[Node], opening_loc: Location?, closing_loc: Location?, start_offset: Integer, length: Integer) -> void - def initialize(constant, requireds, rest, posts, opening_loc, closing_loc, start_offset, length) + # def initialize: (constant: Node?, requireds: Array[Node], rest: Node?, posts: Array[Node], opening_loc: Location?, closing_loc: Location?, location: Location) -> void + def initialize(constant, requireds, rest, posts, opening_loc, closing_loc, location) @constant = constant @requireds = requireds @rest = rest @posts = posts @opening_loc = opening_loc @closing_loc = closing_loc - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -273,6 +292,16 @@ module YARP def deconstruct_keys(keys) { constant: constant, requireds: requireds, rest: rest, posts: posts, opening_loc: opening_loc, closing_loc: closing_loc, location: location } end + + # def opening: () -> String? + def opening + opening_loc&.slice + end + + # def closing: () -> String? + def closing + closing_loc&.slice + end end # Represents a hash key/value pair. @@ -289,13 +318,12 @@ module YARP # attr_reader operator_loc: Location? attr_reader :operator_loc - # def initialize: (key: Node, value: Node?, operator_loc: Location?, start_offset: Integer, length: Integer) -> void - def initialize(key, value, operator_loc, start_offset, length) + # def initialize: (key: Node, value: Node?, operator_loc: Location?, location: Location) -> void + def initialize(key, value, operator_loc, location) @key = key @value = value @operator_loc = operator_loc - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -315,6 +343,11 @@ module YARP def deconstruct_keys(keys) { key: key, value: value, operator_loc: operator_loc, location: location } end + + # def operator: () -> String? + def operator + operator_loc&.slice + end end # Represents a splat in a hash literal. @@ -328,12 +361,11 @@ module YARP # attr_reader operator_loc: Location attr_reader :operator_loc - # def initialize: (value: Node?, operator_loc: Location, start_offset: Integer, length: Integer) -> void - def initialize(value, operator_loc, start_offset, length) + # def initialize: (value: Node?, operator_loc: Location, location: Location) -> void + def initialize(value, operator_loc, location) @value = value @operator_loc = operator_loc - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -353,6 +385,11 @@ module YARP def deconstruct_keys(keys) { value: value, operator_loc: operator_loc, location: location } end + + # def operator: () -> String + def operator + operator_loc.slice + end end # Represents reading a reference to a field in the previous match. @@ -360,10 +397,9 @@ module YARP # $' # ^^ class BackReferenceReadNode < Node - # def initialize: (start_offset: Integer, length: Integer) -> void - def initialize(start_offset, length) - @start_offset = start_offset - @length = length + # def initialize: (location: Location) -> void + def initialize(location) + @location = location end # def accept: (visitor: Visitor) -> void @@ -410,16 +446,15 @@ module YARP # attr_reader end_keyword_loc: Location? attr_reader :end_keyword_loc - # def initialize: (begin_keyword_loc: Location?, statements: Node?, rescue_clause: Node?, else_clause: Node?, ensure_clause: Node?, end_keyword_loc: Location?, start_offset: Integer, length: Integer) -> void - def initialize(begin_keyword_loc, statements, rescue_clause, else_clause, ensure_clause, end_keyword_loc, start_offset, length) + # def initialize: (begin_keyword_loc: Location?, statements: Node?, rescue_clause: Node?, else_clause: Node?, ensure_clause: Node?, end_keyword_loc: Location?, location: Location) -> void + def initialize(begin_keyword_loc, statements, rescue_clause, else_clause, ensure_clause, end_keyword_loc, location) @begin_keyword_loc = begin_keyword_loc @statements = statements @rescue_clause = rescue_clause @else_clause = else_clause @ensure_clause = ensure_clause @end_keyword_loc = end_keyword_loc - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -439,6 +474,16 @@ module YARP def deconstruct_keys(keys) { begin_keyword_loc: begin_keyword_loc, statements: statements, rescue_clause: rescue_clause, else_clause: else_clause, ensure_clause: ensure_clause, end_keyword_loc: end_keyword_loc, location: location } end + + # def begin_keyword: () -> String? + def begin_keyword + begin_keyword_loc&.slice + end + + # def end_keyword: () -> String? + def end_keyword + end_keyword_loc&.slice + end end # Represents block method arguments. @@ -452,12 +497,11 @@ module YARP # attr_reader operator_loc: Location attr_reader :operator_loc - # def initialize: (expression: Node?, operator_loc: Location, start_offset: Integer, length: Integer) -> void - def initialize(expression, operator_loc, start_offset, length) + # def initialize: (expression: Node?, operator_loc: Location, location: Location) -> void + def initialize(expression, operator_loc, location) @expression = expression @operator_loc = operator_loc - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -477,6 +521,11 @@ module YARP def deconstruct_keys(keys) { expression: expression, operator_loc: operator_loc, location: location } end + + # def operator: () -> String + def operator + operator_loc.slice + end end # Represents a block of ruby code. @@ -499,15 +548,14 @@ module YARP # attr_reader closing_loc: Location attr_reader :closing_loc - # def initialize: (locals: Array[Symbol], parameters: Node?, statements: Node?, opening_loc: Location, closing_loc: Location, start_offset: Integer, length: Integer) -> void - def initialize(locals, parameters, statements, opening_loc, closing_loc, start_offset, length) + # def initialize: (locals: Array[Symbol], parameters: Node?, statements: Node?, opening_loc: Location, closing_loc: Location, location: Location) -> void + def initialize(locals, parameters, statements, opening_loc, closing_loc, location) @locals = locals @parameters = parameters @statements = statements @opening_loc = opening_loc @closing_loc = closing_loc - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -527,6 +575,16 @@ module YARP def deconstruct_keys(keys) { locals: locals, parameters: parameters, statements: statements, opening_loc: opening_loc, closing_loc: closing_loc, location: location } end + + # def opening: () -> String + def opening + opening_loc.slice + end + + # def closing: () -> String + def closing + closing_loc.slice + end end # Represents a block parameter to a method, block, or lambda definition. @@ -541,12 +599,11 @@ module YARP # attr_reader operator_loc: Location attr_reader :operator_loc - # def initialize: (name_loc: Location?, operator_loc: Location, start_offset: Integer, length: Integer) -> void - def initialize(name_loc, operator_loc, start_offset, length) + # def initialize: (name_loc: Location?, operator_loc: Location, location: Location) -> void + def initialize(name_loc, operator_loc, location) @name_loc = name_loc @operator_loc = operator_loc - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -566,6 +623,16 @@ module YARP def deconstruct_keys(keys) { name_loc: name_loc, 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 block's parameters declaration. @@ -589,14 +656,13 @@ module YARP # attr_reader closing_loc: Location? attr_reader :closing_loc - # def initialize: (parameters: Node?, locals: Array[Location], opening_loc: Location?, closing_loc: Location?, start_offset: Integer, length: Integer) -> void - def initialize(parameters, locals, opening_loc, closing_loc, start_offset, length) + # def initialize: (parameters: Node?, locals: Array[Location], opening_loc: Location?, closing_loc: Location?, location: Location) -> void + def initialize(parameters, locals, opening_loc, closing_loc, location) @parameters = parameters @locals = locals @opening_loc = opening_loc @closing_loc = closing_loc - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -616,6 +682,16 @@ module YARP def deconstruct_keys(keys) { parameters: parameters, locals: locals, opening_loc: opening_loc, closing_loc: closing_loc, location: location } end + + # def opening: () -> String? + def opening + opening_loc&.slice + end + + # def closing: () -> String? + def closing + closing_loc&.slice + end end # Represents the use of the `break` keyword. @@ -629,12 +705,11 @@ module YARP # attr_reader keyword_loc: Location attr_reader :keyword_loc - # def initialize: (arguments: Node?, keyword_loc: Location, start_offset: Integer, length: Integer) -> void - def initialize(arguments, keyword_loc, start_offset, length) + # def initialize: (arguments: Node?, keyword_loc: Location, location: Location) -> void + def initialize(arguments, keyword_loc, location) @arguments = arguments @keyword_loc = keyword_loc - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -654,6 +729,11 @@ module YARP def deconstruct_keys(keys) { arguments: arguments, keyword_loc: keyword_loc, location: location } end + + # def keyword: () -> String + def keyword + keyword_loc.slice + end end # Represents a method call, in all of the various forms that can take. @@ -703,8 +783,8 @@ module YARP # attr_reader name: String attr_reader :name - # def initialize: (receiver: Node?, operator_loc: Location?, message_loc: Location?, opening_loc: Location?, arguments: Node?, closing_loc: Location?, block: Node?, flags: Integer, name: String, start_offset: Integer, length: Integer) -> void - def initialize(receiver, operator_loc, message_loc, opening_loc, arguments, closing_loc, block, flags, name, start_offset, length) + # def initialize: (receiver: Node?, operator_loc: Location?, message_loc: Location?, opening_loc: Location?, arguments: Node?, closing_loc: Location?, block: Node?, flags: Integer, name: String, location: Location) -> void + def initialize(receiver, operator_loc, message_loc, opening_loc, arguments, closing_loc, block, flags, name, location) @receiver = receiver @operator_loc = operator_loc @message_loc = message_loc @@ -714,8 +794,7 @@ module YARP @block = block @flags = flags @name = name - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -735,6 +814,26 @@ module YARP def deconstruct_keys(keys) { receiver: receiver, operator_loc: operator_loc, message_loc: message_loc, opening_loc: opening_loc, arguments: arguments, closing_loc: closing_loc, block: block, flags: flags, name: name, location: location } end + + # def operator: () -> String? + def operator + operator_loc&.slice + end + + # def message: () -> String? + def message + message_loc&.slice + end + + # def opening: () -> String? + def opening + opening_loc&.slice + end + + # def closing: () -> String? + def closing + closing_loc&.slice + end end # Represents the use of the `&&=` operator on a call. @@ -751,13 +850,12 @@ module YARP # attr_reader value: Node attr_reader :value - # def initialize: (target: Node, operator_loc: Location, value: Node, start_offset: Integer, length: Integer) -> void - def initialize(target, operator_loc, value, start_offset, length) + # def initialize: (target: Node, operator_loc: Location, value: Node, location: Location) -> void + def initialize(target, operator_loc, value, location) @target = target @operator_loc = operator_loc @value = value - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -777,6 +875,11 @@ module YARP def deconstruct_keys(keys) { target: target, operator_loc: operator_loc, value: value, location: location } end + + # def operator: () -> String + def operator + operator_loc.slice + end end # Represents the use of the `||=` operator on a call. @@ -793,13 +896,12 @@ module YARP # attr_reader operator_loc: Location attr_reader :operator_loc - # def initialize: (target: Node, value: Node, operator_loc: Location, start_offset: Integer, length: Integer) -> void - def initialize(target, value, operator_loc, start_offset, length) + # def initialize: (target: Node, value: Node, operator_loc: Location, location: Location) -> void + def initialize(target, value, operator_loc, location) @target = target @value = value @operator_loc = operator_loc - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -819,6 +921,11 @@ module YARP def deconstruct_keys(keys) { target: target, value: value, operator_loc: operator_loc, location: location } end + + # def operator: () -> String + def operator + operator_loc.slice + end end # Represents the use of an assignment operator on a call. @@ -838,14 +945,13 @@ module YARP # attr_reader operator_id: Symbol attr_reader :operator_id - # def initialize: (target: Node, operator_loc: Location, value: Node, operator_id: Symbol, start_offset: Integer, length: Integer) -> void - def initialize(target, operator_loc, value, operator_id, start_offset, length) + # def initialize: (target: Node, operator_loc: Location, value: Node, operator_id: Symbol, location: Location) -> void + def initialize(target, operator_loc, value, operator_id, location) @target = target @operator_loc = operator_loc @value = value @operator_id = operator_id - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -865,6 +971,11 @@ module YARP def deconstruct_keys(keys) { target: target, operator_loc: operator_loc, value: value, operator_id: operator_id, location: location } end + + # def operator: () -> String + def operator + operator_loc.slice + end end # Represents assigning to a local variable in pattern matching. @@ -881,13 +992,12 @@ module YARP # attr_reader operator_loc: Location attr_reader :operator_loc - # def initialize: (value: Node, target: Node, operator_loc: Location, start_offset: Integer, length: Integer) -> void - def initialize(value, target, operator_loc, start_offset, length) + # def initialize: (value: Node, target: Node, operator_loc: Location, location: Location) -> void + def initialize(value, target, operator_loc, location) @value = value @target = target @operator_loc = operator_loc - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -907,6 +1017,11 @@ module YARP def deconstruct_keys(keys) { value: value, target: target, operator_loc: operator_loc, location: location } end + + # def operator: () -> String + def operator + operator_loc.slice + end end # Represents the use of a case statement. @@ -931,15 +1046,14 @@ module YARP # attr_reader end_keyword_loc: Location attr_reader :end_keyword_loc - # def initialize: (predicate: Node?, conditions: Array[Node], consequent: Node?, case_keyword_loc: Location, end_keyword_loc: Location, start_offset: Integer, length: Integer) -> void - def initialize(predicate, conditions, consequent, case_keyword_loc, end_keyword_loc, start_offset, length) + # def initialize: (predicate: Node?, conditions: Array[Node], consequent: Node?, case_keyword_loc: Location, end_keyword_loc: Location, location: Location) -> void + def initialize(predicate, conditions, consequent, case_keyword_loc, end_keyword_loc, location) @predicate = predicate @conditions = conditions @consequent = consequent @case_keyword_loc = case_keyword_loc @end_keyword_loc = end_keyword_loc - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -959,6 +1073,16 @@ module YARP def deconstruct_keys(keys) { predicate: predicate, conditions: conditions, consequent: consequent, case_keyword_loc: case_keyword_loc, end_keyword_loc: end_keyword_loc, location: location } end + + # def case_keyword: () -> String + def case_keyword + case_keyword_loc.slice + end + + # def end_keyword: () -> String + def end_keyword + end_keyword_loc.slice + end end # Represents a class declaration involving the `class` keyword. @@ -987,8 +1111,8 @@ module YARP # attr_reader end_keyword_loc: Location attr_reader :end_keyword_loc - # def initialize: (locals: Array[Symbol], class_keyword_loc: Location, constant_path: Node, inheritance_operator_loc: Location?, superclass: Node?, statements: Node?, end_keyword_loc: Location, start_offset: Integer, length: Integer) -> void - def initialize(locals, class_keyword_loc, constant_path, inheritance_operator_loc, superclass, statements, end_keyword_loc, start_offset, length) + # def initialize: (locals: Array[Symbol], class_keyword_loc: Location, constant_path: Node, inheritance_operator_loc: Location?, superclass: Node?, statements: Node?, end_keyword_loc: Location, location: Location) -> void + def initialize(locals, class_keyword_loc, constant_path, inheritance_operator_loc, superclass, statements, end_keyword_loc, location) @locals = locals @class_keyword_loc = class_keyword_loc @constant_path = constant_path @@ -996,8 +1120,7 @@ module YARP @superclass = superclass @statements = statements @end_keyword_loc = end_keyword_loc - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -1017,6 +1140,21 @@ module YARP def deconstruct_keys(keys) { locals: locals, class_keyword_loc: class_keyword_loc, constant_path: constant_path, inheritance_operator_loc: inheritance_operator_loc, superclass: superclass, statements: statements, end_keyword_loc: end_keyword_loc, location: location } end + + # def class_keyword: () -> String + def class_keyword + class_keyword_loc.slice + end + + # def inheritance_operator: () -> String? + def inheritance_operator + inheritance_operator_loc&.slice + end + + # def end_keyword: () -> String + def end_keyword + end_keyword_loc.slice + end end # Represents the use of the `&&=` operator for assignment to a class variable. @@ -1033,13 +1171,12 @@ module YARP # attr_reader value: Node attr_reader :value - # def initialize: (name_loc: Location, operator_loc: Location, value: Node, start_offset: Integer, length: Integer) -> void - def initialize(name_loc, operator_loc, value, start_offset, length) + # def initialize: (name_loc: Location, operator_loc: Location, value: Node, location: Location) -> void + def initialize(name_loc, operator_loc, value, location) @name_loc = name_loc @operator_loc = operator_loc @value = value - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -1059,6 +1196,16 @@ module YARP def deconstruct_keys(keys) { name_loc: name_loc, operator_loc: operator_loc, value: value, location: location } end + + # def name: () -> String + def name + name_loc.slice + end + + # def operator: () -> String + def operator + operator_loc.slice + end end # Represents the use of the `||=` operator for assignment to a class variable. @@ -1075,13 +1222,12 @@ module YARP # attr_reader value: Node attr_reader :value - # def initialize: (name_loc: Location, operator_loc: Location, value: Node, start_offset: Integer, length: Integer) -> void - def initialize(name_loc, operator_loc, value, start_offset, length) + # def initialize: (name_loc: Location, operator_loc: Location, value: Node, location: Location) -> void + def initialize(name_loc, operator_loc, value, location) @name_loc = name_loc @operator_loc = operator_loc @value = value - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -1101,6 +1247,16 @@ module YARP def deconstruct_keys(keys) { name_loc: name_loc, operator_loc: operator_loc, value: value, location: location } end + + # def name: () -> String + def name + name_loc.slice + end + + # def operator: () -> String + def operator + operator_loc.slice + end end # Represents assigning to a class variable using an operator that isn't `=`. @@ -1120,14 +1276,13 @@ module YARP # attr_reader operator: Symbol attr_reader :operator - # def initialize: (name_loc: Location, operator_loc: Location, value: Node, operator: Symbol, start_offset: Integer, length: Integer) -> void - def initialize(name_loc, operator_loc, value, operator, start_offset, length) + # def initialize: (name_loc: Location, operator_loc: Location, value: Node, operator: Symbol, location: Location) -> void + def initialize(name_loc, operator_loc, value, operator, location) @name_loc = name_loc @operator_loc = operator_loc @value = value @operator = operator - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -1147,6 +1302,11 @@ module YARP def deconstruct_keys(keys) { name_loc: name_loc, operator_loc: operator_loc, value: value, operator: operator, location: location } end + + # def name: () -> String + def name + name_loc.slice + end end # Represents referencing a class variable. @@ -1154,10 +1314,9 @@ module YARP # @@foo # ^^^^^ class ClassVariableReadNode < Node - # def initialize: (start_offset: Integer, length: Integer) -> void - def initialize(start_offset, length) - @start_offset = start_offset - @length = length + # def initialize: (location: Location) -> void + def initialize(location) + @location = location end # def accept: (visitor: Visitor) -> void @@ -1193,13 +1352,12 @@ module YARP # attr_reader operator_loc: Location? attr_reader :operator_loc - # def initialize: (name_loc: Location, value: Node?, operator_loc: Location?, start_offset: Integer, length: Integer) -> void - def initialize(name_loc, value, operator_loc, start_offset, length) + # 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 - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -1219,6 +1377,16 @@ module YARP 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 the use of the `&&=` operator for assignment to a constant. @@ -1235,13 +1403,12 @@ module YARP # attr_reader value: Node attr_reader :value - # def initialize: (name_loc: Location, operator_loc: Location, value: Node, start_offset: Integer, length: Integer) -> void - def initialize(name_loc, operator_loc, value, start_offset, length) + # def initialize: (name_loc: Location, operator_loc: Location, value: Node, location: Location) -> void + def initialize(name_loc, operator_loc, value, location) @name_loc = name_loc @operator_loc = operator_loc @value = value - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -1261,6 +1428,16 @@ module YARP def deconstruct_keys(keys) { name_loc: name_loc, operator_loc: operator_loc, value: value, location: location } end + + # def name: () -> String + def name + name_loc.slice + end + + # def operator: () -> String + def operator + operator_loc.slice + end end # Represents the use of the `||=` operator for assignment to a constant. @@ -1277,13 +1454,12 @@ module YARP # attr_reader value: Node attr_reader :value - # def initialize: (name_loc: Location, operator_loc: Location, value: Node, start_offset: Integer, length: Integer) -> void - def initialize(name_loc, operator_loc, value, start_offset, length) + # def initialize: (name_loc: Location, operator_loc: Location, value: Node, location: Location) -> void + def initialize(name_loc, operator_loc, value, location) @name_loc = name_loc @operator_loc = operator_loc @value = value - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -1303,6 +1479,16 @@ module YARP def deconstruct_keys(keys) { name_loc: name_loc, operator_loc: operator_loc, value: value, location: location } end + + # def name: () -> String + def name + name_loc.slice + end + + # def operator: () -> String + def operator + operator_loc.slice + end end # Represents assigning to a constant using an operator that isn't `=`. @@ -1322,14 +1508,13 @@ module YARP # attr_reader operator: Symbol attr_reader :operator - # def initialize: (name_loc: Location, operator_loc: Location, value: Node, operator: Symbol, start_offset: Integer, length: Integer) -> void - def initialize(name_loc, operator_loc, value, operator, start_offset, length) + # def initialize: (name_loc: Location, operator_loc: Location, value: Node, operator: Symbol, location: Location) -> void + def initialize(name_loc, operator_loc, value, operator, location) @name_loc = name_loc @operator_loc = operator_loc @value = value @operator = operator - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -1349,6 +1534,11 @@ module YARP def deconstruct_keys(keys) { name_loc: name_loc, operator_loc: operator_loc, value: value, operator: operator, location: location } end + + # def name: () -> String + def name + name_loc.slice + end end # Represents accessing a constant through a path of `::` operators. @@ -1365,13 +1555,12 @@ module YARP # attr_reader delimiter_loc: Location attr_reader :delimiter_loc - # def initialize: (parent: Node?, child: Node, delimiter_loc: Location, start_offset: Integer, length: Integer) -> void - def initialize(parent, child, delimiter_loc, start_offset, length) + # def initialize: (parent: Node?, child: Node, delimiter_loc: Location, location: Location) -> void + def initialize(parent, child, delimiter_loc, location) @parent = parent @child = child @delimiter_loc = delimiter_loc - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -1391,6 +1580,11 @@ module YARP def deconstruct_keys(keys) { parent: parent, child: child, delimiter_loc: delimiter_loc, location: location } end + + # def delimiter: () -> String + def delimiter + delimiter_loc.slice + end end # Represents the use of the `&&=` operator for assignment to a constant path. @@ -1407,13 +1601,12 @@ module YARP # attr_reader value: Node attr_reader :value - # def initialize: (target: Node, operator_loc: Location, value: Node, start_offset: Integer, length: Integer) -> void - def initialize(target, operator_loc, value, start_offset, length) + # def initialize: (target: Node, operator_loc: Location, value: Node, location: Location) -> void + def initialize(target, operator_loc, value, location) @target = target @operator_loc = operator_loc @value = value - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -1433,6 +1626,11 @@ module YARP def deconstruct_keys(keys) { target: target, operator_loc: operator_loc, value: value, location: location } end + + # def operator: () -> String + def operator + operator_loc.slice + end end # Represents the use of the `||=` operator for assignment to a constant path. @@ -1449,13 +1647,12 @@ module YARP # attr_reader value: Node attr_reader :value - # def initialize: (target: Node, operator_loc: Location, value: Node, start_offset: Integer, length: Integer) -> void - def initialize(target, operator_loc, value, start_offset, length) + # def initialize: (target: Node, operator_loc: Location, value: Node, location: Location) -> void + def initialize(target, operator_loc, value, location) @target = target @operator_loc = operator_loc @value = value - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -1475,6 +1672,11 @@ module YARP def deconstruct_keys(keys) { target: target, operator_loc: operator_loc, value: value, location: location } end + + # def operator: () -> String + def operator + operator_loc.slice + end end # Represents assigning to a constant path using an operator that isn't `=`. @@ -1494,14 +1696,13 @@ module YARP # attr_reader operator: Symbol attr_reader :operator - # def initialize: (target: Node, operator_loc: Location, value: Node, operator: Symbol, start_offset: Integer, length: Integer) -> void - def initialize(target, operator_loc, value, operator, start_offset, length) + # def initialize: (target: Node, operator_loc: Location, value: Node, operator: Symbol, location: Location) -> void + def initialize(target, operator_loc, value, operator, location) @target = target @operator_loc = operator_loc @value = value @operator = operator - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -1540,13 +1741,12 @@ module YARP # attr_reader value: Node? attr_reader :value - # def initialize: (target: Node, operator_loc: Location?, value: Node?, start_offset: Integer, length: Integer) -> void - def initialize(target, operator_loc, value, start_offset, length) + # def initialize: (target: Node, operator_loc: Location?, value: Node?, location: Location) -> void + def initialize(target, operator_loc, value, location) @target = target @operator_loc = operator_loc @value = value - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -1566,6 +1766,11 @@ module YARP def deconstruct_keys(keys) { target: target, operator_loc: operator_loc, value: value, location: location } end + + # def operator: () -> String? + def operator + operator_loc&.slice + end end # Represents referencing a constant. @@ -1573,10 +1778,9 @@ module YARP # Foo # ^^^ class ConstantReadNode < Node - # def initialize: (start_offset: Integer, length: Integer) -> void - def initialize(start_offset, length) - @start_offset = start_offset - @length = length + # def initialize: (location: Location) -> void + def initialize(location) + @location = location end # def accept: (visitor: Visitor) -> void @@ -1637,8 +1841,8 @@ module YARP # attr_reader end_keyword_loc: Location? attr_reader :end_keyword_loc - # def initialize: (name_loc: Location, receiver: Node?, parameters: Node?, statements: Node?, locals: Array[Symbol], def_keyword_loc: Location, operator_loc: Location?, lparen_loc: Location?, rparen_loc: Location?, equal_loc: Location?, end_keyword_loc: Location?, start_offset: Integer, length: Integer) -> void - def initialize(name_loc, receiver, parameters, statements, locals, def_keyword_loc, operator_loc, lparen_loc, rparen_loc, equal_loc, end_keyword_loc, start_offset, length) + # def initialize: (name_loc: Location, receiver: Node?, parameters: Node?, statements: Node?, locals: Array[Symbol], def_keyword_loc: Location, operator_loc: Location?, lparen_loc: Location?, rparen_loc: Location?, equal_loc: Location?, end_keyword_loc: Location?, location: Location) -> void + def initialize(name_loc, receiver, parameters, statements, locals, def_keyword_loc, operator_loc, lparen_loc, rparen_loc, equal_loc, end_keyword_loc, location) @name_loc = name_loc @receiver = receiver @parameters = parameters @@ -1650,8 +1854,7 @@ module YARP @rparen_loc = rparen_loc @equal_loc = equal_loc @end_keyword_loc = end_keyword_loc - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -1671,6 +1874,41 @@ module YARP def deconstruct_keys(keys) { name_loc: name_loc, receiver: receiver, parameters: parameters, statements: statements, locals: locals, def_keyword_loc: def_keyword_loc, operator_loc: operator_loc, lparen_loc: lparen_loc, rparen_loc: rparen_loc, equal_loc: equal_loc, end_keyword_loc: end_keyword_loc, location: location } end + + # def name: () -> String + def name + name_loc.slice + end + + # def def_keyword: () -> String + def def_keyword + def_keyword_loc.slice + end + + # def operator: () -> String? + def operator + operator_loc&.slice + end + + # def lparen: () -> String? + def lparen + lparen_loc&.slice + end + + # def rparen: () -> String? + def rparen + rparen_loc&.slice + end + + # def equal: () -> String? + def equal + equal_loc&.slice + end + + # def end_keyword: () -> String? + def end_keyword + end_keyword_loc&.slice + end end # Represents the use of the `defined?` keyword. @@ -1690,14 +1928,13 @@ module YARP # attr_reader keyword_loc: Location attr_reader :keyword_loc - # def initialize: (lparen_loc: Location?, value: Node, rparen_loc: Location?, keyword_loc: Location, start_offset: Integer, length: Integer) -> void - def initialize(lparen_loc, value, rparen_loc, keyword_loc, start_offset, length) + # def initialize: (lparen_loc: Location?, value: Node, rparen_loc: Location?, keyword_loc: Location, location: Location) -> void + def initialize(lparen_loc, value, rparen_loc, keyword_loc, location) @lparen_loc = lparen_loc @value = value @rparen_loc = rparen_loc @keyword_loc = keyword_loc - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -1717,6 +1954,21 @@ module YARP def deconstruct_keys(keys) { lparen_loc: lparen_loc, value: value, rparen_loc: rparen_loc, keyword_loc: keyword_loc, location: location } end + + # def lparen: () -> String? + def lparen + lparen_loc&.slice + end + + # def rparen: () -> String? + def rparen + rparen_loc&.slice + end + + # def keyword: () -> String + def keyword + keyword_loc.slice + end end # Represents an `else` clause in a `case`, `if`, or `unless` statement. @@ -1733,13 +1985,12 @@ module YARP # attr_reader end_keyword_loc: Location? attr_reader :end_keyword_loc - # def initialize: (else_keyword_loc: Location, statements: Node?, end_keyword_loc: Location?, start_offset: Integer, length: Integer) -> void - def initialize(else_keyword_loc, statements, end_keyword_loc, start_offset, length) + # def initialize: (else_keyword_loc: Location, statements: Node?, end_keyword_loc: Location?, location: Location) -> void + def initialize(else_keyword_loc, statements, end_keyword_loc, location) @else_keyword_loc = else_keyword_loc @statements = statements @end_keyword_loc = end_keyword_loc - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -1759,6 +2010,16 @@ module YARP def deconstruct_keys(keys) { else_keyword_loc: else_keyword_loc, statements: statements, end_keyword_loc: end_keyword_loc, location: location } end + + # def else_keyword: () -> String + def else_keyword + else_keyword_loc.slice + end + + # def end_keyword: () -> String? + def end_keyword + end_keyword_loc&.slice + end end # Represents an interpolated set of statements. @@ -1775,13 +2036,12 @@ module YARP # attr_reader closing_loc: Location attr_reader :closing_loc - # def initialize: (opening_loc: Location, statements: Node?, closing_loc: Location, start_offset: Integer, length: Integer) -> void - def initialize(opening_loc, statements, closing_loc, start_offset, length) + # def initialize: (opening_loc: Location, statements: Node?, closing_loc: Location, location: Location) -> void + def initialize(opening_loc, statements, closing_loc, location) @opening_loc = opening_loc @statements = statements @closing_loc = closing_loc - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -1801,6 +2061,16 @@ module YARP def deconstruct_keys(keys) { opening_loc: opening_loc, statements: statements, closing_loc: closing_loc, location: location } end + + # def opening: () -> String + def opening + opening_loc.slice + end + + # def closing: () -> String + def closing + closing_loc.slice + end end # Represents an interpolated variable. @@ -1814,12 +2084,11 @@ module YARP # attr_reader variable: Node attr_reader :variable - # def initialize: (operator_loc: Location, variable: Node, start_offset: Integer, length: Integer) -> void - def initialize(operator_loc, variable, start_offset, length) + # def initialize: (operator_loc: Location, variable: Node, location: Location) -> void + def initialize(operator_loc, variable, location) @operator_loc = operator_loc @variable = variable - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -1839,6 +2108,11 @@ module YARP def deconstruct_keys(keys) { operator_loc: operator_loc, variable: variable, location: location } end + + # def operator: () -> String + def operator + operator_loc.slice + end end # Represents an `ensure` clause in a `begin` statement. @@ -1859,13 +2133,12 @@ module YARP # attr_reader end_keyword_loc: Location attr_reader :end_keyword_loc - # def initialize: (ensure_keyword_loc: Location, statements: Node?, end_keyword_loc: Location, start_offset: Integer, length: Integer) -> void - def initialize(ensure_keyword_loc, statements, end_keyword_loc, start_offset, length) + # def initialize: (ensure_keyword_loc: Location, statements: Node?, end_keyword_loc: Location, location: Location) -> void + def initialize(ensure_keyword_loc, statements, end_keyword_loc, location) @ensure_keyword_loc = ensure_keyword_loc @statements = statements @end_keyword_loc = end_keyword_loc - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -1885,6 +2158,16 @@ module YARP def deconstruct_keys(keys) { ensure_keyword_loc: ensure_keyword_loc, statements: statements, end_keyword_loc: end_keyword_loc, location: location } end + + # def ensure_keyword: () -> String + def ensure_keyword + ensure_keyword_loc.slice + end + + # def end_keyword: () -> String + def end_keyword + end_keyword_loc.slice + end end # Represents the use of the literal `false` keyword. @@ -1892,10 +2175,9 @@ module YARP # false # ^^^^^ class FalseNode < Node - # def initialize: (start_offset: Integer, length: Integer) -> void - def initialize(start_offset, length) - @start_offset = start_offset - @length = length + # def initialize: (location: Location) -> void + def initialize(location) + @location = location end # def accept: (visitor: Visitor) -> void @@ -1946,16 +2228,15 @@ module YARP # attr_reader closing_loc: Location? attr_reader :closing_loc - # def initialize: (constant: Node?, left: Node, requireds: Array[Node], right: Node, opening_loc: Location?, closing_loc: Location?, start_offset: Integer, length: Integer) -> void - def initialize(constant, left, requireds, right, opening_loc, closing_loc, start_offset, length) + # def initialize: (constant: Node?, left: Node, requireds: Array[Node], right: Node, opening_loc: Location?, closing_loc: Location?, location: Location) -> void + def initialize(constant, left, requireds, right, opening_loc, closing_loc, location) @constant = constant @left = left @requireds = requireds @right = right @opening_loc = opening_loc @closing_loc = closing_loc - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -1975,6 +2256,16 @@ module YARP def deconstruct_keys(keys) { constant: constant, left: left, requireds: requireds, right: right, opening_loc: opening_loc, closing_loc: closing_loc, location: location } end + + # def opening: () -> String? + def opening + opening_loc&.slice + end + + # def closing: () -> String? + def closing + closing_loc&.slice + end end # Represents a floating point number literal. @@ -1982,10 +2273,9 @@ module YARP # 1.0 # ^^^ class FloatNode < Node - # def initialize: (start_offset: Integer, length: Integer) -> void - def initialize(start_offset, length) - @start_offset = start_offset - @length = length + # def initialize: (location: Location) -> void + def initialize(location) + @location = location end # def accept: (visitor: Visitor) -> void @@ -2033,8 +2323,8 @@ module YARP # attr_reader end_keyword_loc: Location attr_reader :end_keyword_loc - # def initialize: (index: Node, collection: Node, statements: Node?, for_keyword_loc: Location, in_keyword_loc: Location, do_keyword_loc: Location?, end_keyword_loc: Location, start_offset: Integer, length: Integer) -> void - def initialize(index, collection, statements, for_keyword_loc, in_keyword_loc, do_keyword_loc, end_keyword_loc, start_offset, length) + # def initialize: (index: Node, collection: Node, statements: Node?, for_keyword_loc: Location, in_keyword_loc: Location, do_keyword_loc: Location?, end_keyword_loc: Location, location: Location) -> void + def initialize(index, collection, statements, for_keyword_loc, in_keyword_loc, do_keyword_loc, end_keyword_loc, location) @index = index @collection = collection @statements = statements @@ -2042,8 +2332,7 @@ module YARP @in_keyword_loc = in_keyword_loc @do_keyword_loc = do_keyword_loc @end_keyword_loc = end_keyword_loc - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -2063,6 +2352,26 @@ module YARP def deconstruct_keys(keys) { index: index, collection: collection, statements: statements, for_keyword_loc: for_keyword_loc, in_keyword_loc: in_keyword_loc, do_keyword_loc: do_keyword_loc, end_keyword_loc: end_keyword_loc, location: location } end + + # def for_keyword: () -> String + def for_keyword + for_keyword_loc.slice + end + + # def in_keyword: () -> String + def in_keyword + in_keyword_loc.slice + end + + # def do_keyword: () -> String? + def do_keyword + do_keyword_loc&.slice + end + + # def end_keyword: () -> String + def end_keyword + end_keyword_loc.slice + end end # Represents forwarding all arguments to this method to another method. @@ -2072,10 +2381,9 @@ module YARP # ^^^^^^^^ # end class ForwardingArgumentsNode < Node - # def initialize: (start_offset: Integer, length: Integer) -> void - def initialize(start_offset, length) - @start_offset = start_offset - @length = length + # def initialize: (location: Location) -> void + def initialize(location) + @location = location end # def accept: (visitor: Visitor) -> void @@ -2103,10 +2411,9 @@ module YARP # ^^^ # end class ForwardingParameterNode < Node - # def initialize: (start_offset: Integer, length: Integer) -> void - def initialize(start_offset, length) - @start_offset = start_offset - @length = length + # def initialize: (location: Location) -> void + def initialize(location) + @location = location end # def accept: (visitor: Visitor) -> void @@ -2136,11 +2443,10 @@ module YARP # attr_reader block: Node? attr_reader :block - # def initialize: (block: Node?, start_offset: Integer, length: Integer) -> void - def initialize(block, start_offset, length) + # def initialize: (block: Node?, location: Location) -> void + def initialize(block, location) @block = block - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -2176,13 +2482,12 @@ module YARP # attr_reader value: Node attr_reader :value - # def initialize: (name_loc: Location, operator_loc: Location, value: Node, start_offset: Integer, length: Integer) -> void - def initialize(name_loc, operator_loc, value, start_offset, length) + # def initialize: (name_loc: Location, operator_loc: Location, value: Node, location: Location) -> void + def initialize(name_loc, operator_loc, value, location) @name_loc = name_loc @operator_loc = operator_loc @value = value - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -2202,6 +2507,16 @@ module YARP def deconstruct_keys(keys) { name_loc: name_loc, operator_loc: operator_loc, value: value, location: location } end + + # def name: () -> String + def name + name_loc.slice + end + + # def operator: () -> String + def operator + operator_loc.slice + end end # Represents the use of the `||=` operator for assignment to a global variable. @@ -2218,13 +2533,12 @@ module YARP # attr_reader value: Node attr_reader :value - # def initialize: (name_loc: Location, operator_loc: Location, value: Node, start_offset: Integer, length: Integer) -> void - def initialize(name_loc, operator_loc, value, start_offset, length) + # def initialize: (name_loc: Location, operator_loc: Location, value: Node, location: Location) -> void + def initialize(name_loc, operator_loc, value, location) @name_loc = name_loc @operator_loc = operator_loc @value = value - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -2244,6 +2558,16 @@ module YARP def deconstruct_keys(keys) { name_loc: name_loc, operator_loc: operator_loc, value: value, location: location } end + + # def name: () -> String + def name + name_loc.slice + end + + # def operator: () -> String + def operator + operator_loc.slice + end end # Represents assigning to a global variable using an operator that isn't `=`. @@ -2263,14 +2587,13 @@ module YARP # attr_reader operator: Symbol attr_reader :operator - # def initialize: (name_loc: Location, operator_loc: Location, value: Node, operator: Symbol, start_offset: Integer, length: Integer) -> void - def initialize(name_loc, operator_loc, value, operator, start_offset, length) + # def initialize: (name_loc: Location, operator_loc: Location, value: Node, operator: Symbol, location: Location) -> void + def initialize(name_loc, operator_loc, value, operator, location) @name_loc = name_loc @operator_loc = operator_loc @value = value @operator = operator - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -2290,6 +2613,11 @@ module YARP def deconstruct_keys(keys) { name_loc: name_loc, operator_loc: operator_loc, value: value, operator: operator, location: location } end + + # def name: () -> String + def name + name_loc.slice + end end # Represents referencing a global variable. @@ -2297,10 +2625,9 @@ module YARP # $foo # ^^^^ class GlobalVariableReadNode < Node - # def initialize: (start_offset: Integer, length: Integer) -> void - def initialize(start_offset, length) - @start_offset = start_offset - @length = length + # def initialize: (location: Location) -> void + def initialize(location) + @location = location end # def accept: (visitor: Visitor) -> void @@ -2336,13 +2663,12 @@ module YARP # attr_reader value: Node? attr_reader :value - # def initialize: (name_loc: Location, operator_loc: Location?, value: Node?, start_offset: Integer, length: Integer) -> void - def initialize(name_loc, operator_loc, value, start_offset, length) + # def initialize: (name_loc: Location, operator_loc: Location?, value: Node?, location: Location) -> void + def initialize(name_loc, operator_loc, value, location) @name_loc = name_loc @operator_loc = operator_loc @value = value - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -2362,6 +2688,16 @@ module YARP def deconstruct_keys(keys) { name_loc: name_loc, operator_loc: operator_loc, value: value, location: location } end + + # def name: () -> String + def name + name_loc.slice + end + + # def operator: () -> String? + def operator + operator_loc&.slice + end end # Represents a hash literal. @@ -2378,13 +2714,12 @@ module YARP # attr_reader closing_loc: Location attr_reader :closing_loc - # def initialize: (opening_loc: Location, elements: Array[Node], closing_loc: Location, start_offset: Integer, length: Integer) -> void - def initialize(opening_loc, elements, closing_loc, start_offset, length) + # def initialize: (opening_loc: Location, elements: Array[Node], closing_loc: Location, location: Location) -> void + def initialize(opening_loc, elements, closing_loc, location) @opening_loc = opening_loc @elements = elements @closing_loc = closing_loc - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -2404,6 +2739,16 @@ module YARP def deconstruct_keys(keys) { opening_loc: opening_loc, elements: elements, closing_loc: closing_loc, location: location } end + + # def opening: () -> String + def opening + opening_loc.slice + end + + # def closing: () -> String + def closing + closing_loc.slice + end end # Represents a hash pattern in pattern matching. @@ -2429,15 +2774,14 @@ module YARP # attr_reader closing_loc: Location? attr_reader :closing_loc - # def initialize: (constant: Node?, assocs: Array[Node], kwrest: Node?, opening_loc: Location?, closing_loc: Location?, start_offset: Integer, length: Integer) -> void - def initialize(constant, assocs, kwrest, opening_loc, closing_loc, start_offset, length) + # def initialize: (constant: Node?, assocs: Array[Node], kwrest: Node?, opening_loc: Location?, closing_loc: Location?, location: Location) -> void + def initialize(constant, assocs, kwrest, opening_loc, closing_loc, location) @constant = constant @assocs = assocs @kwrest = kwrest @opening_loc = opening_loc @closing_loc = closing_loc - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -2457,6 +2801,16 @@ module YARP def deconstruct_keys(keys) { constant: constant, assocs: assocs, kwrest: kwrest, opening_loc: opening_loc, closing_loc: closing_loc, location: location } end + + # def opening: () -> String? + def opening + opening_loc&.slice + end + + # def closing: () -> String? + def closing + closing_loc&.slice + end end # Represents the use of the `if` keyword, either in the block form or the modifier form. @@ -2482,15 +2836,14 @@ module YARP # attr_reader end_keyword_loc: Location? attr_reader :end_keyword_loc - # def initialize: (if_keyword_loc: Location?, predicate: Node, statements: Node?, consequent: Node?, end_keyword_loc: Location?, start_offset: Integer, length: Integer) -> void - def initialize(if_keyword_loc, predicate, statements, consequent, end_keyword_loc, start_offset, length) + # def initialize: (if_keyword_loc: Location?, predicate: Node, statements: Node?, consequent: Node?, end_keyword_loc: Location?, location: Location) -> void + def initialize(if_keyword_loc, predicate, statements, consequent, end_keyword_loc, location) @if_keyword_loc = if_keyword_loc @predicate = predicate @statements = statements @consequent = consequent @end_keyword_loc = end_keyword_loc - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -2510,6 +2863,16 @@ module YARP def deconstruct_keys(keys) { if_keyword_loc: if_keyword_loc, predicate: predicate, statements: statements, consequent: consequent, end_keyword_loc: end_keyword_loc, location: location } end + + # def if_keyword: () -> String? + def if_keyword + if_keyword_loc&.slice + end + + # def end_keyword: () -> String? + def end_keyword + end_keyword_loc&.slice + end end # Represents an imaginary number literal. @@ -2520,11 +2883,10 @@ module YARP # attr_reader numeric: Node attr_reader :numeric - # def initialize: (numeric: Node, start_offset: Integer, length: Integer) -> void - def initialize(numeric, start_offset, length) + # def initialize: (numeric: Node, location: Location) -> void + def initialize(numeric, location) @numeric = numeric - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -2563,14 +2925,13 @@ module YARP # attr_reader then_loc: Location? attr_reader :then_loc - # def initialize: (pattern: Node, statements: Node?, in_loc: Location, then_loc: Location?, start_offset: Integer, length: Integer) -> void - def initialize(pattern, statements, in_loc, then_loc, start_offset, length) + # def initialize: (pattern: Node, statements: Node?, in_loc: Location, then_loc: Location?, location: Location) -> void + def initialize(pattern, statements, in_loc, then_loc, location) @pattern = pattern @statements = statements @in_loc = in_loc @then_loc = then_loc - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -2590,6 +2951,16 @@ module YARP def deconstruct_keys(keys) { pattern: pattern, statements: statements, in_loc: in_loc, then_loc: then_loc, location: location } end + + # def in: () -> String + def in + in_loc.slice + end + + # def then: () -> String? + def then + then_loc&.slice + end end # Represents the use of the `&&=` operator for assignment to an instance variable. @@ -2606,13 +2977,12 @@ module YARP # attr_reader value: Node attr_reader :value - # def initialize: (name_loc: Location, operator_loc: Location, value: Node, start_offset: Integer, length: Integer) -> void - def initialize(name_loc, operator_loc, value, start_offset, length) + # def initialize: (name_loc: Location, operator_loc: Location, value: Node, location: Location) -> void + def initialize(name_loc, operator_loc, value, location) @name_loc = name_loc @operator_loc = operator_loc @value = value - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -2632,6 +3002,16 @@ module YARP def deconstruct_keys(keys) { name_loc: name_loc, operator_loc: operator_loc, value: value, location: location } end + + # def name: () -> String + def name + name_loc.slice + end + + # def operator: () -> String + def operator + operator_loc.slice + end end # Represents the use of the `||=` operator for assignment to an instance variable. @@ -2648,13 +3028,12 @@ module YARP # attr_reader value: Node attr_reader :value - # def initialize: (name_loc: Location, operator_loc: Location, value: Node, start_offset: Integer, length: Integer) -> void - def initialize(name_loc, operator_loc, value, start_offset, length) + # def initialize: (name_loc: Location, operator_loc: Location, value: Node, location: Location) -> void + def initialize(name_loc, operator_loc, value, location) @name_loc = name_loc @operator_loc = operator_loc @value = value - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -2674,6 +3053,16 @@ module YARP def deconstruct_keys(keys) { name_loc: name_loc, operator_loc: operator_loc, value: value, location: location } end + + # def name: () -> String + def name + name_loc.slice + end + + # def operator: () -> String + def operator + operator_loc.slice + end end # Represents assigning to an instance variable using an operator that isn't `=`. @@ -2693,14 +3082,13 @@ module YARP # attr_reader operator: Symbol attr_reader :operator - # def initialize: (name_loc: Location, operator_loc: Location, value: Node, operator: Symbol, start_offset: Integer, length: Integer) -> void - def initialize(name_loc, operator_loc, value, operator, start_offset, length) + # def initialize: (name_loc: Location, operator_loc: Location, value: Node, operator: Symbol, location: Location) -> void + def initialize(name_loc, operator_loc, value, operator, location) @name_loc = name_loc @operator_loc = operator_loc @value = value @operator = operator - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -2720,6 +3108,11 @@ module YARP def deconstruct_keys(keys) { name_loc: name_loc, operator_loc: operator_loc, value: value, operator: operator, location: location } end + + # def name: () -> String + def name + name_loc.slice + end end # Represents referencing an instance variable. @@ -2727,10 +3120,9 @@ module YARP # @foo # ^^^^ class InstanceVariableReadNode < Node - # def initialize: (start_offset: Integer, length: Integer) -> void - def initialize(start_offset, length) - @start_offset = start_offset - @length = length + # def initialize: (location: Location) -> void + def initialize(location) + @location = location end # def accept: (visitor: Visitor) -> void @@ -2766,13 +3158,12 @@ module YARP # attr_reader operator_loc: Location? attr_reader :operator_loc - # def initialize: (name_loc: Location, value: Node?, operator_loc: Location?, start_offset: Integer, length: Integer) -> void - def initialize(name_loc, value, operator_loc, start_offset, length) + # 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 - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -2792,6 +3183,16 @@ module YARP 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 an integer number literal. @@ -2799,10 +3200,9 @@ module YARP # 1 # ^ class IntegerNode < Node - # def initialize: (start_offset: Integer, length: Integer) -> void - def initialize(start_offset, length) - @start_offset = start_offset - @length = length + # def initialize: (location: Location) -> void + def initialize(location) + @location = location end # def accept: (visitor: Visitor) -> void @@ -2841,14 +3241,13 @@ module YARP # attr_reader flags: Integer attr_reader :flags - # def initialize: (opening_loc: Location, parts: Array[Node], closing_loc: Location, flags: Integer, start_offset: Integer, length: Integer) -> void - def initialize(opening_loc, parts, closing_loc, flags, start_offset, length) + # def initialize: (opening_loc: Location, parts: Array[Node], closing_loc: Location, flags: Integer, location: Location) -> void + def initialize(opening_loc, parts, closing_loc, flags, location) @opening_loc = opening_loc @parts = parts @closing_loc = closing_loc @flags = flags - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -2868,6 +3267,16 @@ module YARP def deconstruct_keys(keys) { opening_loc: opening_loc, parts: parts, closing_loc: closing_loc, flags: flags, location: location } end + + # def opening: () -> String + def opening + opening_loc.slice + end + + # def closing: () -> String + def closing + closing_loc.slice + end end # Represents a string literal that contains interpolation. @@ -2884,13 +3293,12 @@ module YARP # attr_reader closing_loc: Location? attr_reader :closing_loc - # def initialize: (opening_loc: Location?, parts: Array[Node], closing_loc: Location?, start_offset: Integer, length: Integer) -> void - def initialize(opening_loc, parts, closing_loc, start_offset, length) + # def initialize: (opening_loc: Location?, parts: Array[Node], closing_loc: Location?, location: Location) -> void + def initialize(opening_loc, parts, closing_loc, location) @opening_loc = opening_loc @parts = parts @closing_loc = closing_loc - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -2910,6 +3318,16 @@ module YARP def deconstruct_keys(keys) { opening_loc: opening_loc, parts: parts, closing_loc: closing_loc, location: location } end + + # def opening: () -> String? + def opening + opening_loc&.slice + end + + # def closing: () -> String? + def closing + closing_loc&.slice + end end # Represents a symbol literal that contains interpolation. @@ -2926,13 +3344,12 @@ module YARP # attr_reader closing_loc: Location? attr_reader :closing_loc - # def initialize: (opening_loc: Location?, parts: Array[Node], closing_loc: Location?, start_offset: Integer, length: Integer) -> void - def initialize(opening_loc, parts, closing_loc, start_offset, length) + # def initialize: (opening_loc: Location?, parts: Array[Node], closing_loc: Location?, location: Location) -> void + def initialize(opening_loc, parts, closing_loc, location) @opening_loc = opening_loc @parts = parts @closing_loc = closing_loc - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -2952,6 +3369,16 @@ module YARP def deconstruct_keys(keys) { opening_loc: opening_loc, parts: parts, closing_loc: closing_loc, location: location } end + + # def opening: () -> String? + def opening + opening_loc&.slice + end + + # def closing: () -> String? + def closing + closing_loc&.slice + end end # Represents an xstring literal that contains interpolation. @@ -2968,13 +3395,12 @@ module YARP # attr_reader closing_loc: Location attr_reader :closing_loc - # def initialize: (opening_loc: Location, parts: Array[Node], closing_loc: Location, start_offset: Integer, length: Integer) -> void - def initialize(opening_loc, parts, closing_loc, start_offset, length) + # def initialize: (opening_loc: Location, parts: Array[Node], closing_loc: Location, location: Location) -> void + def initialize(opening_loc, parts, closing_loc, location) @opening_loc = opening_loc @parts = parts @closing_loc = closing_loc - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -2994,6 +3420,16 @@ module YARP def deconstruct_keys(keys) { opening_loc: opening_loc, parts: parts, closing_loc: closing_loc, location: location } end + + # def opening: () -> String + def opening + opening_loc.slice + end + + # def closing: () -> String + def closing + closing_loc.slice + end end # Represents a hash literal without opening and closing braces. @@ -3004,11 +3440,10 @@ module YARP # attr_reader elements: Array[Node] attr_reader :elements - # def initialize: (elements: Array[Node], start_offset: Integer, length: Integer) -> void - def initialize(elements, start_offset, length) + # def initialize: (elements: Array[Node], location: Location) -> void + def initialize(elements, location) @elements = elements - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -3046,12 +3481,11 @@ module YARP # attr_reader value: Node? attr_reader :value - # def initialize: (name_loc: Location, value: Node?, start_offset: Integer, length: Integer) -> void - def initialize(name_loc, value, start_offset, length) + # def initialize: (name_loc: Location, value: Node?, location: Location) -> void + def initialize(name_loc, value, location) @name_loc = name_loc @value = value - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -3071,6 +3505,11 @@ module YARP def deconstruct_keys(keys) { name_loc: name_loc, value: value, location: location } end + + # def name: () -> String + def name + name_loc.slice + end end # Represents a keyword rest parameter to a method, block, or lambda definition. @@ -3085,12 +3524,11 @@ module YARP # attr_reader name_loc: Location? attr_reader :name_loc - # def initialize: (operator_loc: Location, name_loc: Location?, start_offset: Integer, length: Integer) -> void - def initialize(operator_loc, name_loc, start_offset, length) + # def initialize: (operator_loc: Location, name_loc: Location?, location: Location) -> void + def initialize(operator_loc, name_loc, location) @operator_loc = operator_loc @name_loc = name_loc - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -3110,6 +3548,16 @@ module YARP def deconstruct_keys(keys) { operator_loc: operator_loc, name_loc: name_loc, location: location } end + + # def operator: () -> String + def operator + operator_loc.slice + end + + # def name: () -> String? + def name + name_loc&.slice + end end # Represents using a lambda literal (not the lambda method call). @@ -3129,14 +3577,13 @@ module YARP # attr_reader statements: Node? attr_reader :statements - # def initialize: (locals: Array[Symbol], opening_loc: Location, parameters: Node?, statements: Node?, start_offset: Integer, length: Integer) -> void - def initialize(locals, opening_loc, parameters, statements, start_offset, length) + # def initialize: (locals: Array[Symbol], opening_loc: Location, parameters: Node?, statements: Node?, location: Location) -> void + def initialize(locals, opening_loc, parameters, statements, location) @locals = locals @opening_loc = opening_loc @parameters = parameters @statements = statements - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -3156,6 +3603,11 @@ module YARP def deconstruct_keys(keys) { locals: locals, opening_loc: opening_loc, parameters: parameters, statements: statements, location: location } end + + # def opening: () -> String + def opening + opening_loc.slice + end end # Represents the use of the `&&=` operator for assignment to a local variable. @@ -3175,14 +3627,13 @@ module YARP # attr_reader constant_id: Symbol attr_reader :constant_id - # def initialize: (name_loc: Location, operator_loc: Location, value: Node, constant_id: Symbol, start_offset: Integer, length: Integer) -> void - def initialize(name_loc, operator_loc, value, constant_id, start_offset, length) + # def initialize: (name_loc: Location, operator_loc: Location, value: Node, constant_id: Symbol, location: Location) -> void + def initialize(name_loc, operator_loc, value, constant_id, location) @name_loc = name_loc @operator_loc = operator_loc @value = value @constant_id = constant_id - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -3202,6 +3653,16 @@ module YARP def deconstruct_keys(keys) { name_loc: name_loc, operator_loc: operator_loc, value: value, constant_id: constant_id, location: location } end + + # def name: () -> String + def name + name_loc.slice + end + + # def operator: () -> String + def operator + operator_loc.slice + end end # Represents the use of the `||=` operator for assignment to a local variable. @@ -3221,14 +3682,13 @@ module YARP # attr_reader constant_id: Symbol attr_reader :constant_id - # def initialize: (name_loc: Location, operator_loc: Location, value: Node, constant_id: Symbol, start_offset: Integer, length: Integer) -> void - def initialize(name_loc, operator_loc, value, constant_id, start_offset, length) + # def initialize: (name_loc: Location, operator_loc: Location, value: Node, constant_id: Symbol, location: Location) -> void + def initialize(name_loc, operator_loc, value, constant_id, location) @name_loc = name_loc @operator_loc = operator_loc @value = value @constant_id = constant_id - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -3248,6 +3708,16 @@ module YARP def deconstruct_keys(keys) { name_loc: name_loc, operator_loc: operator_loc, value: value, constant_id: constant_id, location: location } end + + # def name: () -> String + def name + name_loc.slice + end + + # def operator: () -> String + def operator + operator_loc.slice + end end # Represents assigning to a local variable using an operator that isn't `=`. @@ -3270,15 +3740,14 @@ module YARP # attr_reader operator_id: Symbol attr_reader :operator_id - # def initialize: (name_loc: Location, operator_loc: Location, value: Node, constant_id: Symbol, operator_id: Symbol, start_offset: Integer, length: Integer) -> void - def initialize(name_loc, operator_loc, value, constant_id, operator_id, start_offset, length) + # def initialize: (name_loc: Location, operator_loc: Location, value: Node, constant_id: Symbol, operator_id: Symbol, location: Location) -> void + def initialize(name_loc, operator_loc, value, constant_id, operator_id, location) @name_loc = name_loc @operator_loc = operator_loc @value = value @constant_id = constant_id @operator_id = operator_id - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -3298,6 +3767,16 @@ module YARP def deconstruct_keys(keys) { name_loc: name_loc, operator_loc: operator_loc, value: value, constant_id: constant_id, operator_id: operator_id, location: location } end + + # def name: () -> String + def name + name_loc.slice + end + + # def operator: () -> String + def operator + operator_loc.slice + end end # Represents reading a local variable. Note that this requires that a local @@ -3313,12 +3792,11 @@ module YARP # attr_reader depth: Integer attr_reader :depth - # def initialize: (constant_id: Symbol, depth: Integer, start_offset: Integer, length: Integer) -> void - def initialize(constant_id, depth, start_offset, length) + # def initialize: (constant_id: Symbol, depth: Integer, location: Location) -> void + def initialize(constant_id, depth, location) @constant_id = constant_id @depth = depth - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -3360,15 +3838,14 @@ module YARP # attr_reader operator_loc: Location? attr_reader :operator_loc - # def initialize: (constant_id: Symbol, depth: Integer, value: Node?, name_loc: Location, operator_loc: Location?, start_offset: Integer, length: Integer) -> void - def initialize(constant_id, depth, value, name_loc, operator_loc, start_offset, length) + # def initialize: (constant_id: Symbol, depth: Integer, value: Node?, name_loc: Location, operator_loc: Location?, location: Location) -> void + def initialize(constant_id, depth, value, name_loc, operator_loc, location) @constant_id = constant_id @depth = depth @value = value @name_loc = name_loc @operator_loc = operator_loc - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -3388,6 +3865,16 @@ module YARP def deconstruct_keys(keys) { constant_id: constant_id, depth: depth, value: value, name_loc: name_loc, 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 the use of the modifier `in` operator. @@ -3404,13 +3891,12 @@ module YARP # attr_reader operator_loc: Location attr_reader :operator_loc - # def initialize: (value: Node, pattern: Node, operator_loc: Location, start_offset: Integer, length: Integer) -> void - def initialize(value, pattern, operator_loc, start_offset, length) + # def initialize: (value: Node, pattern: Node, operator_loc: Location, location: Location) -> void + def initialize(value, pattern, operator_loc, location) @value = value @pattern = pattern @operator_loc = operator_loc - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -3430,6 +3916,11 @@ module YARP def deconstruct_keys(keys) { value: value, pattern: pattern, operator_loc: operator_loc, location: location } end + + # def operator: () -> String + def operator + operator_loc.slice + end end # Represents the use of the `=>` operator. @@ -3446,13 +3937,12 @@ module YARP # attr_reader operator_loc: Location attr_reader :operator_loc - # def initialize: (value: Node, pattern: Node, operator_loc: Location, start_offset: Integer, length: Integer) -> void - def initialize(value, pattern, operator_loc, start_offset, length) + # def initialize: (value: Node, pattern: Node, operator_loc: Location, location: Location) -> void + def initialize(value, pattern, operator_loc, location) @value = value @pattern = pattern @operator_loc = operator_loc - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -3472,15 +3962,19 @@ module YARP def deconstruct_keys(keys) { value: value, pattern: pattern, operator_loc: operator_loc, location: location } end + + # def operator: () -> String + def operator + operator_loc.slice + end end # Represents a node that is missing from the source and results in a syntax # error. class MissingNode < Node - # def initialize: (start_offset: Integer, length: Integer) -> void - def initialize(start_offset, length) - @start_offset = start_offset - @length = length + # def initialize: (location: Location) -> void + def initialize(location) + @location = location end # def accept: (visitor: Visitor) -> void @@ -3522,15 +4016,14 @@ module YARP # attr_reader end_keyword_loc: Location attr_reader :end_keyword_loc - # def initialize: (locals: Array[Symbol], module_keyword_loc: Location, constant_path: Node, statements: Node?, end_keyword_loc: Location, start_offset: Integer, length: Integer) -> void - def initialize(locals, module_keyword_loc, constant_path, statements, end_keyword_loc, start_offset, length) + # def initialize: (locals: Array[Symbol], module_keyword_loc: Location, constant_path: Node, statements: Node?, end_keyword_loc: Location, location: Location) -> void + def initialize(locals, module_keyword_loc, constant_path, statements, end_keyword_loc, location) @locals = locals @module_keyword_loc = module_keyword_loc @constant_path = constant_path @statements = statements @end_keyword_loc = end_keyword_loc - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -3550,6 +4043,16 @@ module YARP def deconstruct_keys(keys) { locals: locals, module_keyword_loc: module_keyword_loc, constant_path: constant_path, statements: statements, end_keyword_loc: end_keyword_loc, location: location } end + + # def module_keyword: () -> String + def module_keyword + module_keyword_loc.slice + end + + # def end_keyword: () -> String + def end_keyword + end_keyword_loc.slice + end end # Represents a multi-target expression. @@ -3572,15 +4075,14 @@ module YARP # attr_reader rparen_loc: Location? attr_reader :rparen_loc - # def initialize: (targets: Array[Node], operator_loc: Location?, value: Node?, lparen_loc: Location?, rparen_loc: Location?, start_offset: Integer, length: Integer) -> void - def initialize(targets, operator_loc, value, lparen_loc, rparen_loc, start_offset, length) + # def initialize: (targets: Array[Node], operator_loc: Location?, value: Node?, lparen_loc: Location?, rparen_loc: Location?, location: Location) -> void + def initialize(targets, operator_loc, value, lparen_loc, rparen_loc, location) @targets = targets @operator_loc = operator_loc @value = value @lparen_loc = lparen_loc @rparen_loc = rparen_loc - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -3600,6 +4102,21 @@ module YARP def deconstruct_keys(keys) { targets: targets, operator_loc: operator_loc, value: value, lparen_loc: lparen_loc, rparen_loc: rparen_loc, location: location } end + + # def operator: () -> String? + def operator + operator_loc&.slice + end + + # def lparen: () -> String? + def lparen + lparen_loc&.slice + end + + # def rparen: () -> String? + def rparen + rparen_loc&.slice + end end # Represents the use of the `next` keyword. @@ -3613,12 +4130,11 @@ module YARP # attr_reader keyword_loc: Location attr_reader :keyword_loc - # def initialize: (arguments: Node?, keyword_loc: Location, start_offset: Integer, length: Integer) -> void - def initialize(arguments, keyword_loc, start_offset, length) + # def initialize: (arguments: Node?, keyword_loc: Location, location: Location) -> void + def initialize(arguments, keyword_loc, location) @arguments = arguments @keyword_loc = keyword_loc - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -3638,6 +4154,11 @@ module YARP def deconstruct_keys(keys) { arguments: arguments, keyword_loc: keyword_loc, location: location } end + + # def keyword: () -> String + def keyword + keyword_loc.slice + end end # Represents the use of the `nil` keyword. @@ -3645,10 +4166,9 @@ module YARP # nil # ^^^ class NilNode < Node - # def initialize: (start_offset: Integer, length: Integer) -> void - def initialize(start_offset, length) - @start_offset = start_offset - @length = length + # def initialize: (location: Location) -> void + def initialize(location) + @location = location end # def accept: (visitor: Visitor) -> void @@ -3682,12 +4202,11 @@ module YARP # attr_reader keyword_loc: Location attr_reader :keyword_loc - # def initialize: (operator_loc: Location, keyword_loc: Location, start_offset: Integer, length: Integer) -> void - def initialize(operator_loc, keyword_loc, start_offset, length) + # def initialize: (operator_loc: Location, keyword_loc: Location, location: Location) -> void + def initialize(operator_loc, keyword_loc, location) @operator_loc = operator_loc @keyword_loc = keyword_loc - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -3707,6 +4226,16 @@ module YARP def deconstruct_keys(keys) { operator_loc: operator_loc, keyword_loc: keyword_loc, location: location } end + + # def operator: () -> String + def operator + operator_loc.slice + end + + # def keyword: () -> String + def keyword + keyword_loc.slice + end end # Represents reading a numbered reference to a capture in the previous match. @@ -3714,10 +4243,9 @@ module YARP # $1 # ^^ class NumberedReferenceReadNode < Node - # def initialize: (start_offset: Integer, length: Integer) -> void - def initialize(start_offset, length) - @start_offset = start_offset - @length = length + # def initialize: (location: Location) -> void + def initialize(location) + @location = location end # def accept: (visitor: Visitor) -> void @@ -3757,14 +4285,13 @@ module YARP # attr_reader value: Node attr_reader :value - # def initialize: (constant_id: Symbol, name_loc: Location, operator_loc: Location, value: Node, start_offset: Integer, length: Integer) -> void - def initialize(constant_id, name_loc, operator_loc, value, start_offset, length) + # def initialize: (constant_id: Symbol, name_loc: Location, operator_loc: Location, value: Node, location: Location) -> void + def initialize(constant_id, name_loc, operator_loc, value, location) @constant_id = constant_id @name_loc = name_loc @operator_loc = operator_loc @value = value - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -3784,6 +4311,16 @@ module YARP def deconstruct_keys(keys) { constant_id: constant_id, name_loc: name_loc, operator_loc: operator_loc, value: value, location: location } end + + # def name: () -> String + def name + name_loc.slice + end + + # def operator: () -> String + def operator + operator_loc.slice + end end # Represents the use of the `||` operator or the `or` keyword. @@ -3800,13 +4337,12 @@ module YARP # attr_reader operator_loc: Location attr_reader :operator_loc - # def initialize: (left: Node, right: Node, operator_loc: Location, start_offset: Integer, length: Integer) -> void - def initialize(left, right, operator_loc, start_offset, length) + # def initialize: (left: Node, right: Node, operator_loc: Location, location: Location) -> void + def initialize(left, right, operator_loc, location) @left = left @right = right @operator_loc = operator_loc - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -3826,6 +4362,11 @@ module YARP def deconstruct_keys(keys) { left: left, right: right, operator_loc: operator_loc, location: location } end + + # def operator: () -> String + def operator + operator_loc.slice + end end # Represents the list of parameters on a method, block, or lambda definition. @@ -3855,8 +4396,8 @@ module YARP # attr_reader block: Node? attr_reader :block - # def initialize: (requireds: Array[Node], optionals: Array[Node], posts: Array[Node], rest: Node?, keywords: Array[Node], keyword_rest: Node?, block: Node?, start_offset: Integer, length: Integer) -> void - def initialize(requireds, optionals, posts, rest, keywords, keyword_rest, block, start_offset, length) + # def initialize: (requireds: Array[Node], optionals: Array[Node], posts: Array[Node], rest: Node?, keywords: Array[Node], keyword_rest: Node?, block: Node?, location: Location) -> void + def initialize(requireds, optionals, posts, rest, keywords, keyword_rest, block, location) @requireds = requireds @optionals = optionals @posts = posts @@ -3864,8 +4405,7 @@ module YARP @keywords = keywords @keyword_rest = keyword_rest @block = block - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -3901,13 +4441,12 @@ module YARP # attr_reader closing_loc: Location attr_reader :closing_loc - # def initialize: (statements: Node?, opening_loc: Location, closing_loc: Location, start_offset: Integer, length: Integer) -> void - def initialize(statements, opening_loc, closing_loc, start_offset, length) + # def initialize: (statements: Node?, opening_loc: Location, closing_loc: Location, location: Location) -> void + def initialize(statements, opening_loc, closing_loc, location) @statements = statements @opening_loc = opening_loc @closing_loc = closing_loc - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -3927,6 +4466,16 @@ module YARP def deconstruct_keys(keys) { statements: statements, opening_loc: opening_loc, closing_loc: closing_loc, location: location } end + + # def opening: () -> String + def opening + opening_loc.slice + end + + # def closing: () -> String + def closing + closing_loc.slice + end end # Represents the use of the `^` operator for pinning an expression in a @@ -3947,14 +4496,13 @@ module YARP # attr_reader rparen_loc: Location attr_reader :rparen_loc - # def initialize: (expression: Node, operator_loc: Location, lparen_loc: Location, rparen_loc: Location, start_offset: Integer, length: Integer) -> void - def initialize(expression, operator_loc, lparen_loc, rparen_loc, start_offset, length) + # def initialize: (expression: Node, operator_loc: Location, lparen_loc: Location, rparen_loc: Location, location: Location) -> void + def initialize(expression, operator_loc, lparen_loc, rparen_loc, location) @expression = expression @operator_loc = operator_loc @lparen_loc = lparen_loc @rparen_loc = rparen_loc - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -3974,6 +4522,21 @@ module YARP def deconstruct_keys(keys) { expression: expression, operator_loc: operator_loc, lparen_loc: lparen_loc, rparen_loc: rparen_loc, location: location } end + + # def operator: () -> String + def operator + operator_loc.slice + end + + # def lparen: () -> String + def lparen + lparen_loc.slice + end + + # def rparen: () -> String + def rparen + rparen_loc.slice + end end # Represents the use of the `^` operator for pinning a variable in a pattern @@ -3988,12 +4551,11 @@ module YARP # attr_reader operator_loc: Location attr_reader :operator_loc - # def initialize: (variable: Node, operator_loc: Location, start_offset: Integer, length: Integer) -> void - def initialize(variable, operator_loc, start_offset, length) + # def initialize: (variable: Node, operator_loc: Location, location: Location) -> void + def initialize(variable, operator_loc, location) @variable = variable @operator_loc = operator_loc - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -4013,6 +4575,11 @@ module YARP def deconstruct_keys(keys) { variable: variable, operator_loc: operator_loc, location: location } end + + # def operator: () -> String + def operator + operator_loc.slice + end end # Represents the use of the `END` keyword. @@ -4032,14 +4599,13 @@ module YARP # attr_reader closing_loc: Location attr_reader :closing_loc - # def initialize: (statements: Node?, keyword_loc: Location, opening_loc: Location, closing_loc: Location, start_offset: Integer, length: Integer) -> void - def initialize(statements, keyword_loc, opening_loc, closing_loc, start_offset, length) + # def initialize: (statements: Node?, keyword_loc: Location, opening_loc: Location, closing_loc: Location, location: Location) -> void + def initialize(statements, keyword_loc, opening_loc, closing_loc, location) @statements = statements @keyword_loc = keyword_loc @opening_loc = opening_loc @closing_loc = closing_loc - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -4059,6 +4625,21 @@ module YARP def deconstruct_keys(keys) { statements: statements, keyword_loc: keyword_loc, opening_loc: opening_loc, closing_loc: closing_loc, location: location } end + + # def keyword: () -> String + def keyword + keyword_loc.slice + end + + # def opening: () -> String + def opening + opening_loc.slice + end + + # def closing: () -> String + def closing + closing_loc.slice + end end # Represents the use of the `BEGIN` keyword. @@ -4078,14 +4659,13 @@ module YARP # attr_reader closing_loc: Location attr_reader :closing_loc - # def initialize: (statements: Node?, keyword_loc: Location, opening_loc: Location, closing_loc: Location, start_offset: Integer, length: Integer) -> void - def initialize(statements, keyword_loc, opening_loc, closing_loc, start_offset, length) + # def initialize: (statements: Node?, keyword_loc: Location, opening_loc: Location, closing_loc: Location, location: Location) -> void + def initialize(statements, keyword_loc, opening_loc, closing_loc, location) @statements = statements @keyword_loc = keyword_loc @opening_loc = opening_loc @closing_loc = closing_loc - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -4105,6 +4685,21 @@ module YARP def deconstruct_keys(keys) { statements: statements, keyword_loc: keyword_loc, opening_loc: opening_loc, closing_loc: closing_loc, location: location } end + + # def keyword: () -> String + def keyword + keyword_loc.slice + end + + # def opening: () -> String + def opening + opening_loc.slice + end + + # def closing: () -> String + def closing + closing_loc.slice + end end # The top level node of any parse tree. @@ -4115,12 +4710,11 @@ module YARP # attr_reader statements: Node attr_reader :statements - # def initialize: (locals: Array[Symbol], statements: Node, start_offset: Integer, length: Integer) -> void - def initialize(locals, statements, start_offset, length) + # def initialize: (locals: Array[Symbol], statements: Node, location: Location) -> void + def initialize(locals, statements, location) @locals = locals @statements = statements - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -4162,14 +4756,13 @@ module YARP # attr_reader flags: Integer attr_reader :flags - # def initialize: (left: Node?, right: Node?, operator_loc: Location, flags: Integer, start_offset: Integer, length: Integer) -> void - def initialize(left, right, operator_loc, flags, start_offset, length) + # 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 - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -4189,6 +4782,11 @@ module YARP 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 end # Represents a rational number literal. @@ -4199,11 +4797,10 @@ module YARP # attr_reader numeric: Node attr_reader :numeric - # def initialize: (numeric: Node, start_offset: Integer, length: Integer) -> void - def initialize(numeric, start_offset, length) + # def initialize: (numeric: Node, location: Location) -> void + def initialize(numeric, location) @numeric = numeric - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -4230,10 +4827,9 @@ module YARP # redo # ^^^^ class RedoNode < Node - # def initialize: (start_offset: Integer, length: Integer) -> void - def initialize(start_offset, length) - @start_offset = start_offset - @length = length + # def initialize: (location: Location) -> void + def initialize(location) + @location = location end # def accept: (visitor: Visitor) -> void @@ -4275,15 +4871,14 @@ module YARP # attr_reader flags: Integer attr_reader :flags - # def initialize: (opening_loc: Location, content_loc: Location, closing_loc: Location, unescaped: String, flags: Integer, start_offset: Integer, length: Integer) -> void - def initialize(opening_loc, content_loc, closing_loc, unescaped, flags, start_offset, length) + # def initialize: (opening_loc: Location, content_loc: Location, closing_loc: Location, unescaped: String, flags: Integer, location: Location) -> void + def initialize(opening_loc, content_loc, closing_loc, unescaped, flags, location) @opening_loc = opening_loc @content_loc = content_loc @closing_loc = closing_loc @unescaped = unescaped @flags = flags - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -4303,6 +4898,21 @@ module YARP def deconstruct_keys(keys) { opening_loc: opening_loc, content_loc: content_loc, closing_loc: closing_loc, unescaped: unescaped, flags: flags, location: location } end + + # def opening: () -> String + def opening + opening_loc.slice + end + + # def content: () -> String + def content + content_loc.slice + end + + # def closing: () -> String + def closing + closing_loc.slice + end end # Represents a destructured required parameter node. @@ -4320,13 +4930,12 @@ module YARP # attr_reader closing_loc: Location attr_reader :closing_loc - # def initialize: (parameters: Array[Node], opening_loc: Location, closing_loc: Location, start_offset: Integer, length: Integer) -> void - def initialize(parameters, opening_loc, closing_loc, start_offset, length) + # def initialize: (parameters: Array[Node], opening_loc: Location, closing_loc: Location, location: Location) -> void + def initialize(parameters, opening_loc, closing_loc, location) @parameters = parameters @opening_loc = opening_loc @closing_loc = closing_loc - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -4346,6 +4955,16 @@ module YARP def deconstruct_keys(keys) { parameters: parameters, opening_loc: opening_loc, closing_loc: closing_loc, location: location } end + + # def opening: () -> String + def opening + opening_loc.slice + end + + # def closing: () -> String + def closing + closing_loc.slice + end end # Represents a required parameter to a method, block, or lambda definition. @@ -4357,11 +4976,10 @@ module YARP # attr_reader constant_id: Symbol attr_reader :constant_id - # def initialize: (constant_id: Symbol, start_offset: Integer, length: Integer) -> void - def initialize(constant_id, start_offset, length) + # def initialize: (constant_id: Symbol, location: Location) -> void + def initialize(constant_id, location) @constant_id = constant_id - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -4397,13 +5015,12 @@ module YARP # attr_reader rescue_expression: Node attr_reader :rescue_expression - # def initialize: (expression: Node, keyword_loc: Location, rescue_expression: Node, start_offset: Integer, length: Integer) -> void - def initialize(expression, keyword_loc, rescue_expression, start_offset, length) + # def initialize: (expression: Node, keyword_loc: Location, rescue_expression: Node, location: Location) -> void + def initialize(expression, keyword_loc, rescue_expression, location) @expression = expression @keyword_loc = keyword_loc @rescue_expression = rescue_expression - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -4423,6 +5040,11 @@ module YARP def deconstruct_keys(keys) { expression: expression, keyword_loc: keyword_loc, rescue_expression: rescue_expression, location: location } end + + # def keyword: () -> String + def keyword + keyword_loc.slice + end end # Represents a rescue statement. @@ -4451,16 +5073,15 @@ 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?, start_offset: Integer, length: Integer) -> void - def initialize(keyword_loc, exceptions, operator_loc, exception, statements, consequent, start_offset, length) + # 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) @keyword_loc = keyword_loc @exceptions = exceptions @operator_loc = operator_loc @exception = exception @statements = statements @consequent = consequent - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -4480,6 +5101,16 @@ module YARP def deconstruct_keys(keys) { keyword_loc: keyword_loc, exceptions: exceptions, operator_loc: operator_loc, exception: exception, statements: statements, consequent: consequent, location: location } end + + # def keyword: () -> String + def keyword + keyword_loc.slice + end + + # def operator: () -> String? + def operator + operator_loc&.slice + end end # Represents a rest parameter to a method, block, or lambda definition. @@ -4494,12 +5125,11 @@ module YARP # attr_reader name_loc: Location? attr_reader :name_loc - # def initialize: (operator_loc: Location, name_loc: Location?, start_offset: Integer, length: Integer) -> void - def initialize(operator_loc, name_loc, start_offset, length) + # def initialize: (operator_loc: Location, name_loc: Location?, location: Location) -> void + def initialize(operator_loc, name_loc, location) @operator_loc = operator_loc @name_loc = name_loc - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -4519,6 +5149,16 @@ module YARP def deconstruct_keys(keys) { operator_loc: operator_loc, name_loc: name_loc, location: location } end + + # def operator: () -> String + def operator + operator_loc.slice + end + + # def name: () -> String? + def name + name_loc&.slice + end end # Represents the use of the `retry` keyword. @@ -4526,10 +5166,9 @@ module YARP # retry # ^^^^^ class RetryNode < Node - # def initialize: (start_offset: Integer, length: Integer) -> void - def initialize(start_offset, length) - @start_offset = start_offset - @length = length + # def initialize: (location: Location) -> void + def initialize(location) + @location = location end # def accept: (visitor: Visitor) -> void @@ -4562,12 +5201,11 @@ module YARP # attr_reader arguments: Node? attr_reader :arguments - # def initialize: (keyword_loc: Location, arguments: Node?, start_offset: Integer, length: Integer) -> void - def initialize(keyword_loc, arguments, start_offset, length) + # def initialize: (keyword_loc: Location, arguments: Node?, location: Location) -> void + def initialize(keyword_loc, arguments, location) @keyword_loc = keyword_loc @arguments = arguments - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -4587,6 +5225,11 @@ module YARP def deconstruct_keys(keys) { keyword_loc: keyword_loc, arguments: arguments, location: location } end + + # def keyword: () -> String + def keyword + keyword_loc.slice + end end # Represents the `self` keyword. @@ -4594,10 +5237,9 @@ module YARP # self # ^^^^ class SelfNode < Node - # def initialize: (start_offset: Integer, length: Integer) -> void - def initialize(start_offset, length) - @start_offset = start_offset - @length = length + # def initialize: (location: Location) -> void + def initialize(location) + @location = location end # def accept: (visitor: Visitor) -> void @@ -4642,16 +5284,15 @@ module YARP # attr_reader end_keyword_loc: Location attr_reader :end_keyword_loc - # def initialize: (locals: Array[Symbol], class_keyword_loc: Location, operator_loc: Location, expression: Node, statements: Node?, end_keyword_loc: Location, start_offset: Integer, length: Integer) -> void - def initialize(locals, class_keyword_loc, operator_loc, expression, statements, end_keyword_loc, start_offset, length) + # def initialize: (locals: Array[Symbol], class_keyword_loc: Location, operator_loc: Location, expression: Node, statements: Node?, end_keyword_loc: Location, location: Location) -> void + def initialize(locals, class_keyword_loc, operator_loc, expression, statements, end_keyword_loc, location) @locals = locals @class_keyword_loc = class_keyword_loc @operator_loc = operator_loc @expression = expression @statements = statements @end_keyword_loc = end_keyword_loc - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -4671,6 +5312,21 @@ module YARP def deconstruct_keys(keys) { locals: locals, class_keyword_loc: class_keyword_loc, operator_loc: operator_loc, expression: expression, statements: statements, end_keyword_loc: end_keyword_loc, location: location } end + + # def class_keyword: () -> String + def class_keyword + class_keyword_loc.slice + end + + # def operator: () -> String + def operator + operator_loc.slice + end + + # def end_keyword: () -> String + def end_keyword + end_keyword_loc.slice + end end # Represents the use of the `__ENCODING__` keyword. @@ -4678,10 +5334,9 @@ module YARP # __ENCODING__ # ^^^^^^^^^^^^ class SourceEncodingNode < Node - # def initialize: (start_offset: Integer, length: Integer) -> void - def initialize(start_offset, length) - @start_offset = start_offset - @length = length + # def initialize: (location: Location) -> void + def initialize(location) + @location = location end # def accept: (visitor: Visitor) -> void @@ -4711,11 +5366,10 @@ module YARP # attr_reader filepath: String attr_reader :filepath - # def initialize: (filepath: String, start_offset: Integer, length: Integer) -> void - def initialize(filepath, start_offset, length) + # def initialize: (filepath: String, location: Location) -> void + def initialize(filepath, location) @filepath = filepath - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -4742,10 +5396,9 @@ module YARP # __LINE__ # ^^^^^^^^ class SourceLineNode < Node - # def initialize: (start_offset: Integer, length: Integer) -> void - def initialize(start_offset, length) - @start_offset = start_offset - @length = length + # def initialize: (location: Location) -> void + def initialize(location) + @location = location end # def accept: (visitor: Visitor) -> void @@ -4778,12 +5431,11 @@ module YARP # attr_reader expression: Node? attr_reader :expression - # def initialize: (operator_loc: Location, expression: Node?, start_offset: Integer, length: Integer) -> void - def initialize(operator_loc, expression, start_offset, length) + # def initialize: (operator_loc: Location, expression: Node?, location: Location) -> void + def initialize(operator_loc, expression, location) @operator_loc = operator_loc @expression = expression - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -4803,6 +5455,11 @@ module YARP def deconstruct_keys(keys) { operator_loc: operator_loc, expression: expression, location: location } end + + # def operator: () -> String + def operator + operator_loc.slice + end end # Represents a set of statements contained within some scope. @@ -4813,11 +5470,10 @@ module YARP # attr_reader body: Array[Node] attr_reader :body - # def initialize: (body: Array[Node], start_offset: Integer, length: Integer) -> void - def initialize(body, start_offset, length) + # def initialize: (body: Array[Node], location: Location) -> void + def initialize(body, location) @body = body - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -4850,12 +5506,11 @@ module YARP # attr_reader right: Node attr_reader :right - # def initialize: (left: Node, right: Node, start_offset: Integer, length: Integer) -> void - def initialize(left, right, start_offset, length) + # def initialize: (left: Node, right: Node, location: Location) -> void + def initialize(left, right, location) @left = left @right = right - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -4901,14 +5556,13 @@ module YARP # attr_reader unescaped: String attr_reader :unescaped - # def initialize: (opening_loc: Location?, content_loc: Location, closing_loc: Location?, unescaped: String, start_offset: Integer, length: Integer) -> void - def initialize(opening_loc, content_loc, closing_loc, unescaped, start_offset, length) + # def initialize: (opening_loc: Location?, content_loc: Location, closing_loc: Location?, unescaped: String, location: Location) -> void + def initialize(opening_loc, content_loc, closing_loc, unescaped, location) @opening_loc = opening_loc @content_loc = content_loc @closing_loc = closing_loc @unescaped = unescaped - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -4928,6 +5582,21 @@ module YARP def deconstruct_keys(keys) { opening_loc: opening_loc, content_loc: content_loc, closing_loc: closing_loc, unescaped: unescaped, location: location } end + + # def opening: () -> String? + def opening + opening_loc&.slice + end + + # def content: () -> String + def content + content_loc.slice + end + + # def closing: () -> String? + def closing + closing_loc&.slice + end end # Represents the use of the `super` keyword with parentheses or arguments. @@ -4953,15 +5622,14 @@ module YARP # attr_reader block: Node? attr_reader :block - # def initialize: (keyword_loc: Location, lparen_loc: Location?, arguments: Node?, rparen_loc: Location?, block: Node?, start_offset: Integer, length: Integer) -> void - def initialize(keyword_loc, lparen_loc, arguments, rparen_loc, block, start_offset, length) + # def initialize: (keyword_loc: Location, lparen_loc: Location?, arguments: Node?, rparen_loc: Location?, block: Node?, location: Location) -> void + def initialize(keyword_loc, lparen_loc, arguments, rparen_loc, block, location) @keyword_loc = keyword_loc @lparen_loc = lparen_loc @arguments = arguments @rparen_loc = rparen_loc @block = block - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -4981,6 +5649,21 @@ module YARP def deconstruct_keys(keys) { keyword_loc: keyword_loc, lparen_loc: lparen_loc, arguments: arguments, rparen_loc: rparen_loc, block: block, location: location } end + + # def keyword: () -> String + def keyword + keyword_loc.slice + end + + # def lparen: () -> String? + def lparen + lparen_loc&.slice + end + + # def rparen: () -> String? + def rparen + rparen_loc&.slice + end end # Represents a symbol literal or a symbol contained within a `%i` list. @@ -5003,14 +5686,13 @@ module YARP # attr_reader unescaped: String attr_reader :unescaped - # def initialize: (opening_loc: Location?, value_loc: Location, closing_loc: Location?, unescaped: String, start_offset: Integer, length: Integer) -> void - def initialize(opening_loc, value_loc, closing_loc, unescaped, start_offset, length) + # def initialize: (opening_loc: Location?, value_loc: Location, closing_loc: Location?, unescaped: String, location: Location) -> void + def initialize(opening_loc, value_loc, closing_loc, unescaped, location) @opening_loc = opening_loc @value_loc = value_loc @closing_loc = closing_loc @unescaped = unescaped - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -5030,6 +5712,21 @@ module YARP def deconstruct_keys(keys) { opening_loc: opening_loc, value_loc: value_loc, closing_loc: closing_loc, unescaped: unescaped, location: location } end + + # def opening: () -> String? + def opening + opening_loc&.slice + end + + # def value: () -> String + def value + value_loc.slice + end + + # def closing: () -> String? + def closing + closing_loc&.slice + end end # Represents the use of the literal `true` keyword. @@ -5037,10 +5734,9 @@ module YARP # true # ^^^^ class TrueNode < Node - # def initialize: (start_offset: Integer, length: Integer) -> void - def initialize(start_offset, length) - @start_offset = start_offset - @length = length + # def initialize: (location: Location) -> void + def initialize(location) + @location = location end # def accept: (visitor: Visitor) -> void @@ -5073,12 +5769,11 @@ module YARP # attr_reader keyword_loc: Location attr_reader :keyword_loc - # def initialize: (names: Array[Node], keyword_loc: Location, start_offset: Integer, length: Integer) -> void - def initialize(names, keyword_loc, start_offset, length) + # def initialize: (names: Array[Node], keyword_loc: Location, location: Location) -> void + def initialize(names, keyword_loc, location) @names = names @keyword_loc = keyword_loc - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -5098,6 +5793,11 @@ module YARP def deconstruct_keys(keys) { names: names, keyword_loc: keyword_loc, location: location } end + + # def keyword: () -> String + def keyword + keyword_loc.slice + end end # Represents the use of the `unless` keyword, either in the block form or the modifier form. @@ -5123,15 +5823,14 @@ module YARP # attr_reader end_keyword_loc: Location? attr_reader :end_keyword_loc - # def initialize: (keyword_loc: Location, predicate: Node, statements: Node?, consequent: Node?, end_keyword_loc: Location?, start_offset: Integer, length: Integer) -> void - def initialize(keyword_loc, predicate, statements, consequent, end_keyword_loc, start_offset, length) + # def initialize: (keyword_loc: Location, predicate: Node, statements: Node?, consequent: Node?, end_keyword_loc: Location?, location: Location) -> void + def initialize(keyword_loc, predicate, statements, consequent, end_keyword_loc, location) @keyword_loc = keyword_loc @predicate = predicate @statements = statements @consequent = consequent @end_keyword_loc = end_keyword_loc - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -5151,6 +5850,16 @@ module YARP def deconstruct_keys(keys) { keyword_loc: keyword_loc, predicate: predicate, statements: statements, consequent: consequent, end_keyword_loc: end_keyword_loc, location: location } end + + # def keyword: () -> String + def keyword + keyword_loc.slice + end + + # def end_keyword: () -> String? + def end_keyword + end_keyword_loc&.slice + end end # Represents the use of the `until` keyword, either in the block form or the modifier form. @@ -5170,13 +5879,12 @@ module YARP # attr_reader statements: Node? attr_reader :statements - # def initialize: (keyword_loc: Location, predicate: Node, statements: Node?, start_offset: Integer, length: Integer) -> void - def initialize(keyword_loc, predicate, statements, start_offset, length) + # def initialize: (keyword_loc: Location, predicate: Node, statements: Node?, location: Location) -> void + def initialize(keyword_loc, predicate, statements, location) @keyword_loc = keyword_loc @predicate = predicate @statements = statements - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -5196,6 +5904,11 @@ module YARP def deconstruct_keys(keys) { keyword_loc: keyword_loc, predicate: predicate, statements: statements, location: location } end + + # def keyword: () -> String + def keyword + keyword_loc.slice + end end # case true @@ -5212,13 +5925,12 @@ module YARP # attr_reader statements: Node? attr_reader :statements - # def initialize: (keyword_loc: Location, conditions: Array[Node], statements: Node?, start_offset: Integer, length: Integer) -> void - def initialize(keyword_loc, conditions, statements, start_offset, length) + # def initialize: (keyword_loc: Location, conditions: Array[Node], statements: Node?, location: Location) -> void + def initialize(keyword_loc, conditions, statements, location) @keyword_loc = keyword_loc @conditions = conditions @statements = statements - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -5238,6 +5950,11 @@ module YARP def deconstruct_keys(keys) { keyword_loc: keyword_loc, conditions: conditions, statements: statements, location: location } end + + # def keyword: () -> String + def keyword + keyword_loc.slice + end end # Represents the use of the `while` keyword, either in the block form or the modifier form. @@ -5257,13 +5974,12 @@ module YARP # attr_reader statements: Node? attr_reader :statements - # def initialize: (keyword_loc: Location, predicate: Node, statements: Node?, start_offset: Integer, length: Integer) -> void - def initialize(keyword_loc, predicate, statements, start_offset, length) + # def initialize: (keyword_loc: Location, predicate: Node, statements: Node?, location: Location) -> void + def initialize(keyword_loc, predicate, statements, location) @keyword_loc = keyword_loc @predicate = predicate @statements = statements - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -5283,6 +5999,11 @@ module YARP def deconstruct_keys(keys) { keyword_loc: keyword_loc, predicate: predicate, statements: statements, location: location } end + + # def keyword: () -> String + def keyword + keyword_loc.slice + end end # Represents an xstring literal with no interpolation. @@ -5302,14 +6023,13 @@ module YARP # attr_reader unescaped: String attr_reader :unescaped - # def initialize: (opening_loc: Location, content_loc: Location, closing_loc: Location, unescaped: String, start_offset: Integer, length: Integer) -> void - def initialize(opening_loc, content_loc, closing_loc, unescaped, start_offset, length) + # def initialize: (opening_loc: Location, content_loc: Location, closing_loc: Location, unescaped: String, location: Location) -> void + def initialize(opening_loc, content_loc, closing_loc, unescaped, location) @opening_loc = opening_loc @content_loc = content_loc @closing_loc = closing_loc @unescaped = unescaped - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -5329,6 +6049,21 @@ module YARP def deconstruct_keys(keys) { opening_loc: opening_loc, content_loc: content_loc, closing_loc: closing_loc, unescaped: unescaped, location: location } end + + # def opening: () -> String + def opening + opening_loc.slice + end + + # def content: () -> String + def content + content_loc.slice + end + + # def closing: () -> String + def closing + closing_loc.slice + end end # Represents the use of the `yield` keyword. @@ -5348,14 +6083,13 @@ module YARP # attr_reader rparen_loc: Location? attr_reader :rparen_loc - # def initialize: (keyword_loc: Location, lparen_loc: Location?, arguments: Node?, rparen_loc: Location?, start_offset: Integer, length: Integer) -> void - def initialize(keyword_loc, lparen_loc, arguments, rparen_loc, start_offset, length) + # def initialize: (keyword_loc: Location, lparen_loc: Location?, arguments: Node?, rparen_loc: Location?, location: Location) -> void + def initialize(keyword_loc, lparen_loc, arguments, rparen_loc, location) @keyword_loc = keyword_loc @lparen_loc = lparen_loc @arguments = arguments @rparen_loc = rparen_loc - @start_offset = start_offset - @length = length + @location = location end # def accept: (visitor: Visitor) -> void @@ -5375,6 +6109,21 @@ module YARP def deconstruct_keys(keys) { keyword_loc: keyword_loc, lparen_loc: lparen_loc, arguments: arguments, rparen_loc: rparen_loc, location: location } end + + # def keyword: () -> String + def keyword + keyword_loc.slice + end + + # def lparen: () -> String? + def lparen + lparen_loc&.slice + end + + # def rparen: () -> String? + def rparen + rparen_loc&.slice + end end module CallNodeFlags @@ -5413,6 +6162,24 @@ 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 @@ -5797,638 +6564,638 @@ module YARP private # Create a new Location object - def Location(start_offset = 0, length = 0) - Location.new(start_offset, length) + def Location(source = nil, start_offset = 0, length = 0) + Location.new(source, start_offset, length) end # Create a new AliasNode node - def AliasNode(new_name, old_name, keyword_loc) - AliasNode.new(new_name, old_name, keyword_loc, 0, 0) + def AliasNode(new_name, old_name, keyword_loc, location = Location()) + AliasNode.new(new_name, old_name, keyword_loc, location) end # Create a new AlternationPatternNode node - def AlternationPatternNode(left, right, operator_loc) - AlternationPatternNode.new(left, right, operator_loc, 0, 0) + def AlternationPatternNode(left, right, operator_loc, location = Location()) + AlternationPatternNode.new(left, right, operator_loc, location) end # Create a new AndNode node - def AndNode(left, right, operator_loc) - AndNode.new(left, right, operator_loc, 0, 0) + def AndNode(left, right, operator_loc, location = Location()) + AndNode.new(left, right, operator_loc, location) end # Create a new ArgumentsNode node - def ArgumentsNode(arguments) - ArgumentsNode.new(arguments, 0, 0) + def ArgumentsNode(arguments, location = Location()) + ArgumentsNode.new(arguments, location) end # Create a new ArrayNode node - def ArrayNode(elements, opening_loc, closing_loc) - ArrayNode.new(elements, opening_loc, closing_loc, 0, 0) + def ArrayNode(elements, opening_loc, closing_loc, location = Location()) + ArrayNode.new(elements, opening_loc, closing_loc, location) end # Create a new ArrayPatternNode node - def ArrayPatternNode(constant, requireds, rest, posts, opening_loc, closing_loc) - ArrayPatternNode.new(constant, requireds, rest, posts, opening_loc, closing_loc, 0, 0) + def ArrayPatternNode(constant, requireds, rest, posts, opening_loc, closing_loc, location = Location()) + ArrayPatternNode.new(constant, requireds, rest, posts, opening_loc, closing_loc, location) end # Create a new AssocNode node - def AssocNode(key, value, operator_loc) - AssocNode.new(key, value, operator_loc, 0, 0) + def AssocNode(key, value, operator_loc, location = Location()) + AssocNode.new(key, value, operator_loc, location) end # Create a new AssocSplatNode node - def AssocSplatNode(value, operator_loc) - AssocSplatNode.new(value, operator_loc, 0, 0) + def AssocSplatNode(value, operator_loc, location = Location()) + AssocSplatNode.new(value, operator_loc, location) end # Create a new BackReferenceReadNode node - def BackReferenceReadNode() - BackReferenceReadNode.new(0, 0) + def BackReferenceReadNode(location = Location()) + BackReferenceReadNode.new(location) end # Create a new BeginNode node - def BeginNode(begin_keyword_loc, statements, rescue_clause, else_clause, ensure_clause, end_keyword_loc) - BeginNode.new(begin_keyword_loc, statements, rescue_clause, else_clause, ensure_clause, end_keyword_loc, 0, 0) + def BeginNode(begin_keyword_loc, statements, rescue_clause, else_clause, ensure_clause, end_keyword_loc, location = Location()) + BeginNode.new(begin_keyword_loc, statements, rescue_clause, else_clause, ensure_clause, end_keyword_loc, location) end # Create a new BlockArgumentNode node - def BlockArgumentNode(expression, operator_loc) - BlockArgumentNode.new(expression, operator_loc, 0, 0) + def BlockArgumentNode(expression, operator_loc, location = Location()) + BlockArgumentNode.new(expression, operator_loc, location) end # Create a new BlockNode node - def BlockNode(locals, parameters, statements, opening_loc, closing_loc) - BlockNode.new(locals, parameters, statements, opening_loc, closing_loc, 0, 0) + def BlockNode(locals, parameters, statements, opening_loc, closing_loc, location = Location()) + BlockNode.new(locals, parameters, statements, opening_loc, closing_loc, location) end # Create a new BlockParameterNode node - def BlockParameterNode(name_loc, operator_loc) - BlockParameterNode.new(name_loc, operator_loc, 0, 0) + def BlockParameterNode(name_loc, operator_loc, location = Location()) + BlockParameterNode.new(name_loc, operator_loc, location) end # Create a new BlockParametersNode node - def BlockParametersNode(parameters, locals, opening_loc, closing_loc) - BlockParametersNode.new(parameters, locals, opening_loc, closing_loc, 0, 0) + def BlockParametersNode(parameters, locals, opening_loc, closing_loc, location = Location()) + BlockParametersNode.new(parameters, locals, opening_loc, closing_loc, location) end # Create a new BreakNode node - def BreakNode(arguments, keyword_loc) - BreakNode.new(arguments, keyword_loc, 0, 0) + def BreakNode(arguments, keyword_loc, location = Location()) + BreakNode.new(arguments, keyword_loc, location) end # Create a new CallNode node - def CallNode(receiver, operator_loc, message_loc, opening_loc, arguments, closing_loc, block, flags, name) - CallNode.new(receiver, operator_loc, message_loc, opening_loc, arguments, closing_loc, block, flags, name, 0, 0) + def CallNode(receiver, operator_loc, message_loc, opening_loc, arguments, closing_loc, block, flags, name, location = Location()) + CallNode.new(receiver, operator_loc, message_loc, opening_loc, arguments, closing_loc, block, flags, name, location) end # Create a new CallOperatorAndWriteNode node - def CallOperatorAndWriteNode(target, operator_loc, value) - CallOperatorAndWriteNode.new(target, operator_loc, value, 0, 0) + def CallOperatorAndWriteNode(target, operator_loc, value, location = Location()) + CallOperatorAndWriteNode.new(target, operator_loc, value, location) end # Create a new CallOperatorOrWriteNode node - def CallOperatorOrWriteNode(target, value, operator_loc) - CallOperatorOrWriteNode.new(target, value, operator_loc, 0, 0) + def CallOperatorOrWriteNode(target, value, operator_loc, location = Location()) + CallOperatorOrWriteNode.new(target, value, operator_loc, location) end # Create a new CallOperatorWriteNode node - def CallOperatorWriteNode(target, operator_loc, value, operator_id) - CallOperatorWriteNode.new(target, operator_loc, value, operator_id, 0, 0) + def CallOperatorWriteNode(target, operator_loc, value, operator_id, location = Location()) + CallOperatorWriteNode.new(target, operator_loc, value, operator_id, location) end # Create a new CapturePatternNode node - def CapturePatternNode(value, target, operator_loc) - CapturePatternNode.new(value, target, operator_loc, 0, 0) + def CapturePatternNode(value, target, operator_loc, location = Location()) + CapturePatternNode.new(value, target, operator_loc, location) end # Create a new CaseNode node - def CaseNode(predicate, conditions, consequent, case_keyword_loc, end_keyword_loc) - CaseNode.new(predicate, conditions, consequent, case_keyword_loc, end_keyword_loc, 0, 0) + def CaseNode(predicate, conditions, consequent, case_keyword_loc, end_keyword_loc, location = Location()) + CaseNode.new(predicate, conditions, consequent, case_keyword_loc, end_keyword_loc, location) end # Create a new ClassNode node - def ClassNode(locals, class_keyword_loc, constant_path, inheritance_operator_loc, superclass, statements, end_keyword_loc) - ClassNode.new(locals, class_keyword_loc, constant_path, inheritance_operator_loc, superclass, statements, end_keyword_loc, 0, 0) + def ClassNode(locals, class_keyword_loc, constant_path, inheritance_operator_loc, superclass, statements, end_keyword_loc, location = Location()) + ClassNode.new(locals, class_keyword_loc, constant_path, inheritance_operator_loc, superclass, statements, end_keyword_loc, location) end # Create a new ClassVariableOperatorAndWriteNode node - def ClassVariableOperatorAndWriteNode(name_loc, operator_loc, value) - ClassVariableOperatorAndWriteNode.new(name_loc, operator_loc, value, 0, 0) + def ClassVariableOperatorAndWriteNode(name_loc, operator_loc, value, location = Location()) + ClassVariableOperatorAndWriteNode.new(name_loc, operator_loc, value, location) end # Create a new ClassVariableOperatorOrWriteNode node - def ClassVariableOperatorOrWriteNode(name_loc, operator_loc, value) - ClassVariableOperatorOrWriteNode.new(name_loc, operator_loc, value, 0, 0) + def ClassVariableOperatorOrWriteNode(name_loc, operator_loc, value, location = Location()) + ClassVariableOperatorOrWriteNode.new(name_loc, operator_loc, value, location) end # Create a new ClassVariableOperatorWriteNode node - def ClassVariableOperatorWriteNode(name_loc, operator_loc, value, operator) - ClassVariableOperatorWriteNode.new(name_loc, operator_loc, value, operator, 0, 0) + def ClassVariableOperatorWriteNode(name_loc, operator_loc, value, operator, location = Location()) + ClassVariableOperatorWriteNode.new(name_loc, operator_loc, value, operator, location) end # Create a new ClassVariableReadNode node - def ClassVariableReadNode() - ClassVariableReadNode.new(0, 0) + def ClassVariableReadNode(location = Location()) + ClassVariableReadNode.new(location) end # Create a new ClassVariableWriteNode node - def ClassVariableWriteNode(name_loc, value, operator_loc) - ClassVariableWriteNode.new(name_loc, value, operator_loc, 0, 0) + def ClassVariableWriteNode(name_loc, value, operator_loc, location = Location()) + ClassVariableWriteNode.new(name_loc, value, operator_loc, location) end # Create a new ConstantOperatorAndWriteNode node - def ConstantOperatorAndWriteNode(name_loc, operator_loc, value) - ConstantOperatorAndWriteNode.new(name_loc, operator_loc, value, 0, 0) + def ConstantOperatorAndWriteNode(name_loc, operator_loc, value, location = Location()) + ConstantOperatorAndWriteNode.new(name_loc, operator_loc, value, location) end # Create a new ConstantOperatorOrWriteNode node - def ConstantOperatorOrWriteNode(name_loc, operator_loc, value) - ConstantOperatorOrWriteNode.new(name_loc, operator_loc, value, 0, 0) + def ConstantOperatorOrWriteNode(name_loc, operator_loc, value, location = Location()) + ConstantOperatorOrWriteNode.new(name_loc, operator_loc, value, location) end # Create a new ConstantOperatorWriteNode node - def ConstantOperatorWriteNode(name_loc, operator_loc, value, operator) - ConstantOperatorWriteNode.new(name_loc, operator_loc, value, operator, 0, 0) + def ConstantOperatorWriteNode(name_loc, operator_loc, value, operator, location = Location()) + ConstantOperatorWriteNode.new(name_loc, operator_loc, value, operator, location) end # Create a new ConstantPathNode node - def ConstantPathNode(parent, child, delimiter_loc) - ConstantPathNode.new(parent, child, delimiter_loc, 0, 0) + def ConstantPathNode(parent, child, delimiter_loc, location = Location()) + ConstantPathNode.new(parent, child, delimiter_loc, location) end # Create a new ConstantPathOperatorAndWriteNode node - def ConstantPathOperatorAndWriteNode(target, operator_loc, value) - ConstantPathOperatorAndWriteNode.new(target, operator_loc, value, 0, 0) + def ConstantPathOperatorAndWriteNode(target, operator_loc, value, location = Location()) + ConstantPathOperatorAndWriteNode.new(target, operator_loc, value, location) end # Create a new ConstantPathOperatorOrWriteNode node - def ConstantPathOperatorOrWriteNode(target, operator_loc, value) - ConstantPathOperatorOrWriteNode.new(target, operator_loc, value, 0, 0) + def ConstantPathOperatorOrWriteNode(target, operator_loc, value, location = Location()) + ConstantPathOperatorOrWriteNode.new(target, operator_loc, value, location) end # Create a new ConstantPathOperatorWriteNode node - def ConstantPathOperatorWriteNode(target, operator_loc, value, operator) - ConstantPathOperatorWriteNode.new(target, operator_loc, value, operator, 0, 0) + def ConstantPathOperatorWriteNode(target, operator_loc, value, operator, location = Location()) + ConstantPathOperatorWriteNode.new(target, operator_loc, value, operator, location) end # Create a new ConstantPathWriteNode node - def ConstantPathWriteNode(target, operator_loc, value) - ConstantPathWriteNode.new(target, operator_loc, value, 0, 0) + def ConstantPathWriteNode(target, operator_loc, value, location = Location()) + ConstantPathWriteNode.new(target, operator_loc, value, location) end # Create a new ConstantReadNode node - def ConstantReadNode() - ConstantReadNode.new(0, 0) + def ConstantReadNode(location = Location()) + ConstantReadNode.new(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) - DefNode.new(name_loc, receiver, parameters, statements, locals, def_keyword_loc, operator_loc, lparen_loc, rparen_loc, equal_loc, end_keyword_loc, 0, 0) + 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) end # Create a new DefinedNode node - def DefinedNode(lparen_loc, value, rparen_loc, keyword_loc) - DefinedNode.new(lparen_loc, value, rparen_loc, keyword_loc, 0, 0) + def DefinedNode(lparen_loc, value, rparen_loc, keyword_loc, location = Location()) + DefinedNode.new(lparen_loc, value, rparen_loc, keyword_loc, location) end # Create a new ElseNode node - def ElseNode(else_keyword_loc, statements, end_keyword_loc) - ElseNode.new(else_keyword_loc, statements, end_keyword_loc, 0, 0) + def ElseNode(else_keyword_loc, statements, end_keyword_loc, location = Location()) + ElseNode.new(else_keyword_loc, statements, end_keyword_loc, location) end # Create a new EmbeddedStatementsNode node - def EmbeddedStatementsNode(opening_loc, statements, closing_loc) - EmbeddedStatementsNode.new(opening_loc, statements, closing_loc, 0, 0) + def EmbeddedStatementsNode(opening_loc, statements, closing_loc, location = Location()) + EmbeddedStatementsNode.new(opening_loc, statements, closing_loc, location) end # Create a new EmbeddedVariableNode node - def EmbeddedVariableNode(operator_loc, variable) - EmbeddedVariableNode.new(operator_loc, variable, 0, 0) + def EmbeddedVariableNode(operator_loc, variable, location = Location()) + EmbeddedVariableNode.new(operator_loc, variable, location) end # Create a new EnsureNode node - def EnsureNode(ensure_keyword_loc, statements, end_keyword_loc) - EnsureNode.new(ensure_keyword_loc, statements, end_keyword_loc, 0, 0) + def EnsureNode(ensure_keyword_loc, statements, end_keyword_loc, location = Location()) + EnsureNode.new(ensure_keyword_loc, statements, end_keyword_loc, location) end # Create a new FalseNode node - def FalseNode() - FalseNode.new(0, 0) + def FalseNode(location = Location()) + FalseNode.new(location) end # Create a new FindPatternNode node - def FindPatternNode(constant, left, requireds, right, opening_loc, closing_loc) - FindPatternNode.new(constant, left, requireds, right, opening_loc, closing_loc, 0, 0) + def FindPatternNode(constant, left, requireds, right, opening_loc, closing_loc, location = Location()) + FindPatternNode.new(constant, left, requireds, right, opening_loc, closing_loc, location) end # Create a new FloatNode node - def FloatNode() - FloatNode.new(0, 0) + def FloatNode(location = Location()) + FloatNode.new(location) end # Create a new ForNode node - def ForNode(index, collection, statements, for_keyword_loc, in_keyword_loc, do_keyword_loc, end_keyword_loc) - ForNode.new(index, collection, statements, for_keyword_loc, in_keyword_loc, do_keyword_loc, end_keyword_loc, 0, 0) + def ForNode(index, collection, statements, for_keyword_loc, in_keyword_loc, do_keyword_loc, end_keyword_loc, location = Location()) + ForNode.new(index, collection, statements, for_keyword_loc, in_keyword_loc, do_keyword_loc, end_keyword_loc, location) end # Create a new ForwardingArgumentsNode node - def ForwardingArgumentsNode() - ForwardingArgumentsNode.new(0, 0) + def ForwardingArgumentsNode(location = Location()) + ForwardingArgumentsNode.new(location) end # Create a new ForwardingParameterNode node - def ForwardingParameterNode() - ForwardingParameterNode.new(0, 0) + def ForwardingParameterNode(location = Location()) + ForwardingParameterNode.new(location) end # Create a new ForwardingSuperNode node - def ForwardingSuperNode(block) - ForwardingSuperNode.new(block, 0, 0) + def ForwardingSuperNode(block, location = Location()) + ForwardingSuperNode.new(block, location) end # Create a new GlobalVariableOperatorAndWriteNode node - def GlobalVariableOperatorAndWriteNode(name_loc, operator_loc, value) - GlobalVariableOperatorAndWriteNode.new(name_loc, operator_loc, value, 0, 0) + def GlobalVariableOperatorAndWriteNode(name_loc, operator_loc, value, location = Location()) + GlobalVariableOperatorAndWriteNode.new(name_loc, operator_loc, value, location) end # Create a new GlobalVariableOperatorOrWriteNode node - def GlobalVariableOperatorOrWriteNode(name_loc, operator_loc, value) - GlobalVariableOperatorOrWriteNode.new(name_loc, operator_loc, value, 0, 0) + def GlobalVariableOperatorOrWriteNode(name_loc, operator_loc, value, location = Location()) + GlobalVariableOperatorOrWriteNode.new(name_loc, operator_loc, value, location) end # Create a new GlobalVariableOperatorWriteNode node - def GlobalVariableOperatorWriteNode(name_loc, operator_loc, value, operator) - GlobalVariableOperatorWriteNode.new(name_loc, operator_loc, value, operator, 0, 0) + def GlobalVariableOperatorWriteNode(name_loc, operator_loc, value, operator, location = Location()) + GlobalVariableOperatorWriteNode.new(name_loc, operator_loc, value, operator, location) end # Create a new GlobalVariableReadNode node - def GlobalVariableReadNode() - GlobalVariableReadNode.new(0, 0) + def GlobalVariableReadNode(location = Location()) + GlobalVariableReadNode.new(location) end # Create a new GlobalVariableWriteNode node - def GlobalVariableWriteNode(name_loc, operator_loc, value) - GlobalVariableWriteNode.new(name_loc, operator_loc, value, 0, 0) + def GlobalVariableWriteNode(name_loc, operator_loc, value, location = Location()) + GlobalVariableWriteNode.new(name_loc, operator_loc, value, location) end # Create a new HashNode node - def HashNode(opening_loc, elements, closing_loc) - HashNode.new(opening_loc, elements, closing_loc, 0, 0) + def HashNode(opening_loc, elements, closing_loc, location = Location()) + HashNode.new(opening_loc, elements, closing_loc, location) end # Create a new HashPatternNode node - def HashPatternNode(constant, assocs, kwrest, opening_loc, closing_loc) - HashPatternNode.new(constant, assocs, kwrest, opening_loc, closing_loc, 0, 0) + def HashPatternNode(constant, assocs, kwrest, opening_loc, closing_loc, location = Location()) + HashPatternNode.new(constant, assocs, kwrest, opening_loc, closing_loc, location) end # Create a new IfNode node - def IfNode(if_keyword_loc, predicate, statements, consequent, end_keyword_loc) - IfNode.new(if_keyword_loc, predicate, statements, consequent, end_keyword_loc, 0, 0) + def IfNode(if_keyword_loc, predicate, statements, consequent, end_keyword_loc, location = Location()) + IfNode.new(if_keyword_loc, predicate, statements, consequent, end_keyword_loc, location) end # Create a new ImaginaryNode node - def ImaginaryNode(numeric) - ImaginaryNode.new(numeric, 0, 0) + def ImaginaryNode(numeric, location = Location()) + ImaginaryNode.new(numeric, location) end # Create a new InNode node - def InNode(pattern, statements, in_loc, then_loc) - InNode.new(pattern, statements, in_loc, then_loc, 0, 0) + def InNode(pattern, statements, in_loc, then_loc, location = Location()) + InNode.new(pattern, statements, in_loc, then_loc, location) end # Create a new InstanceVariableOperatorAndWriteNode node - def InstanceVariableOperatorAndWriteNode(name_loc, operator_loc, value) - InstanceVariableOperatorAndWriteNode.new(name_loc, operator_loc, value, 0, 0) + def InstanceVariableOperatorAndWriteNode(name_loc, operator_loc, value, location = Location()) + InstanceVariableOperatorAndWriteNode.new(name_loc, operator_loc, value, location) end # Create a new InstanceVariableOperatorOrWriteNode node - def InstanceVariableOperatorOrWriteNode(name_loc, operator_loc, value) - InstanceVariableOperatorOrWriteNode.new(name_loc, operator_loc, value, 0, 0) + def InstanceVariableOperatorOrWriteNode(name_loc, operator_loc, value, location = Location()) + InstanceVariableOperatorOrWriteNode.new(name_loc, operator_loc, value, location) end # Create a new InstanceVariableOperatorWriteNode node - def InstanceVariableOperatorWriteNode(name_loc, operator_loc, value, operator) - InstanceVariableOperatorWriteNode.new(name_loc, operator_loc, value, operator, 0, 0) + def InstanceVariableOperatorWriteNode(name_loc, operator_loc, value, operator, location = Location()) + InstanceVariableOperatorWriteNode.new(name_loc, operator_loc, value, operator, location) end # Create a new InstanceVariableReadNode node - def InstanceVariableReadNode() - InstanceVariableReadNode.new(0, 0) + def InstanceVariableReadNode(location = Location()) + InstanceVariableReadNode.new(location) end # Create a new InstanceVariableWriteNode node - def InstanceVariableWriteNode(name_loc, value, operator_loc) - InstanceVariableWriteNode.new(name_loc, value, operator_loc, 0, 0) + def InstanceVariableWriteNode(name_loc, value, operator_loc, location = Location()) + InstanceVariableWriteNode.new(name_loc, value, operator_loc, location) end # Create a new IntegerNode node - def IntegerNode() - IntegerNode.new(0, 0) + def IntegerNode(location = Location()) + IntegerNode.new(location) end # Create a new InterpolatedRegularExpressionNode node - def InterpolatedRegularExpressionNode(opening_loc, parts, closing_loc, flags) - InterpolatedRegularExpressionNode.new(opening_loc, parts, closing_loc, flags, 0, 0) + def InterpolatedRegularExpressionNode(opening_loc, parts, closing_loc, flags, location = Location()) + InterpolatedRegularExpressionNode.new(opening_loc, parts, closing_loc, flags, location) end # Create a new InterpolatedStringNode node - def InterpolatedStringNode(opening_loc, parts, closing_loc) - InterpolatedStringNode.new(opening_loc, parts, closing_loc, 0, 0) + def InterpolatedStringNode(opening_loc, parts, closing_loc, location = Location()) + InterpolatedStringNode.new(opening_loc, parts, closing_loc, location) end # Create a new InterpolatedSymbolNode node - def InterpolatedSymbolNode(opening_loc, parts, closing_loc) - InterpolatedSymbolNode.new(opening_loc, parts, closing_loc, 0, 0) + def InterpolatedSymbolNode(opening_loc, parts, closing_loc, location = Location()) + InterpolatedSymbolNode.new(opening_loc, parts, closing_loc, location) end # Create a new InterpolatedXStringNode node - def InterpolatedXStringNode(opening_loc, parts, closing_loc) - InterpolatedXStringNode.new(opening_loc, parts, closing_loc, 0, 0) + def InterpolatedXStringNode(opening_loc, parts, closing_loc, location = Location()) + InterpolatedXStringNode.new(opening_loc, parts, closing_loc, location) end # Create a new KeywordHashNode node - def KeywordHashNode(elements) - KeywordHashNode.new(elements, 0, 0) + def KeywordHashNode(elements, location = Location()) + KeywordHashNode.new(elements, location) end # Create a new KeywordParameterNode node - def KeywordParameterNode(name_loc, value) - KeywordParameterNode.new(name_loc, value, 0, 0) + def KeywordParameterNode(name_loc, value, location = Location()) + KeywordParameterNode.new(name_loc, value, location) end # Create a new KeywordRestParameterNode node - def KeywordRestParameterNode(operator_loc, name_loc) - KeywordRestParameterNode.new(operator_loc, name_loc, 0, 0) + def KeywordRestParameterNode(operator_loc, name_loc, location = Location()) + KeywordRestParameterNode.new(operator_loc, name_loc, location) end # Create a new LambdaNode node - def LambdaNode(locals, opening_loc, parameters, statements) - LambdaNode.new(locals, opening_loc, parameters, statements, 0, 0) + def LambdaNode(locals, opening_loc, parameters, statements, location = Location()) + LambdaNode.new(locals, opening_loc, parameters, statements, location) end # Create a new LocalVariableOperatorAndWriteNode node - def LocalVariableOperatorAndWriteNode(name_loc, operator_loc, value, constant_id) - LocalVariableOperatorAndWriteNode.new(name_loc, operator_loc, value, constant_id, 0, 0) + def LocalVariableOperatorAndWriteNode(name_loc, operator_loc, value, constant_id, location = Location()) + LocalVariableOperatorAndWriteNode.new(name_loc, operator_loc, value, constant_id, location) end # Create a new LocalVariableOperatorOrWriteNode node - def LocalVariableOperatorOrWriteNode(name_loc, operator_loc, value, constant_id) - LocalVariableOperatorOrWriteNode.new(name_loc, operator_loc, value, constant_id, 0, 0) + def LocalVariableOperatorOrWriteNode(name_loc, operator_loc, value, constant_id, location = Location()) + LocalVariableOperatorOrWriteNode.new(name_loc, operator_loc, value, constant_id, location) end # Create a new LocalVariableOperatorWriteNode node - def LocalVariableOperatorWriteNode(name_loc, operator_loc, value, constant_id, operator_id) - LocalVariableOperatorWriteNode.new(name_loc, operator_loc, value, constant_id, operator_id, 0, 0) + def LocalVariableOperatorWriteNode(name_loc, operator_loc, value, constant_id, operator_id, location = Location()) + LocalVariableOperatorWriteNode.new(name_loc, operator_loc, value, constant_id, operator_id, location) end # Create a new LocalVariableReadNode node - def LocalVariableReadNode(constant_id, depth) - LocalVariableReadNode.new(constant_id, depth, 0, 0) + def LocalVariableReadNode(constant_id, depth, location = Location()) + LocalVariableReadNode.new(constant_id, depth, location) end # Create a new LocalVariableWriteNode node - def LocalVariableWriteNode(constant_id, depth, value, name_loc, operator_loc) - LocalVariableWriteNode.new(constant_id, depth, value, name_loc, operator_loc, 0, 0) + def LocalVariableWriteNode(constant_id, depth, value, name_loc, operator_loc, location = Location()) + LocalVariableWriteNode.new(constant_id, depth, value, name_loc, operator_loc, location) end # Create a new MatchPredicateNode node - def MatchPredicateNode(value, pattern, operator_loc) - MatchPredicateNode.new(value, pattern, operator_loc, 0, 0) + def MatchPredicateNode(value, pattern, operator_loc, location = Location()) + MatchPredicateNode.new(value, pattern, operator_loc, location) end # Create a new MatchRequiredNode node - def MatchRequiredNode(value, pattern, operator_loc) - MatchRequiredNode.new(value, pattern, operator_loc, 0, 0) + def MatchRequiredNode(value, pattern, operator_loc, location = Location()) + MatchRequiredNode.new(value, pattern, operator_loc, location) end # Create a new MissingNode node - def MissingNode() - MissingNode.new(0, 0) + def MissingNode(location = Location()) + MissingNode.new(location) end # Create a new ModuleNode node - def ModuleNode(locals, module_keyword_loc, constant_path, statements, end_keyword_loc) - ModuleNode.new(locals, module_keyword_loc, constant_path, statements, end_keyword_loc, 0, 0) + def ModuleNode(locals, module_keyword_loc, constant_path, statements, end_keyword_loc, location = Location()) + ModuleNode.new(locals, module_keyword_loc, constant_path, statements, end_keyword_loc, location) end # Create a new MultiWriteNode node - def MultiWriteNode(targets, operator_loc, value, lparen_loc, rparen_loc) - MultiWriteNode.new(targets, operator_loc, value, lparen_loc, rparen_loc, 0, 0) + def MultiWriteNode(targets, operator_loc, value, lparen_loc, rparen_loc, location = Location()) + MultiWriteNode.new(targets, operator_loc, value, lparen_loc, rparen_loc, location) end # Create a new NextNode node - def NextNode(arguments, keyword_loc) - NextNode.new(arguments, keyword_loc, 0, 0) + def NextNode(arguments, keyword_loc, location = Location()) + NextNode.new(arguments, keyword_loc, location) end # Create a new NilNode node - def NilNode() - NilNode.new(0, 0) + def NilNode(location = Location()) + NilNode.new(location) end # Create a new NoKeywordsParameterNode node - def NoKeywordsParameterNode(operator_loc, keyword_loc) - NoKeywordsParameterNode.new(operator_loc, keyword_loc, 0, 0) + def NoKeywordsParameterNode(operator_loc, keyword_loc, location = Location()) + NoKeywordsParameterNode.new(operator_loc, keyword_loc, location) end # Create a new NumberedReferenceReadNode node - def NumberedReferenceReadNode() - NumberedReferenceReadNode.new(0, 0) + def NumberedReferenceReadNode(location = Location()) + NumberedReferenceReadNode.new(location) end # Create a new OptionalParameterNode node - def OptionalParameterNode(constant_id, name_loc, operator_loc, value) - OptionalParameterNode.new(constant_id, name_loc, operator_loc, value, 0, 0) + def OptionalParameterNode(constant_id, name_loc, operator_loc, value, location = Location()) + OptionalParameterNode.new(constant_id, name_loc, operator_loc, value, location) end # Create a new OrNode node - def OrNode(left, right, operator_loc) - OrNode.new(left, right, operator_loc, 0, 0) + def OrNode(left, right, operator_loc, location = Location()) + OrNode.new(left, right, operator_loc, location) end # Create a new ParametersNode node - def ParametersNode(requireds, optionals, posts, rest, keywords, keyword_rest, block) - ParametersNode.new(requireds, optionals, posts, rest, keywords, keyword_rest, block, 0, 0) + def ParametersNode(requireds, optionals, posts, rest, keywords, keyword_rest, block, location = Location()) + ParametersNode.new(requireds, optionals, posts, rest, keywords, keyword_rest, block, location) end # Create a new ParenthesesNode node - def ParenthesesNode(statements, opening_loc, closing_loc) - ParenthesesNode.new(statements, opening_loc, closing_loc, 0, 0) + def ParenthesesNode(statements, opening_loc, closing_loc, location = Location()) + ParenthesesNode.new(statements, opening_loc, closing_loc, location) end # Create a new PinnedExpressionNode node - def PinnedExpressionNode(expression, operator_loc, lparen_loc, rparen_loc) - PinnedExpressionNode.new(expression, operator_loc, lparen_loc, rparen_loc, 0, 0) + def PinnedExpressionNode(expression, operator_loc, lparen_loc, rparen_loc, location = Location()) + PinnedExpressionNode.new(expression, operator_loc, lparen_loc, rparen_loc, location) end # Create a new PinnedVariableNode node - def PinnedVariableNode(variable, operator_loc) - PinnedVariableNode.new(variable, operator_loc, 0, 0) + def PinnedVariableNode(variable, operator_loc, location = Location()) + PinnedVariableNode.new(variable, operator_loc, location) end # Create a new PostExecutionNode node - def PostExecutionNode(statements, keyword_loc, opening_loc, closing_loc) - PostExecutionNode.new(statements, keyword_loc, opening_loc, closing_loc, 0, 0) + def PostExecutionNode(statements, keyword_loc, opening_loc, closing_loc, location = Location()) + PostExecutionNode.new(statements, keyword_loc, opening_loc, closing_loc, location) end # Create a new PreExecutionNode node - def PreExecutionNode(statements, keyword_loc, opening_loc, closing_loc) - PreExecutionNode.new(statements, keyword_loc, opening_loc, closing_loc, 0, 0) + def PreExecutionNode(statements, keyword_loc, opening_loc, closing_loc, location = Location()) + PreExecutionNode.new(statements, keyword_loc, opening_loc, closing_loc, location) end # Create a new ProgramNode node - def ProgramNode(locals, statements) - ProgramNode.new(locals, statements, 0, 0) + def ProgramNode(locals, statements, location = Location()) + ProgramNode.new(locals, statements, location) end # Create a new RangeNode node - def RangeNode(left, right, operator_loc, flags) - RangeNode.new(left, right, operator_loc, flags, 0, 0) + def RangeNode(left, right, operator_loc, flags, location = Location()) + RangeNode.new(left, right, operator_loc, flags, location) end # Create a new RationalNode node - def RationalNode(numeric) - RationalNode.new(numeric, 0, 0) + def RationalNode(numeric, location = Location()) + RationalNode.new(numeric, location) end # Create a new RedoNode node - def RedoNode() - RedoNode.new(0, 0) + def RedoNode(location = Location()) + RedoNode.new(location) end # Create a new RegularExpressionNode node - def RegularExpressionNode(opening_loc, content_loc, closing_loc, unescaped, flags) - RegularExpressionNode.new(opening_loc, content_loc, closing_loc, unescaped, flags, 0, 0) + def RegularExpressionNode(opening_loc, content_loc, closing_loc, unescaped, flags, location = Location()) + RegularExpressionNode.new(opening_loc, content_loc, closing_loc, unescaped, flags, location) end # Create a new RequiredDestructuredParameterNode node - def RequiredDestructuredParameterNode(parameters, opening_loc, closing_loc) - RequiredDestructuredParameterNode.new(parameters, opening_loc, closing_loc, 0, 0) + def RequiredDestructuredParameterNode(parameters, opening_loc, closing_loc, location = Location()) + RequiredDestructuredParameterNode.new(parameters, opening_loc, closing_loc, location) end # Create a new RequiredParameterNode node - def RequiredParameterNode(constant_id) - RequiredParameterNode.new(constant_id, 0, 0) + def RequiredParameterNode(constant_id, location = Location()) + RequiredParameterNode.new(constant_id, location) end # Create a new RescueModifierNode node - def RescueModifierNode(expression, keyword_loc, rescue_expression) - RescueModifierNode.new(expression, keyword_loc, rescue_expression, 0, 0) + def RescueModifierNode(expression, keyword_loc, rescue_expression, location = Location()) + RescueModifierNode.new(expression, keyword_loc, rescue_expression, location) end # Create a new RescueNode node - def RescueNode(keyword_loc, exceptions, operator_loc, exception, statements, consequent) - RescueNode.new(keyword_loc, exceptions, operator_loc, exception, statements, consequent, 0, 0) + def RescueNode(keyword_loc, exceptions, operator_loc, exception, statements, consequent, location = Location()) + RescueNode.new(keyword_loc, exceptions, operator_loc, exception, statements, consequent, location) end # Create a new RestParameterNode node - def RestParameterNode(operator_loc, name_loc) - RestParameterNode.new(operator_loc, name_loc, 0, 0) + def RestParameterNode(operator_loc, name_loc, location = Location()) + RestParameterNode.new(operator_loc, name_loc, location) end # Create a new RetryNode node - def RetryNode() - RetryNode.new(0, 0) + def RetryNode(location = Location()) + RetryNode.new(location) end # Create a new ReturnNode node - def ReturnNode(keyword_loc, arguments) - ReturnNode.new(keyword_loc, arguments, 0, 0) + def ReturnNode(keyword_loc, arguments, location = Location()) + ReturnNode.new(keyword_loc, arguments, location) end # Create a new SelfNode node - def SelfNode() - SelfNode.new(0, 0) + def SelfNode(location = Location()) + SelfNode.new(location) end # Create a new SingletonClassNode node - def SingletonClassNode(locals, class_keyword_loc, operator_loc, expression, statements, end_keyword_loc) - SingletonClassNode.new(locals, class_keyword_loc, operator_loc, expression, statements, end_keyword_loc, 0, 0) + def SingletonClassNode(locals, class_keyword_loc, operator_loc, expression, statements, end_keyword_loc, location = Location()) + SingletonClassNode.new(locals, class_keyword_loc, operator_loc, expression, statements, end_keyword_loc, location) end # Create a new SourceEncodingNode node - def SourceEncodingNode() - SourceEncodingNode.new(0, 0) + def SourceEncodingNode(location = Location()) + SourceEncodingNode.new(location) end # Create a new SourceFileNode node - def SourceFileNode(filepath) - SourceFileNode.new(filepath, 0, 0) + def SourceFileNode(filepath, location = Location()) + SourceFileNode.new(filepath, location) end # Create a new SourceLineNode node - def SourceLineNode() - SourceLineNode.new(0, 0) + def SourceLineNode(location = Location()) + SourceLineNode.new(location) end # Create a new SplatNode node - def SplatNode(operator_loc, expression) - SplatNode.new(operator_loc, expression, 0, 0) + def SplatNode(operator_loc, expression, location = Location()) + SplatNode.new(operator_loc, expression, location) end # Create a new StatementsNode node - def StatementsNode(body) - StatementsNode.new(body, 0, 0) + def StatementsNode(body, location = Location()) + StatementsNode.new(body, location) end # Create a new StringConcatNode node - def StringConcatNode(left, right) - StringConcatNode.new(left, right, 0, 0) + def StringConcatNode(left, right, location = Location()) + StringConcatNode.new(left, right, location) end # Create a new StringNode node - def StringNode(opening_loc, content_loc, closing_loc, unescaped) - StringNode.new(opening_loc, content_loc, closing_loc, unescaped, 0, 0) + def StringNode(opening_loc, content_loc, closing_loc, unescaped, location = Location()) + StringNode.new(opening_loc, content_loc, closing_loc, unescaped, location) end # Create a new SuperNode node - def SuperNode(keyword_loc, lparen_loc, arguments, rparen_loc, block) - SuperNode.new(keyword_loc, lparen_loc, arguments, rparen_loc, block, 0, 0) + def SuperNode(keyword_loc, lparen_loc, arguments, rparen_loc, block, location = Location()) + SuperNode.new(keyword_loc, lparen_loc, arguments, rparen_loc, block, location) end # Create a new SymbolNode node - def SymbolNode(opening_loc, value_loc, closing_loc, unescaped) - SymbolNode.new(opening_loc, value_loc, closing_loc, unescaped, 0, 0) + def SymbolNode(opening_loc, value_loc, closing_loc, unescaped, location = Location()) + SymbolNode.new(opening_loc, value_loc, closing_loc, unescaped, location) end # Create a new TrueNode node - def TrueNode() - TrueNode.new(0, 0) + def TrueNode(location = Location()) + TrueNode.new(location) end # Create a new UndefNode node - def UndefNode(names, keyword_loc) - UndefNode.new(names, keyword_loc, 0, 0) + def UndefNode(names, keyword_loc, location = Location()) + UndefNode.new(names, keyword_loc, location) end # Create a new UnlessNode node - def UnlessNode(keyword_loc, predicate, statements, consequent, end_keyword_loc) - UnlessNode.new(keyword_loc, predicate, statements, consequent, end_keyword_loc, 0, 0) + def UnlessNode(keyword_loc, predicate, statements, consequent, end_keyword_loc, location = Location()) + UnlessNode.new(keyword_loc, predicate, statements, consequent, end_keyword_loc, location) end # Create a new UntilNode node - def UntilNode(keyword_loc, predicate, statements) - UntilNode.new(keyword_loc, predicate, statements, 0, 0) + def UntilNode(keyword_loc, predicate, statements, location = Location()) + UntilNode.new(keyword_loc, predicate, statements, location) end # Create a new WhenNode node - def WhenNode(keyword_loc, conditions, statements) - WhenNode.new(keyword_loc, conditions, statements, 0, 0) + def WhenNode(keyword_loc, conditions, statements, location = Location()) + WhenNode.new(keyword_loc, conditions, statements, location) end # Create a new WhileNode node - def WhileNode(keyword_loc, predicate, statements) - WhileNode.new(keyword_loc, predicate, statements, 0, 0) + def WhileNode(keyword_loc, predicate, statements, location = Location()) + WhileNode.new(keyword_loc, predicate, statements, location) end # Create a new XStringNode node - def XStringNode(opening_loc, content_loc, closing_loc, unescaped) - XStringNode.new(opening_loc, content_loc, closing_loc, unescaped, 0, 0) + def XStringNode(opening_loc, content_loc, closing_loc, unescaped, location = Location()) + XStringNode.new(opening_loc, content_loc, closing_loc, unescaped, location) end # Create a new YieldNode node - def YieldNode(keyword_loc, lparen_loc, arguments, rparen_loc) - YieldNode.new(keyword_loc, lparen_loc, arguments, rparen_loc, 0, 0) + def YieldNode(keyword_loc, lparen_loc, arguments, rparen_loc, location = Location()) + YieldNode.new(keyword_loc, lparen_loc, arguments, rparen_loc, location) end end end diff --git a/lib/yarp/serialize.rb b/lib/yarp/serialize.rb index f6861f24b5..6295a94d8c 100644 --- a/lib/yarp/serialize.rb +++ b/lib/yarp/serialize.rb @@ -9,26 +9,30 @@ require "stringio" module YARP module Serialize - def self.load(source, serialized) + def self.load(input, serialized) io = StringIO.new(serialized) io.set_encoding(Encoding::BINARY) - Loader.new(source, serialized, io).load + Loader.new(input, serialized, io).load end class Loader - attr_reader :encoding, :source, :serialized, :io - attr_reader :constant_pool_offset, :constant_pool + attr_reader :encoding, :input, :serialized, :io + attr_reader :constant_pool_offset, :constant_pool, :source - def initialize(source, serialized, io) + def initialize(input, serialized, io) @encoding = Encoding::UTF_8 - @source = source.dup + @input = input.dup @serialized = serialized @io = io @constant_pool_offset = nil @constant_pool = nil + + offsets = [0] + input.b.scan("\n") { offsets << $~.end(0) } + @source = Source.new(input, offsets) end def load @@ -36,7 +40,7 @@ module YARP io.read(3).unpack("C3") => [0, 4, 0] @encoding = Encoding.find(io.read(load_varint)) - @source = source.force_encoding(@encoding).freeze + @input = input.force_encoding(@encoding).freeze @constant_pool_offset = io.read(4).unpack1("L") @constant_pool = Array.new(load_varint, nil) @@ -78,7 +82,7 @@ module YARP end def load_location - Location.new(load_varint, load_varint) + Location.new(source, load_varint, load_varint) end def load_optional_location @@ -95,7 +99,7 @@ module YARP start = serialized.unpack1("L", offset: offset) length = serialized.unpack1("L", offset: offset + 4) - constant = source.byteslice(start, length).to_sym + constant = input.byteslice(start, length).to_sym constant_pool[index] = constant end @@ -104,262 +108,262 @@ module YARP def load_node type = io.getbyte - start_offset, length = load_varint, load_varint + location = load_location case type when 1 then - AliasNode.new(load_node, load_node, load_location, start_offset, length) + AliasNode.new(load_node, load_node, load_location, location) when 2 then - AlternationPatternNode.new(load_node, load_node, load_location, start_offset, length) + AlternationPatternNode.new(load_node, load_node, load_location, location) when 3 then - AndNode.new(load_node, load_node, load_location, start_offset, length) + AndNode.new(load_node, load_node, load_location, location) when 4 then - ArgumentsNode.new(Array.new(load_varint) { load_node }, start_offset, length) + ArgumentsNode.new(Array.new(load_varint) { load_node }, location) when 5 then - ArrayNode.new(Array.new(load_varint) { load_node }, load_optional_location, load_optional_location, start_offset, length) + ArrayNode.new(Array.new(load_varint) { load_node }, load_optional_location, load_optional_location, location) when 6 then - ArrayPatternNode.new(load_optional_node, Array.new(load_varint) { load_node }, load_optional_node, Array.new(load_varint) { load_node }, load_optional_location, load_optional_location, start_offset, length) + ArrayPatternNode.new(load_optional_node, Array.new(load_varint) { load_node }, load_optional_node, Array.new(load_varint) { load_node }, load_optional_location, load_optional_location, location) when 7 then - AssocNode.new(load_node, load_optional_node, load_optional_location, start_offset, length) + AssocNode.new(load_node, load_optional_node, load_optional_location, location) when 8 then - AssocSplatNode.new(load_optional_node, load_location, start_offset, length) + AssocSplatNode.new(load_optional_node, load_location, location) when 9 then - BackReferenceReadNode.new(start_offset, length) + BackReferenceReadNode.new(location) when 10 then - BeginNode.new(load_optional_location, load_optional_node, load_optional_node, load_optional_node, load_optional_node, load_optional_location, start_offset, length) + BeginNode.new(load_optional_location, load_optional_node, load_optional_node, load_optional_node, load_optional_node, load_optional_location, location) when 11 then - BlockArgumentNode.new(load_optional_node, load_location, start_offset, length) + BlockArgumentNode.new(load_optional_node, load_location, location) when 12 then - BlockNode.new(Array.new(load_varint) { load_constant }, load_optional_node, load_optional_node, load_location, load_location, start_offset, length) + BlockNode.new(Array.new(load_varint) { load_constant }, load_optional_node, load_optional_node, load_location, load_location, location) when 13 then - BlockParameterNode.new(load_optional_location, load_location, start_offset, length) + BlockParameterNode.new(load_optional_location, load_location, location) when 14 then - BlockParametersNode.new(load_optional_node, Array.new(load_varint) { load_location }, load_optional_location, load_optional_location, start_offset, length) + BlockParametersNode.new(load_optional_node, Array.new(load_varint) { load_location }, load_optional_location, load_optional_location, location) when 15 then - BreakNode.new(load_optional_node, load_location, start_offset, length) + BreakNode.new(load_optional_node, load_location, location) when 16 then - CallNode.new(load_optional_node, load_optional_location, load_optional_location, load_optional_location, load_optional_node, load_optional_location, load_optional_node, load_varint, load_string, start_offset, length) + CallNode.new(load_optional_node, load_optional_location, load_optional_location, load_optional_location, load_optional_node, load_optional_location, load_optional_node, load_varint, load_string, location) when 17 then - CallOperatorAndWriteNode.new(load_node, load_location, load_node, start_offset, length) + CallOperatorAndWriteNode.new(load_node, load_location, load_node, location) when 18 then - CallOperatorOrWriteNode.new(load_node, load_node, load_location, start_offset, length) + CallOperatorOrWriteNode.new(load_node, load_node, load_location, location) when 19 then - CallOperatorWriteNode.new(load_node, load_location, load_node, load_constant, start_offset, length) + CallOperatorWriteNode.new(load_node, load_location, load_node, load_constant, location) when 20 then - CapturePatternNode.new(load_node, load_node, load_location, start_offset, length) + CapturePatternNode.new(load_node, load_node, load_location, location) when 21 then - CaseNode.new(load_optional_node, Array.new(load_varint) { load_node }, load_optional_node, load_location, load_location, start_offset, length) + CaseNode.new(load_optional_node, Array.new(load_varint) { load_node }, load_optional_node, load_location, load_location, location) when 22 then - ClassNode.new(Array.new(load_varint) { load_constant }, load_location, load_node, load_optional_location, load_optional_node, load_optional_node, load_location, start_offset, length) + ClassNode.new(Array.new(load_varint) { load_constant }, load_location, load_node, load_optional_location, load_optional_node, load_optional_node, load_location, location) when 23 then - ClassVariableOperatorAndWriteNode.new(load_location, load_location, load_node, start_offset, length) + ClassVariableOperatorAndWriteNode.new(load_location, load_location, load_node, location) when 24 then - ClassVariableOperatorOrWriteNode.new(load_location, load_location, load_node, start_offset, length) + ClassVariableOperatorOrWriteNode.new(load_location, load_location, load_node, location) when 25 then - ClassVariableOperatorWriteNode.new(load_location, load_location, load_node, load_constant, start_offset, length) + ClassVariableOperatorWriteNode.new(load_location, load_location, load_node, load_constant, location) when 26 then - ClassVariableReadNode.new(start_offset, length) + ClassVariableReadNode.new(location) when 27 then - ClassVariableWriteNode.new(load_location, load_optional_node, load_optional_location, start_offset, length) + ClassVariableWriteNode.new(load_location, load_optional_node, load_optional_location, location) when 28 then - ConstantOperatorAndWriteNode.new(load_location, load_location, load_node, start_offset, length) + ConstantOperatorAndWriteNode.new(load_location, load_location, load_node, location) when 29 then - ConstantOperatorOrWriteNode.new(load_location, load_location, load_node, start_offset, length) + ConstantOperatorOrWriteNode.new(load_location, load_location, load_node, location) when 30 then - ConstantOperatorWriteNode.new(load_location, load_location, load_node, load_constant, start_offset, length) + ConstantOperatorWriteNode.new(load_location, load_location, load_node, load_constant, location) when 31 then - ConstantPathNode.new(load_optional_node, load_node, load_location, start_offset, length) + ConstantPathNode.new(load_optional_node, load_node, load_location, location) when 32 then - ConstantPathOperatorAndWriteNode.new(load_node, load_location, load_node, start_offset, length) + ConstantPathOperatorAndWriteNode.new(load_node, load_location, load_node, location) when 33 then - ConstantPathOperatorOrWriteNode.new(load_node, load_location, load_node, start_offset, length) + ConstantPathOperatorOrWriteNode.new(load_node, load_location, load_node, location) when 34 then - ConstantPathOperatorWriteNode.new(load_node, load_location, load_node, load_constant, start_offset, length) + ConstantPathOperatorWriteNode.new(load_node, load_location, load_node, load_constant, location) when 35 then - ConstantPathWriteNode.new(load_node, load_optional_location, load_optional_node, start_offset, length) + ConstantPathWriteNode.new(load_node, load_optional_location, load_optional_node, location) when 36 then - ConstantReadNode.new(start_offset, length) + ConstantReadNode.new(location) when 37 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, start_offset, 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, start_offset, length) + 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, start_offset, length) + ElseNode.new(load_location, load_optional_node, load_optional_location, location) when 40 then - EmbeddedStatementsNode.new(load_location, load_optional_node, load_location, start_offset, length) + EmbeddedStatementsNode.new(load_location, load_optional_node, load_location, location) when 41 then - EmbeddedVariableNode.new(load_location, load_node, start_offset, length) + EmbeddedVariableNode.new(load_location, load_node, location) when 42 then - EnsureNode.new(load_location, load_optional_node, load_location, start_offset, length) + EnsureNode.new(load_location, load_optional_node, load_location, location) when 43 then - FalseNode.new(start_offset, length) + FalseNode.new(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, start_offset, length) + FindPatternNode.new(load_optional_node, load_node, Array.new(load_varint) { load_node }, load_node, load_optional_location, load_optional_location, location) when 45 then - FloatNode.new(start_offset, length) + FloatNode.new(location) when 46 then - ForNode.new(load_node, load_node, load_optional_node, load_location, load_location, load_optional_location, load_location, start_offset, length) + ForNode.new(load_node, load_node, load_optional_node, load_location, load_location, load_optional_location, load_location, location) when 47 then - ForwardingArgumentsNode.new(start_offset, length) + ForwardingArgumentsNode.new(location) when 48 then - ForwardingParameterNode.new(start_offset, length) + ForwardingParameterNode.new(location) when 49 then - ForwardingSuperNode.new(load_optional_node, start_offset, length) + ForwardingSuperNode.new(load_optional_node, location) when 50 then - GlobalVariableOperatorAndWriteNode.new(load_location, load_location, load_node, start_offset, length) + GlobalVariableOperatorAndWriteNode.new(load_location, load_location, load_node, location) when 51 then - GlobalVariableOperatorOrWriteNode.new(load_location, load_location, load_node, start_offset, length) + GlobalVariableOperatorOrWriteNode.new(load_location, load_location, load_node, location) when 52 then - GlobalVariableOperatorWriteNode.new(load_location, load_location, load_node, load_constant, start_offset, length) + GlobalVariableOperatorWriteNode.new(load_location, load_location, load_node, load_constant, location) when 53 then - GlobalVariableReadNode.new(start_offset, length) + GlobalVariableReadNode.new(location) when 54 then - GlobalVariableWriteNode.new(load_location, load_optional_location, load_optional_node, start_offset, length) + GlobalVariableWriteNode.new(load_location, load_optional_location, load_optional_node, location) when 55 then - HashNode.new(load_location, Array.new(load_varint) { load_node }, load_location, start_offset, length) + HashNode.new(load_location, Array.new(load_varint) { load_node }, load_location, location) when 56 then - HashPatternNode.new(load_optional_node, Array.new(load_varint) { load_node }, load_optional_node, load_optional_location, load_optional_location, start_offset, length) + HashPatternNode.new(load_optional_node, Array.new(load_varint) { load_node }, load_optional_node, load_optional_location, load_optional_location, location) when 57 then - IfNode.new(load_optional_location, load_node, load_optional_node, load_optional_node, load_optional_location, start_offset, length) + IfNode.new(load_optional_location, load_node, load_optional_node, load_optional_node, load_optional_location, location) when 58 then - ImaginaryNode.new(load_node, start_offset, length) + ImaginaryNode.new(load_node, location) when 59 then - InNode.new(load_node, load_optional_node, load_location, load_optional_location, start_offset, length) + InNode.new(load_node, load_optional_node, load_location, load_optional_location, location) when 60 then - InstanceVariableOperatorAndWriteNode.new(load_location, load_location, load_node, start_offset, length) + InstanceVariableOperatorAndWriteNode.new(load_location, load_location, load_node, location) when 61 then - InstanceVariableOperatorOrWriteNode.new(load_location, load_location, load_node, start_offset, length) + InstanceVariableOperatorOrWriteNode.new(load_location, load_location, load_node, location) when 62 then - InstanceVariableOperatorWriteNode.new(load_location, load_location, load_node, load_constant, start_offset, length) + InstanceVariableOperatorWriteNode.new(load_location, load_location, load_node, load_constant, location) when 63 then - InstanceVariableReadNode.new(start_offset, length) + InstanceVariableReadNode.new(location) when 64 then - InstanceVariableWriteNode.new(load_location, load_optional_node, load_optional_location, start_offset, length) + InstanceVariableWriteNode.new(load_location, load_optional_node, load_optional_location, location) when 65 then - IntegerNode.new(start_offset, length) + IntegerNode.new(location) when 66 then - InterpolatedRegularExpressionNode.new(load_location, Array.new(load_varint) { load_node }, load_location, load_varint, start_offset, length) + InterpolatedRegularExpressionNode.new(load_location, Array.new(load_varint) { load_node }, load_location, load_varint, location) when 67 then - InterpolatedStringNode.new(load_optional_location, Array.new(load_varint) { load_node }, load_optional_location, start_offset, length) + InterpolatedStringNode.new(load_optional_location, Array.new(load_varint) { load_node }, load_optional_location, location) when 68 then - InterpolatedSymbolNode.new(load_optional_location, Array.new(load_varint) { load_node }, load_optional_location, start_offset, length) + InterpolatedSymbolNode.new(load_optional_location, Array.new(load_varint) { load_node }, load_optional_location, location) when 69 then - InterpolatedXStringNode.new(load_location, Array.new(load_varint) { load_node }, load_location, start_offset, length) + InterpolatedXStringNode.new(load_location, Array.new(load_varint) { load_node }, load_location, location) when 70 then - KeywordHashNode.new(Array.new(load_varint) { load_node }, start_offset, length) + KeywordHashNode.new(Array.new(load_varint) { load_node }, location) when 71 then - KeywordParameterNode.new(load_location, load_optional_node, start_offset, length) + KeywordParameterNode.new(load_location, load_optional_node, location) when 72 then - KeywordRestParameterNode.new(load_location, load_optional_location, start_offset, length) + KeywordRestParameterNode.new(load_location, load_optional_location, location) when 73 then - LambdaNode.new(Array.new(load_varint) { load_constant }, load_location, load_optional_node, load_optional_node, start_offset, length) + LambdaNode.new(Array.new(load_varint) { load_constant }, load_location, load_optional_node, load_optional_node, location) when 74 then - LocalVariableOperatorAndWriteNode.new(load_location, load_location, load_node, load_constant, start_offset, length) + LocalVariableOperatorAndWriteNode.new(load_location, load_location, load_node, load_constant, location) when 75 then - LocalVariableOperatorOrWriteNode.new(load_location, load_location, load_node, load_constant, start_offset, length) + LocalVariableOperatorOrWriteNode.new(load_location, load_location, load_node, load_constant, location) when 76 then - LocalVariableOperatorWriteNode.new(load_location, load_location, load_node, load_constant, load_constant, start_offset, length) + LocalVariableOperatorWriteNode.new(load_location, load_location, load_node, load_constant, load_constant, location) when 77 then - LocalVariableReadNode.new(load_constant, load_varint, start_offset, length) + LocalVariableReadNode.new(load_constant, load_varint, location) when 78 then - LocalVariableWriteNode.new(load_constant, load_varint, load_optional_node, load_location, load_optional_location, start_offset, length) + LocalVariableWriteNode.new(load_constant, load_varint, load_optional_node, load_location, load_optional_location, location) when 79 then - MatchPredicateNode.new(load_node, load_node, load_location, start_offset, length) + MatchPredicateNode.new(load_node, load_node, load_location, location) when 80 then - MatchRequiredNode.new(load_node, load_node, load_location, start_offset, length) + MatchRequiredNode.new(load_node, load_node, load_location, location) when 81 then - MissingNode.new(start_offset, length) + MissingNode.new(location) when 82 then - ModuleNode.new(Array.new(load_varint) { load_constant }, load_location, load_node, load_optional_node, load_location, start_offset, length) + ModuleNode.new(Array.new(load_varint) { load_constant }, load_location, load_node, load_optional_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, start_offset, length) + MultiWriteNode.new(Array.new(load_varint) { load_node }, load_optional_location, load_optional_node, load_optional_location, load_optional_location, location) when 84 then - NextNode.new(load_optional_node, load_location, start_offset, length) + NextNode.new(load_optional_node, load_location, location) when 85 then - NilNode.new(start_offset, length) + NilNode.new(location) when 86 then - NoKeywordsParameterNode.new(load_location, load_location, start_offset, length) + NoKeywordsParameterNode.new(load_location, load_location, location) when 87 then - NumberedReferenceReadNode.new(start_offset, length) + NumberedReferenceReadNode.new(location) when 88 then - OptionalParameterNode.new(load_constant, load_location, load_location, load_node, start_offset, length) + OptionalParameterNode.new(load_constant, load_location, load_location, load_node, location) when 89 then - OrNode.new(load_node, load_node, load_location, start_offset, length) + OrNode.new(load_node, load_node, load_location, 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, start_offset, length) + 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 91 then - ParenthesesNode.new(load_optional_node, load_location, load_location, start_offset, length) + ParenthesesNode.new(load_optional_node, load_location, load_location, location) when 92 then - PinnedExpressionNode.new(load_node, load_location, load_location, load_location, start_offset, length) + PinnedExpressionNode.new(load_node, load_location, load_location, load_location, location) when 93 then - PinnedVariableNode.new(load_node, load_location, start_offset, length) + PinnedVariableNode.new(load_node, load_location, location) when 94 then - PostExecutionNode.new(load_optional_node, load_location, load_location, load_location, start_offset, length) + PostExecutionNode.new(load_optional_node, load_location, load_location, load_location, location) when 95 then - PreExecutionNode.new(load_optional_node, load_location, load_location, load_location, start_offset, length) + PreExecutionNode.new(load_optional_node, load_location, load_location, load_location, location) when 96 then - ProgramNode.new(Array.new(load_varint) { load_constant }, load_node, start_offset, length) + ProgramNode.new(Array.new(load_varint) { load_constant }, load_node, location) when 97 then - RangeNode.new(load_optional_node, load_optional_node, load_location, load_varint, start_offset, length) + RangeNode.new(load_optional_node, load_optional_node, load_location, load_varint, location) when 98 then - RationalNode.new(load_node, start_offset, length) + RationalNode.new(load_node, location) when 99 then - RedoNode.new(start_offset, length) + RedoNode.new(location) when 100 then - RegularExpressionNode.new(load_location, load_location, load_location, load_string, load_varint, start_offset, length) + RegularExpressionNode.new(load_location, load_location, load_location, load_string, load_varint, location) when 101 then - RequiredDestructuredParameterNode.new(Array.new(load_varint) { load_node }, load_location, load_location, start_offset, length) + RequiredDestructuredParameterNode.new(Array.new(load_varint) { load_node }, load_location, load_location, location) when 102 then - RequiredParameterNode.new(load_constant, start_offset, length) + RequiredParameterNode.new(load_constant, location) when 103 then - RescueModifierNode.new(load_node, load_location, load_node, start_offset, length) + RescueModifierNode.new(load_node, load_location, load_node, 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, start_offset, length) + RescueNode.new(load_location, Array.new(load_varint) { load_node }, load_optional_location, load_optional_node, load_optional_node, load_optional_node, location) when 105 then - RestParameterNode.new(load_location, load_optional_location, start_offset, length) + RestParameterNode.new(load_location, load_optional_location, location) when 106 then - RetryNode.new(start_offset, length) + RetryNode.new(location) when 107 then - ReturnNode.new(load_location, load_optional_node, start_offset, length) + ReturnNode.new(load_location, load_optional_node, location) when 108 then - SelfNode.new(start_offset, length) + SelfNode.new(location) when 109 then - SingletonClassNode.new(Array.new(load_varint) { load_constant }, load_location, load_location, load_node, load_optional_node, load_location, start_offset, length) + SingletonClassNode.new(Array.new(load_varint) { load_constant }, load_location, load_location, load_node, load_optional_node, load_location, location) when 110 then - SourceEncodingNode.new(start_offset, length) + SourceEncodingNode.new(location) when 111 then - SourceFileNode.new(load_string, start_offset, length) + SourceFileNode.new(load_string, location) when 112 then - SourceLineNode.new(start_offset, length) + SourceLineNode.new(location) when 113 then - SplatNode.new(load_location, load_optional_node, start_offset, length) + SplatNode.new(load_location, load_optional_node, location) when 114 then - StatementsNode.new(Array.new(load_varint) { load_node }, start_offset, length) + StatementsNode.new(Array.new(load_varint) { load_node }, location) when 115 then - StringConcatNode.new(load_node, load_node, start_offset, length) + StringConcatNode.new(load_node, load_node, location) when 116 then - StringNode.new(load_optional_location, load_location, load_optional_location, load_string, start_offset, length) + StringNode.new(load_optional_location, load_location, load_optional_location, load_string, location) when 117 then - SuperNode.new(load_location, load_optional_location, load_optional_node, load_optional_location, load_optional_node, start_offset, length) + SuperNode.new(load_location, load_optional_location, load_optional_node, load_optional_location, load_optional_node, location) when 118 then - SymbolNode.new(load_optional_location, load_location, load_optional_location, load_string, start_offset, length) + SymbolNode.new(load_optional_location, load_location, load_optional_location, load_string, location) when 119 then - TrueNode.new(start_offset, length) + TrueNode.new(location) when 120 then - UndefNode.new(Array.new(load_varint) { load_node }, load_location, start_offset, length) + UndefNode.new(Array.new(load_varint) { load_node }, load_location, location) when 121 then - UnlessNode.new(load_location, load_node, load_optional_node, load_optional_node, load_optional_location, start_offset, length) + UnlessNode.new(load_location, load_node, load_optional_node, load_optional_node, load_optional_location, location) when 122 then - UntilNode.new(load_location, load_node, load_optional_node, start_offset, length) + UntilNode.new(load_location, load_node, load_optional_node, location) when 123 then - WhenNode.new(load_location, Array.new(load_varint) { load_node }, load_optional_node, start_offset, length) + WhenNode.new(load_location, Array.new(load_varint) { load_node }, load_optional_node, location) when 124 then - WhileNode.new(load_location, load_node, load_optional_node, start_offset, length) + WhileNode.new(load_location, load_node, load_optional_node, location) when 125 then - XStringNode.new(load_location, load_location, load_location, load_string, start_offset, length) + XStringNode.new(load_location, load_location, load_location, load_string, location) when 126 then - YieldNode.new(load_location, load_optional_location, load_optional_node, load_optional_location, start_offset, length) + YieldNode.new(load_location, load_optional_location, load_optional_node, load_optional_location, location) end end end diff --git a/test/yarp/compile_test.rb b/test/yarp/compile_test.rb deleted file mode 100644 index d0be863db5..0000000000 --- a/test/yarp/compile_test.rb +++ /dev/null @@ -1,212 +0,0 @@ -# frozen_string_literal: true - -require "yarp_test_helper" - -class CompileTest < Test::Unit::TestCase - def test_AliasNode - assert_compiles("alias foo bar") - end - - def test_AndNode - assert_compiles("true && false") - end - - def test_ArrayNode - assert_compiles("[]") - assert_compiles("[foo, bar, baz]") - end - - def test_AssocNode - assert_compiles("{ foo: bar }") - end - - def test_BlockNode - assert_compiles("foo { bar }") - end - - def test_BlockNode_with_optionals - assert_compiles("foo { |x = 1| bar }") - end - - def test_CallNode - assert_compiles("foo") - assert_compiles("foo(bar)") - end - - def test_ClassVariableReadNode - assert_compiles("@@foo") - end - - def test_ClassVariableWriteNode - assert_compiles("@@foo = 1") - end - - def test_FalseNode - assert_compiles("false") - end - - def test_GlobalVariableReadNode - assert_compiles("$foo") - end - - def test_GlobalVariableWriteNode - assert_compiles("$foo = 1") - end - - def test_HashNode - assert_compiles("{ foo: bar }") - end - - def test_InstanceVariableReadNode - assert_compiles("@foo") - end - - def test_InstanceVariableWriteNode - assert_compiles("@foo = 1") - end - - def test_IntegerNode - assert_compiles("1") - assert_compiles("1_000") - end - - def test_InterpolatedStringNode - assert_compiles("\"foo \#{bar} baz\"") - end - - def test_LocalVariableWriteNode - assert_compiles("foo = 1") - end - - def test_LocalVariableReadNode - assert_compiles("[foo = 1, foo]") - end - - def test_NilNode - assert_compiles("nil") - end - - def test_OrNode - assert_compiles("true || false") - end - - def test_ParenthesesNode - assert_compiles("()") - end - - def test_ProgramNode - assert_compiles("") - end - - def test_RangeNode - assert_compiles("foo..bar") - assert_compiles("foo...bar") - assert_compiles("(foo..)") - assert_compiles("(foo...)") - assert_compiles("(..bar)") - assert_compiles("(...bar)") - end - - def test_SelfNode - assert_compiles("self") - end - - def test_StringNode - assert_compiles("\"foo\"") - end - - def test_SymbolNode - assert_compiles(":foo") - end - - def test_TrueNode - assert_compiles("true") - end - - def test_UndefNode - assert_compiles("undef :foo, :bar, :baz") - end - - def test_XStringNode - assert_compiles("`foo`") - end - - private - - def assert_compiles(source) - assert_equal_iseqs(rubyvm_compile(source), YARP.compile(source)) - end - - # Instruction sequences have 13 elements in their lists. We don't currently - # support all of the fields, so we can't compare the iseqs directly. Instead, - # we compare the elements that we do support. - def assert_equal_iseqs(expected, actual) - # The first element is the magic comment string. - assert_equal expected[0], actual[0] - - # The next three elements are the major, minor, and patch version numbers. - # TODO: Insert this check once Ruby 3.3 is released, and the TruffleRuby - # GitHub workflow also checks against Ruby 3.3 - # assert_equal expected[1...4], actual[1...4] - - # The next element is a set of options for the iseq. It has lots of - # different information, some of which we support and some of which we - # don't. - assert_equal expected[4][:arg_size], actual[4][:arg_size], "Unexpected difference in arg_size" - assert_equal expected[4][:stack_max], actual[4][:stack_max], "Unexpected difference in stack_max" - - assert_kind_of Integer, actual[4][:local_size] - assert_kind_of Integer, actual[4][:node_id] - - assert_equal expected[4][:code_location].length, actual[4][:code_location].length, "Unexpected difference in code_location length" - assert_equal expected[4][:node_ids].length, actual[4][:node_ids].length, "Unexpected difference in node_ids length" - - # Then we have the name of the iseq, the relative file path, the absolute - # file path, and the line number. We don't have this working quite yet. - assert_kind_of String, actual[5] - assert_kind_of String, actual[6] - assert_kind_of String, actual[7] - assert_kind_of Integer, actual[8] - - # Next we have the type of the iseq. - assert_equal expected[9], actual[9] - - # Next we have the list of local variables. We don't support this yet. - assert_kind_of Array, actual[10] - - # Next we have the argument options. These are used in block and method - # iseqs to reflect how the arguments are passed. - assert_equal expected[11], actual[11], "Unexpected difference in argument options" - - # Next we have the catch table entries. We don't have this working yet. - assert_kind_of Array, actual[12] - - # Finally we have the actual instructions. We support some of this, but omit - # line numbers and some tracepoint events. - expected[13].each do |insn| - case insn - in [:send, opnds, expected_block] unless expected_block.nil? - actual[13].shift => [:send, ^(opnds), actual_block] - assert_equal_iseqs expected_block, actual_block - in Array | :RUBY_EVENT_B_CALL | :RUBY_EVENT_B_RETURN | /^label_\d+/ - assert_equal insn, actual[13].shift - in Integer | /^RUBY_EVENT_/ - # skip these for now - else - flunk "Unexpected instruction: #{insn.inspect}" - end - end - end - - def rubyvm_compile(source) - options = { - peephole_optimization: false, - specialized_instruction: false, - operands_unification: false, - instructions_unification: false, - frozen_string_literal: false - } - - RubyVM::InstructionSequence.compile(source, **options).to_a - end -end diff --git a/test/yarp/encoding_test.rb b/test/yarp/encoding_test.rb index 02ff97f4be..a39fa9b198 100644 --- a/test/yarp/encoding_test.rb +++ b/test/yarp/encoding_test.rb @@ -55,6 +55,21 @@ class EncodingTest < Test::Unit::TestCase assert_equal Encoding.find("utf-8"), actual end + # This test may be a little confusing. Basically when we use our strpbrk, it + # takes into account the encoding of the file. + def test_strpbrk_multibyte + result = YARP.parse(<<~RUBY) + # encoding: Shift_JIS + %w[\x81\x5c] + RUBY + + assert(result.errors.empty?) + assert_equal( + (+"\x81\x5c").force_encoding(Encoding::Shift_JIS), + result.value.statements.body.first.elements.first.unescaped + ) + end + def test_utf_8_variations %w[ utf-8-unix diff --git a/test/yarp/fixtures/not.txt b/test/yarp/fixtures/not.txt index eeb976c410..a623553613 100644 --- a/test/yarp/fixtures/not.txt +++ b/test/yarp/fixtures/not.txt @@ -18,3 +18,16 @@ not foo and bar + +not(foo + + +) + +not( + + +foo + + + ) diff --git a/test/yarp/fixtures/patterns.txt b/test/yarp/fixtures/patterns.txt index c779b85cea..e0c5f303cb 100644 --- a/test/yarp/fixtures/patterns.txt +++ b/test/yarp/fixtures/patterns.txt @@ -76,6 +76,7 @@ foo => Foo(*bar, baz, *qux) foo => Foo[] foo => Foo[1] foo => Foo[1, 2, 3] +foo => Foo[Foo[]] foo => Foo[bar] foo => Foo[*bar, baz] foo => Foo[bar, *baz] diff --git a/test/yarp/language_server_test.rb b/test/yarp/language_server_test.rb deleted file mode 100644 index 4561911c01..0000000000 --- a/test/yarp/language_server_test.rb +++ /dev/null @@ -1,363 +0,0 @@ -# frozen_string_literal: true - -require_relative "yarp_test_helper" -require "yarp/language_server" - -module YARP - class LanguageServerTest < Test::Unit::TestCase - module Request - # Represents a hash pattern. - class Shape - attr_reader :values - - def initialize(values) - @values = values - end - - def ===(other) - values.all? do |key, value| - value == :any ? other.key?(key) : value === other[key] - end - end - end - - # Represents an array pattern. - class Tuple - attr_reader :values - - def initialize(values) - @values = values - end - - def ===(other) - values.each_with_index.all? { |value, index| value === other[index] } - end - end - - def self.[](value) - case value - when Array - Tuple.new(value.map { |child| self[child] }) - when Hash - Shape.new(value.transform_values { |child| self[child] }) - else - value - end - end - end - - class Initialize < Struct.new(:id) - def to_hash - { method: "initialize", id: id } - end - end - - class Shutdown < Struct.new(:id) - def to_hash - { method: "shutdown", id: id } - end - end - - class TextDocumentDidOpen < Struct.new(:uri, :text) - def to_hash - { - method: "textDocument/didOpen", - params: { textDocument: { uri: uri, text: text } } - } - end - end - - class TextDocumentDidChange < Struct.new(:uri, :text) - def to_hash - { - method: "textDocument/didChange", - params: { - textDocument: { uri: uri }, - contentChanges: [{ text: text }] - } - } - end - end - - class TextDocumentDidClose < Struct.new(:uri) - def to_hash - { - method: "textDocument/didClose", - params: { textDocument: { uri: uri } } - } - end - end - - class TextDocumentCodeAction < Struct.new(:id, :uri, :diagnostics) - def to_hash - { - method: "textDocument/codeAction", - id: id, - params: { - textDocument: { uri: uri }, - context: { - diagnostics: diagnostics, - }, - }, - } - end - end - - class TextDocumentDiagnostic < Struct.new(:id, :uri) - def to_hash - { - method: "textDocument/diagnostic", - id: id, - params: { - textDocument: { uri: uri }, - } - } - end - end - - def test_reading_file - Tempfile.create(%w[test- .rb]) do |file| - file.write("class Foo; end") - file.rewind - - responses = run_server([ - Initialize.new(1), - Shutdown.new(3) - ]) - - shape = Request[[ - { id: 1, result: { capabilities: Hash } }, - { id: 3, result: {} } - ]] - - assert_operator(shape, :===, responses) - end - end - - def test_clean_shutdown - responses = run_server([Initialize.new(1), Shutdown.new(2)]) - - shape = Request[[ - { id: 1, result: { capabilities: Hash } }, - { id: 2, result: {} } - ]] - - assert_operator(shape, :===, responses) - end - - def test_file_that_does_not_exist - responses = run_server([ - Initialize.new(1), - Shutdown.new(3) - ]) - - shape = Request[[ - { id: 1, result: { capabilities: Hash } }, - { id: 3, result: {} } - ]] - - assert_operator(shape, :===, responses) - end - - def test_code_action_request - message = "this is an error" - diagnostic = { - range: { start: { line: 0, character: 0 }, end: { line: 0, character: 0 } }, - message: message, - severity: 1, - } - responses = run_server([ - Initialize.new(1), - TextDocumentDidOpen.new("file:///path/to/file.rb", <<~RUBY), - 1 + ( - RUBY - TextDocumentCodeAction.new(2, "file:///path/to/file.rb", [diagnostic]), - Shutdown.new(3) - ]) - - shape = Request[[ - { id: 1, result: { capabilities: Hash } }, - { id: 2, result: [ - { - title: "Report incorrect error: `#{message}`", - kind: "quickfix", - diagnostics: [diagnostic], - command: { - title: "Report incorrect error", - command: "vscode.open", - arguments: [String] - } - } - ], - }, - { id: 3, result: {} } - ]] - - assert_operator(shape, :===, responses) - assert(responses.dig(1, :result, 0, :command, :arguments, 0).include?(URI.encode_www_form_component(message))) - end - - def test_code_action_request_no_diagnostic - responses = run_server([ - Initialize.new(1), - TextDocumentDidOpen.new("file:///path/to/file.rb", <<~RUBY), - 1 + ( - RUBY - TextDocumentCodeAction.new(2, "file:///path/to/file.rb", []), - Shutdown.new(3) - ]) - - shape = Request[[ - { id: 1, result: { capabilities: Hash } }, - { id: 2, result: [] }, - { id: 3, result: {} } - ]] - - assert_operator(shape, :===, responses) - end - - def test_code_action_request_no_content - message = "this is an error" - diagnostic = { - range: { start: { line: 0, character: 0 }, end: { line: 0, character: 0 } }, - message: message, - severity: 1, - } - responses = run_server([ - Initialize.new(1), - TextDocumentCodeAction.new(2, "file:///path/to/file.rb", [diagnostic]), - Shutdown.new(3) - ]) - - shape = Request[[ - { id: 1, result: { capabilities: Hash } }, - { id: 2, result: nil }, - { id: 3, result: {} } - ]] - - assert_operator(shape, :===, responses) - end - - def test_diagnostics_request_error - responses = run_server([ - Initialize.new(1), - TextDocumentDidOpen.new("file:///path/to/file.rb", <<~RUBY), - 1 + ( - RUBY - TextDocumentDiagnostic.new(2, "file:///path/to/file.rb"), - Shutdown.new(3) - ]) - - shape = Request[[ - { id: 1, result: { capabilities: Hash } }, - { id: 2, result: { kind: "full", items: [ - { - range: { - start: { line: Integer, character: Integer }, - end: { line: Integer, character: Integer } - }, - message: String, - severity: Integer - }, - ] } }, - { id: 3, result: {} } - ]] - - assert_operator(shape, :===, responses) - assert(responses.dig(1, :result, :items).count { |item| item[:severity] == 1 } > 0) - end - - def test_diagnostics_request_warning - responses = run_server([ - Initialize.new(1), - TextDocumentDidOpen.new("file:///path/to/file.rb", <<~RUBY), - a/b /c - RUBY - TextDocumentDiagnostic.new(2, "file:///path/to/file.rb"), - Shutdown.new(3) - ]) - - shape = Request[[ - { id: 1, result: { capabilities: Hash } }, - { id: 2, result: { kind: "full", items: [ - { - range: { - start: { line: Integer, character: Integer }, - end: { line: Integer, character: Integer } - }, - message: String, - severity: Integer - }, - ] } }, - { id: 3, result: {} } - ]] - - assert_operator(shape, :===, responses) - assert(responses.dig(1, :result, :items).count { |item| item[:severity] == 2 } > 0) - end - - def test_diagnostics_request_nothing - responses = run_server([ - Initialize.new(1), - TextDocumentDidOpen.new("file:///path/to/file.rb", <<~RUBY), - a = 1 - RUBY - TextDocumentDiagnostic.new(2, "file:///path/to/file.rb"), - Shutdown.new(3) - ]) - - shape = Request[[ - { id: 1, result: { capabilities: Hash } }, - { id: 2, result: { kind: "full", items: [] } }, - { id: 3, result: {} } - ]] - - assert_operator(shape, :===, responses) - assert_equal(0, responses.dig(1, :result, :items).size) - end - - def test_diagnostics_request_no_content - responses = run_server([ - Initialize.new(1), - TextDocumentDiagnostic.new(2, "file:///path/to/file.rb"), - Shutdown.new(3) - ]) - - shape = Request[[ - { id: 1, result: { capabilities: Hash } }, - { id: 2, result: nil }, - { id: 3, result: {} } - ]] - - assert_operator(shape, :===, responses) - end - - private - - def write(content) - request = content.to_hash.merge(jsonrpc: "2.0").to_json - "Content-Length: #{request.bytesize}\r\n\r\n#{request}" - end - - def read(content) - [].tap do |messages| - while (headers = content.gets("\r\n\r\n")) - source = content.read(headers[/Content-Length: (\d+)/i, 1].to_i) - messages << JSON.parse(source, symbolize_names: true) - end - end - end - - def run_server(messages) - input = StringIO.new(messages.map { |message| write(message) }.join) - output = StringIO.new - - LanguageServer.new( - input: input, - output: output, - ).run - - read(output.tap(&:rewind)) - end - end -end diff --git a/test/yarp/parse_test.rb b/test/yarp/parse_test.rb index 08b8ca948e..4d108ddfab 100644 --- a/test/yarp/parse_test.rb +++ b/test/yarp/parse_test.rb @@ -3,10 +3,12 @@ require "yarp_test_helper" class ParseTest < Test::Unit::TestCase - # Because we're reading the snapshots from disk, we need to make sure that - # they're encoded as UTF-8. When certain settings are present this might not - # always be the case (e.g., LANG=C or -Eascii-8bit). So here we force the - # default external encoding for the duration of the test. + # When we pretty-print the trees to compare against the snapshots, we want to + # be certain that we print with the same external encoding. This is because + # methods like Symbol#inspect take into account external encoding and it could + # change how the snapshot is generated. On machines with certain settings + # (like LANG=C or -Eascii-8bit) this could have been changed. So here we're + # going to force it to be UTF-8 to keep the snapshots consistent. def setup @previous_default_external = Encoding.default_external ignore_warnings { Encoding.default_external = Encoding::UTF_8 } @@ -29,20 +31,6 @@ class ParseTest < Test::Unit::TestCase seattlerb/pct_w_heredoc_interp_nested.txt ] - # Because the filepath in SourceFileNodes is different from one maching to the - # next, PP.pp(sexp, +"", 79) can have different results: both the path itself - # and the line breaks based on the length of the path. - def normalize_printed(printed) - printed - .gsub( - /SourceFileNode \s* - \(\s* (\d+\.\.\.\d+) \s*\) \s* - \(\s* ("[^"]*") \s*\) - /mx, - 'SourceFileNode(\1)(\2)') - .gsub(__dir__, "") - end - def find_source_file_node(node) if node.is_a?(YARP::SourceFileNode) node @@ -79,27 +67,26 @@ class ParseTest < Test::Unit::TestCase # that is invalid Ruby. refute_nil Ripper.sexp_raw(source) - # Next, parse the source and print the value. - result = YARP.parse_file(filepath) - value = result.value - printed = normalize_printed(PP.pp(value, +"", 79)) - # Next, assert that there were no errors during parsing. - assert_empty result.errors, value + result = YARP.parse(source, relative) + assert_empty result.errors + + # Next, pretty print the source. + printed = PP.pp(result.value, +"", 79) if File.exist?(snapshot) - normalized = normalize_printed(File.read(snapshot)) + saved = File.read(snapshot) # If the snapshot file exists, but the printed value does not match the # snapshot, then update the snapshot file. - if normalized != printed - File.write(snapshot, normalized) + if printed != saved + File.write(snapshot, printed) warn("Updated snapshot at #{snapshot}.") end # If the snapshot file exists, then assert that the printed value # matches the snapshot. - assert_equal(normalized, printed) + assert_equal(saved, printed) else # If the snapshot file does not yet exist, then write it out now. File.write(snapshot, printed) @@ -108,11 +95,11 @@ 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(value, YARP.load(source, YARP.dump(source, filepath))) + assert_equal_nodes(result.value, YARP.load(source, YARP.dump(source, relative))) # Next, assert that the newlines are in the expected places. expected_newlines = [0] - source.b.scan("\n") { expected_newlines << $~.offset(0)[0] } + source.b.scan("\n") { expected_newlines << $~.offset(0)[0] + 1 } assert_equal expected_newlines, YARP.newlines(source) # Finally, assert that we can lex the source and get the same tokens as diff --git a/test/yarp/regexp_test.rb b/test/yarp/regexp_test.rb index 3bad27019b..4fd3e1d7cb 100644 --- a/test/yarp/regexp_test.rb +++ b/test/yarp/regexp_test.rb @@ -101,6 +101,10 @@ class RegexpTest < Test::Unit::TestCase refute_nil(YARP.named_captures("(?#foo)")) end + def test_comments_with_escaped_parentheses + refute_nil(YARP.named_captures("(?#foo\\)\\))")) + end + def test_non_capturing_groups refute_nil(YARP.named_captures("(?:foo)")) end diff --git a/test/yarp/snapshots/keyword_method_names.txt b/test/yarp/snapshots/keyword_method_names.txt index 47e56957ce..37fc09d0af 100644 --- a/test/yarp/snapshots/keyword_method_names.txt +++ b/test/yarp/snapshots/keyword_method_names.txt @@ -102,7 +102,7 @@ ProgramNode(0...185)( StringNode(123...129)((123...125), (125...128), (128...129), "abc"), DefNode(131...149)( (144...145), - SourceFileNode(135...143)("/fixtures/keyword_method_names.txt"), + SourceFileNode(135...143)("keyword_method_names.txt"), nil, nil, [], diff --git a/test/yarp/snapshots/keywords.txt b/test/yarp/snapshots/keywords.txt index 8bdd4c642d..c949b291aa 100644 --- a/test/yarp/snapshots/keywords.txt +++ b/test/yarp/snapshots/keywords.txt @@ -5,7 +5,7 @@ ProgramNode(0...51)( RetryNode(6...11)(), SelfNode(13...17)(), SourceEncodingNode(19...31)(), - SourceFileNode(33...41)("/fixtures/keywords.txt"), + SourceFileNode(33...41)("keywords.txt"), SourceLineNode(43...51)()] ) ) diff --git a/test/yarp/snapshots/not.txt b/test/yarp/snapshots/not.txt index 80ad5dac2e..a4be66de26 100644 --- a/test/yarp/snapshots/not.txt +++ b/test/yarp/snapshots/not.txt @@ -1,6 +1,6 @@ -ProgramNode(0...125)( +ProgramNode(0...156)( [], - StatementsNode(0...125)( + StatementsNode(0...156)( [AndNode(0...19)( CallNode(0...7)( CallNode(4...7)(nil, nil, (4...7), nil, nil, nil, nil, 0, "foo"), @@ -146,6 +146,48 @@ ProgramNode(0...125)( "!" ), (108...111) + ), + CallNode(127...138)( + CallNode(131...134)( + nil, + nil, + (131...134), + nil, + nil, + nil, + nil, + 0, + "foo" + ), + nil, + (127...130), + (130...131), + nil, + (137...138), + nil, + 0, + "!" + ), + CallNode(140...156)( + CallNode(147...150)( + nil, + nil, + (147...150), + nil, + nil, + nil, + nil, + 0, + "foo" + ), + nil, + (140...143), + (143...144), + nil, + (155...156), + nil, + 0, + "!" )] ) ) diff --git a/test/yarp/snapshots/patterns.txt b/test/yarp/snapshots/patterns.txt index 48cc45edc8..397000235c 100644 --- a/test/yarp/snapshots/patterns.txt +++ b/test/yarp/snapshots/patterns.txt @@ -1,6 +1,6 @@ -ProgramNode(0...3725)( +ProgramNode(0...3743)( [:bar, :baz, :qux, :b, :a], - StatementsNode(0...3725)( + StatementsNode(0...3743)( [MatchRequiredNode(0...10)( CallNode(0...3)(nil, nil, (0...3), nil, nil, nil, nil, 0, "foo"), LocalVariableWriteNode(7...10)(:bar, 0, nil, (7...10), nil), @@ -279,7 +279,7 @@ ProgramNode(0...3725)( 0, "foo" ), - SourceFileNode(291...299)("/fixtures/patterns.txt"), + SourceFileNode(291...299)("patterns.txt"), (288...290) ), MatchRequiredNode(300...315)( @@ -817,8 +817,8 @@ ProgramNode(0...3725)( "foo" ), RangeNode(824...844)( - SourceFileNode(824...832)("/fixtures/patterns.txt"), - SourceFileNode(836...844)("/fixtures/patterns.txt"), + SourceFileNode(824...832)("patterns.txt"), + SourceFileNode(836...844)("patterns.txt"), (833...835), 0 ), @@ -1420,7 +1420,7 @@ ProgramNode(0...3725)( ), (1282...1284) ), - MatchRequiredNode(1298...1313)( + MatchRequiredNode(1298...1315)( CallNode(1298...1301)( nil, nil, @@ -1432,27 +1432,56 @@ ProgramNode(0...3725)( 0, "foo" ), - ArrayPatternNode(1305...1313)( + ArrayPatternNode(1305...1315)( ConstantReadNode(1305...1308)(), - [LocalVariableWriteNode(1309...1312)( + [ArrayPatternNode(1309...1314)( + ConstantReadNode(1309...1312)(), + [], + nil, + [], + (1312...1313), + (1313...1314) + )], + nil, + [], + (1308...1309), + (1314...1315) + ), + (1302...1304) + ), + MatchRequiredNode(1316...1331)( + CallNode(1316...1319)( + nil, + nil, + (1316...1319), + nil, + nil, + nil, + nil, + 0, + "foo" + ), + ArrayPatternNode(1323...1331)( + ConstantReadNode(1323...1326)(), + [LocalVariableWriteNode(1327...1330)( :bar, 0, nil, - (1309...1312), + (1327...1330), nil )], nil, [], - (1308...1309), - (1312...1313) + (1326...1327), + (1330...1331) ), - (1302...1304) + (1320...1322) ), - MatchRequiredNode(1314...1335)( - CallNode(1314...1317)( + MatchRequiredNode(1332...1353)( + CallNode(1332...1335)( nil, nil, - (1314...1317), + (1332...1335), nil, nil, nil, @@ -1460,36 +1489,36 @@ ProgramNode(0...3725)( 0, "foo" ), - ArrayPatternNode(1321...1335)( - ConstantReadNode(1321...1324)(), + ArrayPatternNode(1339...1353)( + ConstantReadNode(1339...1342)(), [], - SplatNode(1325...1329)( - (1325...1326), - LocalVariableWriteNode(1326...1329)( + SplatNode(1343...1347)( + (1343...1344), + LocalVariableWriteNode(1344...1347)( :bar, 0, nil, - (1326...1329), + (1344...1347), nil ) ), - [LocalVariableWriteNode(1331...1334)( + [LocalVariableWriteNode(1349...1352)( :baz, 0, nil, - (1331...1334), + (1349...1352), nil )], - (1324...1325), - (1334...1335) + (1342...1343), + (1352...1353) ), - (1318...1320) + (1336...1338) ), - MatchRequiredNode(1336...1357)( - CallNode(1336...1339)( + MatchRequiredNode(1354...1375)( + CallNode(1354...1357)( nil, nil, - (1336...1339), + (1354...1357), nil, nil, nil, @@ -1497,36 +1526,36 @@ ProgramNode(0...3725)( 0, "foo" ), - ArrayPatternNode(1343...1357)( - ConstantReadNode(1343...1346)(), - [LocalVariableWriteNode(1347...1350)( + ArrayPatternNode(1361...1375)( + ConstantReadNode(1361...1364)(), + [LocalVariableWriteNode(1365...1368)( :bar, 0, nil, - (1347...1350), + (1365...1368), nil )], - SplatNode(1352...1356)( - (1352...1353), - LocalVariableWriteNode(1353...1356)( + SplatNode(1370...1374)( + (1370...1371), + LocalVariableWriteNode(1371...1374)( :baz, 0, nil, - (1353...1356), + (1371...1374), nil ) ), [], - (1346...1347), - (1356...1357) + (1364...1365), + (1374...1375) ), - (1340...1342) + (1358...1360) ), - MatchRequiredNode(1358...1385)( - CallNode(1358...1361)( + MatchRequiredNode(1376...1403)( + CallNode(1376...1379)( nil, nil, - (1358...1361), + (1376...1379), nil, nil, nil, @@ -1534,45 +1563,45 @@ ProgramNode(0...3725)( 0, "foo" ), - FindPatternNode(1365...1385)( - ConstantReadNode(1365...1368)(), - SplatNode(1369...1373)( - (1369...1370), - LocalVariableWriteNode(1370...1373)( + FindPatternNode(1383...1403)( + ConstantReadNode(1383...1386)(), + SplatNode(1387...1391)( + (1387...1388), + LocalVariableWriteNode(1388...1391)( :bar, 0, nil, - (1370...1373), + (1388...1391), nil ) ), - [LocalVariableWriteNode(1375...1378)( + [LocalVariableWriteNode(1393...1396)( :baz, 0, nil, - (1375...1378), + (1393...1396), nil )], - SplatNode(1380...1384)( - (1380...1381), - LocalVariableWriteNode(1381...1384)( + SplatNode(1398...1402)( + (1398...1399), + LocalVariableWriteNode(1399...1402)( :qux, 0, nil, - (1381...1384), + (1399...1402), nil ) ), - (1368...1369), - (1384...1385) + (1386...1387), + (1402...1403) ), - (1362...1364) + (1380...1382) ), - MatchRequiredNode(1387...1398)( - CallNode(1387...1390)( + MatchRequiredNode(1405...1416)( + CallNode(1405...1408)( nil, nil, - (1387...1390), + (1405...1408), nil, nil, nil, @@ -1580,16 +1609,16 @@ ProgramNode(0...3725)( 0, "foo" ), - ArrayPatternNode(1394...1398)( + ArrayPatternNode(1412...1416)( nil, [], - SplatNode(1394...1398)( - (1394...1395), - LocalVariableWriteNode(1395...1398)( + SplatNode(1412...1416)( + (1412...1413), + LocalVariableWriteNode(1413...1416)( :bar, 0, nil, - (1395...1398), + (1413...1416), nil ) ), @@ -1597,13 +1626,13 @@ ProgramNode(0...3725)( nil, nil ), - (1391...1393) + (1409...1411) ), - MatchRequiredNode(1399...1420)( - CallNode(1399...1402)( + MatchRequiredNode(1417...1438)( + CallNode(1417...1420)( nil, nil, - (1399...1402), + (1417...1420), nil, nil, nil, @@ -1611,43 +1640,43 @@ ProgramNode(0...3725)( 0, "foo" ), - ArrayPatternNode(1406...1420)( + ArrayPatternNode(1424...1438)( nil, [], - SplatNode(1406...1410)( - (1406...1407), - LocalVariableWriteNode(1407...1410)( + SplatNode(1424...1428)( + (1424...1425), + LocalVariableWriteNode(1425...1428)( :bar, 0, nil, - (1407...1410), + (1425...1428), nil ) ), - [LocalVariableWriteNode(1412...1415)( + [LocalVariableWriteNode(1430...1433)( :baz, 0, nil, - (1412...1415), + (1430...1433), nil ), - LocalVariableWriteNode(1417...1420)( + LocalVariableWriteNode(1435...1438)( :qux, 0, nil, - (1417...1420), + (1435...1438), nil )], nil, nil ), - (1403...1405) + (1421...1423) ), - MatchRequiredNode(1421...1442)( - CallNode(1421...1424)( + MatchRequiredNode(1439...1460)( + CallNode(1439...1442)( nil, nil, - (1421...1424), + (1439...1442), nil, nil, nil, @@ -1655,42 +1684,42 @@ ProgramNode(0...3725)( 0, "foo" ), - ArrayPatternNode(1428...1442)( + ArrayPatternNode(1446...1460)( nil, - [LocalVariableWriteNode(1428...1431)( + [LocalVariableWriteNode(1446...1449)( :bar, 0, nil, - (1428...1431), + (1446...1449), nil )], - SplatNode(1433...1437)( - (1433...1434), - LocalVariableWriteNode(1434...1437)( + SplatNode(1451...1455)( + (1451...1452), + LocalVariableWriteNode(1452...1455)( :baz, 0, nil, - (1434...1437), + (1452...1455), nil ) ), - [LocalVariableWriteNode(1439...1442)( + [LocalVariableWriteNode(1457...1460)( :qux, 0, nil, - (1439...1442), + (1457...1460), nil )], nil, nil ), - (1425...1427) + (1443...1445) ), - MatchRequiredNode(1443...1464)( - CallNode(1443...1446)( + MatchRequiredNode(1461...1482)( + CallNode(1461...1464)( nil, nil, - (1443...1446), + (1461...1464), nil, nil, nil, @@ -1698,29 +1727,29 @@ ProgramNode(0...3725)( 0, "foo" ), - ArrayPatternNode(1450...1464)( + ArrayPatternNode(1468...1482)( nil, - [LocalVariableWriteNode(1450...1453)( + [LocalVariableWriteNode(1468...1471)( :bar, 0, nil, - (1450...1453), + (1468...1471), nil ), - LocalVariableWriteNode(1455...1458)( + LocalVariableWriteNode(1473...1476)( :baz, 0, nil, - (1455...1458), + (1473...1476), nil )], - SplatNode(1460...1464)( - (1460...1461), - LocalVariableWriteNode(1461...1464)( + SplatNode(1478...1482)( + (1478...1479), + LocalVariableWriteNode(1479...1482)( :qux, 0, nil, - (1461...1464), + (1479...1482), nil ) ), @@ -1728,13 +1757,13 @@ ProgramNode(0...3725)( nil, nil ), - (1447...1449) + (1465...1467) ), - MatchRequiredNode(1465...1487)( - CallNode(1465...1468)( + MatchRequiredNode(1483...1505)( + CallNode(1483...1486)( nil, nil, - (1465...1468), + (1483...1486), nil, nil, nil, @@ -1742,45 +1771,45 @@ ProgramNode(0...3725)( 0, "foo" ), - FindPatternNode(1472...1487)( + FindPatternNode(1490...1505)( nil, - SplatNode(1472...1476)( - (1472...1473), - LocalVariableWriteNode(1473...1476)( + SplatNode(1490...1494)( + (1490...1491), + LocalVariableWriteNode(1491...1494)( :bar, 0, nil, - (1473...1476), + (1491...1494), nil ) ), - [LocalVariableWriteNode(1478...1481)( + [LocalVariableWriteNode(1496...1499)( :baz, 0, nil, - (1478...1481), + (1496...1499), nil )], - SplatNode(1483...1487)( - (1483...1484), - LocalVariableWriteNode(1484...1487)( + SplatNode(1501...1505)( + (1501...1502), + LocalVariableWriteNode(1502...1505)( :qux, 0, nil, - (1484...1487), + (1502...1505), nil ) ), nil, nil ), - (1469...1471) + (1487...1489) ), - MatchRequiredNode(1489...1498)( - CallNode(1489...1492)( + MatchRequiredNode(1507...1516)( + CallNode(1507...1510)( nil, nil, - (1489...1492), + (1507...1510), nil, nil, nil, @@ -1788,21 +1817,21 @@ ProgramNode(0...3725)( 0, "foo" ), - ArrayPatternNode(1496...1498)( + ArrayPatternNode(1514...1516)( nil, [], nil, [], - (1496...1497), - (1497...1498) + (1514...1515), + (1515...1516) ), - (1493...1495) + (1511...1513) ), - MatchRequiredNode(1499...1516)( - CallNode(1499...1502)( + MatchRequiredNode(1517...1534)( + CallNode(1517...1520)( nil, nil, - (1499...1502), + (1517...1520), nil, nil, nil, @@ -1810,49 +1839,49 @@ ProgramNode(0...3725)( 0, "foo" ), - ArrayPatternNode(1506...1516)( + ArrayPatternNode(1524...1534)( nil, - [ArrayPatternNode(1507...1515)( + [ArrayPatternNode(1525...1533)( nil, - [ArrayPatternNode(1508...1514)( + [ArrayPatternNode(1526...1532)( nil, - [ArrayPatternNode(1509...1513)( + [ArrayPatternNode(1527...1531)( nil, - [ArrayPatternNode(1510...1512)( + [ArrayPatternNode(1528...1530)( nil, [], nil, [], - (1510...1511), - (1511...1512) + (1528...1529), + (1529...1530) )], nil, [], - (1509...1510), - (1512...1513) + (1527...1528), + (1530...1531) )], nil, [], - (1508...1509), - (1513...1514) + (1526...1527), + (1531...1532) )], nil, [], - (1507...1508), - (1514...1515) + (1525...1526), + (1532...1533) )], nil, [], - (1506...1507), - (1515...1516) + (1524...1525), + (1533...1534) ), - (1503...1505) + (1521...1523) ), - MatchRequiredNode(1518...1531)( - CallNode(1518...1521)( + MatchRequiredNode(1536...1549)( + CallNode(1536...1539)( nil, nil, - (1518...1521), + (1536...1539), nil, nil, nil, @@ -1860,30 +1889,30 @@ ProgramNode(0...3725)( 0, "foo" ), - ArrayPatternNode(1525...1531)( + ArrayPatternNode(1543...1549)( nil, [], - SplatNode(1526...1530)( - (1526...1527), - LocalVariableWriteNode(1527...1530)( + SplatNode(1544...1548)( + (1544...1545), + LocalVariableWriteNode(1545...1548)( :bar, 0, nil, - (1527...1530), + (1545...1548), nil ) ), [], - (1525...1526), - (1530...1531) + (1543...1544), + (1548...1549) ), - (1522...1524) + (1540...1542) ), - MatchRequiredNode(1532...1555)( - CallNode(1532...1535)( + MatchRequiredNode(1550...1573)( + CallNode(1550...1553)( nil, nil, - (1532...1535), + (1550...1553), nil, nil, nil, @@ -1891,43 +1920,43 @@ ProgramNode(0...3725)( 0, "foo" ), - ArrayPatternNode(1539...1555)( + ArrayPatternNode(1557...1573)( nil, [], - SplatNode(1540...1544)( - (1540...1541), - LocalVariableWriteNode(1541...1544)( + SplatNode(1558...1562)( + (1558...1559), + LocalVariableWriteNode(1559...1562)( :bar, 0, nil, - (1541...1544), + (1559...1562), nil ) ), - [LocalVariableWriteNode(1546...1549)( + [LocalVariableWriteNode(1564...1567)( :baz, 0, nil, - (1546...1549), + (1564...1567), nil ), - LocalVariableWriteNode(1551...1554)( + LocalVariableWriteNode(1569...1572)( :qux, 0, nil, - (1551...1554), + (1569...1572), nil )], - (1539...1540), - (1554...1555) + (1557...1558), + (1572...1573) ), - (1536...1538) + (1554...1556) ), - MatchRequiredNode(1556...1579)( - CallNode(1556...1559)( + MatchRequiredNode(1574...1597)( + CallNode(1574...1577)( nil, nil, - (1556...1559), + (1574...1577), nil, nil, nil, @@ -1935,42 +1964,42 @@ ProgramNode(0...3725)( 0, "foo" ), - ArrayPatternNode(1563...1579)( + ArrayPatternNode(1581...1597)( nil, - [LocalVariableWriteNode(1564...1567)( + [LocalVariableWriteNode(1582...1585)( :bar, 0, nil, - (1564...1567), + (1582...1585), nil )], - SplatNode(1569...1573)( - (1569...1570), - LocalVariableWriteNode(1570...1573)( + SplatNode(1587...1591)( + (1587...1588), + LocalVariableWriteNode(1588...1591)( :baz, 0, nil, - (1570...1573), + (1588...1591), nil ) ), - [LocalVariableWriteNode(1575...1578)( + [LocalVariableWriteNode(1593...1596)( :qux, 0, nil, - (1575...1578), + (1593...1596), nil )], - (1563...1564), - (1578...1579) + (1581...1582), + (1596...1597) ), - (1560...1562) + (1578...1580) ), - MatchRequiredNode(1580...1603)( - CallNode(1580...1583)( + MatchRequiredNode(1598...1621)( + CallNode(1598...1601)( nil, nil, - (1580...1583), + (1598...1601), nil, nil, nil, @@ -1978,43 +2007,43 @@ ProgramNode(0...3725)( 0, "foo" ), - ArrayPatternNode(1587...1603)( + ArrayPatternNode(1605...1621)( nil, - [LocalVariableWriteNode(1588...1591)( + [LocalVariableWriteNode(1606...1609)( :bar, 0, nil, - (1588...1591), + (1606...1609), nil ), - LocalVariableWriteNode(1593...1596)( + LocalVariableWriteNode(1611...1614)( :baz, 0, nil, - (1593...1596), + (1611...1614), nil )], - SplatNode(1598...1602)( - (1598...1599), - LocalVariableWriteNode(1599...1602)( + SplatNode(1616...1620)( + (1616...1617), + LocalVariableWriteNode(1617...1620)( :qux, 0, nil, - (1599...1602), + (1617...1620), nil ) ), [], - (1587...1588), - (1602...1603) + (1605...1606), + (1620...1621) ), - (1584...1586) + (1602...1604) ), - MatchRequiredNode(1604...1628)( - CallNode(1604...1607)( + MatchRequiredNode(1622...1646)( + CallNode(1622...1625)( nil, nil, - (1604...1607), + (1622...1625), nil, nil, nil, @@ -2022,45 +2051,45 @@ ProgramNode(0...3725)( 0, "foo" ), - FindPatternNode(1611...1628)( + FindPatternNode(1629...1646)( nil, - SplatNode(1612...1616)( - (1612...1613), - LocalVariableWriteNode(1613...1616)( + SplatNode(1630...1634)( + (1630...1631), + LocalVariableWriteNode(1631...1634)( :bar, 0, nil, - (1613...1616), + (1631...1634), nil ) ), - [LocalVariableWriteNode(1618...1621)( + [LocalVariableWriteNode(1636...1639)( :baz, 0, nil, - (1618...1621), + (1636...1639), nil )], - SplatNode(1623...1627)( - (1623...1624), - LocalVariableWriteNode(1624...1627)( + SplatNode(1641...1645)( + (1641...1642), + LocalVariableWriteNode(1642...1645)( :qux, 0, nil, - (1624...1627), + (1642...1645), nil ) ), - (1611...1612), - (1627...1628) + (1629...1630), + (1645...1646) ), - (1608...1610) + (1626...1628) ), - MatchPredicateNode(1630...1640)( - CallNode(1630...1633)( + MatchPredicateNode(1648...1658)( + CallNode(1648...1651)( nil, nil, - (1630...1633), + (1648...1651), nil, nil, nil, @@ -2068,14 +2097,14 @@ ProgramNode(0...3725)( 0, "foo" ), - LocalVariableWriteNode(1637...1640)(:bar, 0, nil, (1637...1640), nil), - (1634...1636) + LocalVariableWriteNode(1655...1658)(:bar, 0, nil, (1655...1658), nil), + (1652...1654) ), - MatchPredicateNode(1641...1649)( - CallNode(1641...1644)( + MatchPredicateNode(1659...1667)( + CallNode(1659...1662)( nil, nil, - (1641...1644), + (1659...1662), nil, nil, nil, @@ -2083,14 +2112,14 @@ ProgramNode(0...3725)( 0, "foo" ), - IntegerNode(1648...1649)(), - (1645...1647) + IntegerNode(1666...1667)(), + (1663...1665) ), - MatchPredicateNode(1650...1660)( - CallNode(1650...1653)( + MatchPredicateNode(1668...1678)( + CallNode(1668...1671)( nil, nil, - (1650...1653), + (1668...1671), nil, nil, nil, @@ -2098,14 +2127,14 @@ ProgramNode(0...3725)( 0, "foo" ), - FloatNode(1657...1660)(), - (1654...1656) + FloatNode(1675...1678)(), + (1672...1674) ), - MatchPredicateNode(1661...1670)( - CallNode(1661...1664)( + MatchPredicateNode(1679...1688)( + CallNode(1679...1682)( nil, nil, - (1661...1664), + (1679...1682), nil, nil, nil, @@ -2113,14 +2142,14 @@ ProgramNode(0...3725)( 0, "foo" ), - ImaginaryNode(1668...1670)(IntegerNode(1668...1669)()), - (1665...1667) + ImaginaryNode(1686...1688)(IntegerNode(1686...1687)()), + (1683...1685) ), - MatchPredicateNode(1671...1680)( - CallNode(1671...1674)( + MatchPredicateNode(1689...1698)( + CallNode(1689...1692)( nil, nil, - (1671...1674), + (1689...1692), nil, nil, nil, @@ -2128,14 +2157,14 @@ ProgramNode(0...3725)( 0, "foo" ), - RationalNode(1678...1680)(IntegerNode(1678...1679)()), - (1675...1677) + RationalNode(1696...1698)(IntegerNode(1696...1697)()), + (1693...1695) ), - MatchPredicateNode(1681...1692)( - CallNode(1681...1684)( + MatchPredicateNode(1699...1710)( + CallNode(1699...1702)( nil, nil, - (1681...1684), + (1699...1702), nil, nil, nil, @@ -2143,14 +2172,14 @@ ProgramNode(0...3725)( 0, "foo" ), - SymbolNode(1688...1692)((1688...1689), (1689...1692), nil, "foo"), - (1685...1687) + SymbolNode(1706...1710)((1706...1707), (1707...1710), nil, "foo"), + (1703...1705) ), - MatchPredicateNode(1693...1707)( - CallNode(1693...1696)( + MatchPredicateNode(1711...1725)( + CallNode(1711...1714)( nil, nil, - (1693...1696), + (1711...1714), nil, nil, nil, @@ -2158,19 +2187,19 @@ ProgramNode(0...3725)( 0, "foo" ), - SymbolNode(1700...1707)( - (1700...1703), - (1703...1706), - (1706...1707), + SymbolNode(1718...1725)( + (1718...1721), + (1721...1724), + (1724...1725), "foo" ), - (1697...1699) + (1715...1717) ), - MatchPredicateNode(1708...1721)( - CallNode(1708...1711)( + MatchPredicateNode(1726...1739)( + CallNode(1726...1729)( nil, nil, - (1708...1711), + (1726...1729), nil, nil, nil, @@ -2178,18 +2207,18 @@ ProgramNode(0...3725)( 0, "foo" ), - InterpolatedSymbolNode(1715...1721)( - (1715...1717), - [StringNode(1717...1720)(nil, (1717...1720), nil, "foo")], - (1720...1721) + InterpolatedSymbolNode(1733...1739)( + (1733...1735), + [StringNode(1735...1738)(nil, (1735...1738), nil, "foo")], + (1738...1739) ), - (1712...1714) + (1730...1732) ), - MatchPredicateNode(1722...1734)( - CallNode(1722...1725)( + MatchPredicateNode(1740...1752)( + CallNode(1740...1743)( nil, nil, - (1722...1725), + (1740...1743), nil, nil, nil, @@ -2197,20 +2226,20 @@ ProgramNode(0...3725)( 0, "foo" ), - RegularExpressionNode(1729...1734)( - (1729...1730), - (1730...1733), - (1733...1734), + RegularExpressionNode(1747...1752)( + (1747...1748), + (1748...1751), + (1751...1752), "foo", 0 ), - (1726...1728) + (1744...1746) ), - MatchPredicateNode(1735...1747)( - CallNode(1735...1738)( + MatchPredicateNode(1753...1765)( + CallNode(1753...1756)( nil, nil, - (1735...1738), + (1753...1756), nil, nil, nil, @@ -2218,19 +2247,19 @@ ProgramNode(0...3725)( 0, "foo" ), - XStringNode(1742...1747)( - (1742...1743), - (1743...1746), - (1746...1747), + XStringNode(1760...1765)( + (1760...1761), + (1761...1764), + (1764...1765), "foo" ), - (1739...1741) + (1757...1759) ), - MatchPredicateNode(1748...1762)( - CallNode(1748...1751)( + MatchPredicateNode(1766...1780)( + CallNode(1766...1769)( nil, nil, - (1748...1751), + (1766...1769), nil, nil, nil, @@ -2238,19 +2267,19 @@ ProgramNode(0...3725)( 0, "foo" ), - XStringNode(1755...1762)( - (1755...1758), - (1758...1761), - (1761...1762), + XStringNode(1773...1780)( + (1773...1776), + (1776...1779), + (1779...1780), "foo" ), - (1752...1754) + (1770...1772) ), - MatchPredicateNode(1763...1777)( - CallNode(1763...1766)( + MatchPredicateNode(1781...1795)( + CallNode(1781...1784)( nil, nil, - (1763...1766), + (1781...1784), nil, nil, nil, @@ -2258,18 +2287,18 @@ ProgramNode(0...3725)( 0, "foo" ), - ArrayNode(1770...1777)( - [SymbolNode(1773...1776)(nil, (1773...1776), nil, "foo")], - (1770...1773), - (1776...1777) + ArrayNode(1788...1795)( + [SymbolNode(1791...1794)(nil, (1791...1794), nil, "foo")], + (1788...1791), + (1794...1795) ), - (1767...1769) + (1785...1787) ), - MatchPredicateNode(1778...1792)( - CallNode(1778...1781)( + MatchPredicateNode(1796...1810)( + CallNode(1796...1799)( nil, nil, - (1778...1781), + (1796...1799), nil, nil, nil, @@ -2277,18 +2306,18 @@ ProgramNode(0...3725)( 0, "foo" ), - ArrayNode(1785...1792)( - [SymbolNode(1788...1791)(nil, (1788...1791), nil, "foo")], - (1785...1788), - (1791...1792) + ArrayNode(1803...1810)( + [SymbolNode(1806...1809)(nil, (1806...1809), nil, "foo")], + (1803...1806), + (1809...1810) ), - (1782...1784) + (1800...1802) ), - MatchPredicateNode(1793...1807)( - CallNode(1793...1796)( + MatchPredicateNode(1811...1825)( + CallNode(1811...1814)( nil, nil, - (1793...1796), + (1811...1814), nil, nil, nil, @@ -2296,18 +2325,18 @@ ProgramNode(0...3725)( 0, "foo" ), - ArrayNode(1800...1807)( - [StringNode(1803...1806)(nil, (1803...1806), nil, "foo")], - (1800...1803), - (1806...1807) + ArrayNode(1818...1825)( + [StringNode(1821...1824)(nil, (1821...1824), nil, "foo")], + (1818...1821), + (1824...1825) ), - (1797...1799) + (1815...1817) ), - MatchPredicateNode(1808...1822)( - CallNode(1808...1811)( + MatchPredicateNode(1826...1840)( + CallNode(1826...1829)( nil, nil, - (1808...1811), + (1826...1829), nil, nil, nil, @@ -2315,18 +2344,18 @@ ProgramNode(0...3725)( 0, "foo" ), - ArrayNode(1815...1822)( - [StringNode(1818...1821)(nil, (1818...1821), nil, "foo")], - (1815...1818), - (1821...1822) + ArrayNode(1833...1840)( + [StringNode(1836...1839)(nil, (1836...1839), nil, "foo")], + (1833...1836), + (1839...1840) ), - (1812...1814) + (1830...1832) ), - MatchPredicateNode(1823...1837)( - CallNode(1823...1826)( + MatchPredicateNode(1841...1855)( + CallNode(1841...1844)( nil, nil, - (1823...1826), + (1841...1844), nil, nil, nil, @@ -2334,19 +2363,19 @@ ProgramNode(0...3725)( 0, "foo" ), - StringNode(1830...1837)( - (1830...1833), - (1833...1836), - (1836...1837), + StringNode(1848...1855)( + (1848...1851), + (1851...1854), + (1854...1855), "foo" ), - (1827...1829) + (1845...1847) ), - MatchPredicateNode(1838...1852)( - CallNode(1838...1841)( + MatchPredicateNode(1856...1870)( + CallNode(1856...1859)( nil, nil, - (1838...1841), + (1856...1859), nil, nil, nil, @@ -2354,19 +2383,19 @@ ProgramNode(0...3725)( 0, "foo" ), - StringNode(1845...1852)( - (1845...1848), - (1848...1851), - (1851...1852), + StringNode(1863...1870)( + (1863...1866), + (1866...1869), + (1869...1870), "foo" ), - (1842...1844) + (1860...1862) ), - MatchPredicateNode(1853...1865)( - CallNode(1853...1856)( + MatchPredicateNode(1871...1883)( + CallNode(1871...1874)( nil, nil, - (1853...1856), + (1871...1874), nil, nil, nil, @@ -2374,19 +2403,19 @@ ProgramNode(0...3725)( 0, "foo" ), - StringNode(1860...1865)( - (1860...1861), - (1861...1864), - (1864...1865), + StringNode(1878...1883)( + (1878...1879), + (1879...1882), + (1882...1883), "foo" ), - (1857...1859) + (1875...1877) ), - MatchPredicateNode(1866...1876)( - CallNode(1866...1869)( + MatchPredicateNode(1884...1894)( + CallNode(1884...1887)( nil, nil, - (1866...1869), + (1884...1887), nil, nil, nil, @@ -2394,14 +2423,14 @@ ProgramNode(0...3725)( 0, "foo" ), - NilNode(1873...1876)(), - (1870...1872) + NilNode(1891...1894)(), + (1888...1890) ), - MatchPredicateNode(1877...1888)( - CallNode(1877...1880)( + MatchPredicateNode(1895...1906)( + CallNode(1895...1898)( nil, nil, - (1877...1880), + (1895...1898), nil, nil, nil, @@ -2409,14 +2438,14 @@ ProgramNode(0...3725)( 0, "foo" ), - SelfNode(1884...1888)(), - (1881...1883) + SelfNode(1902...1906)(), + (1899...1901) ), - MatchPredicateNode(1889...1900)( - CallNode(1889...1892)( + MatchPredicateNode(1907...1918)( + CallNode(1907...1910)( nil, nil, - (1889...1892), + (1907...1910), nil, nil, nil, @@ -2424,14 +2453,14 @@ ProgramNode(0...3725)( 0, "foo" ), - TrueNode(1896...1900)(), - (1893...1895) + TrueNode(1914...1918)(), + (1911...1913) ), - MatchPredicateNode(1901...1913)( - CallNode(1901...1904)( + MatchPredicateNode(1919...1931)( + CallNode(1919...1922)( nil, nil, - (1901...1904), + (1919...1922), nil, nil, nil, @@ -2439,14 +2468,14 @@ ProgramNode(0...3725)( 0, "foo" ), - FalseNode(1908...1913)(), - (1905...1907) + FalseNode(1926...1931)(), + (1923...1925) ), - MatchPredicateNode(1914...1929)( - CallNode(1914...1917)( + MatchPredicateNode(1932...1947)( + CallNode(1932...1935)( nil, nil, - (1914...1917), + (1932...1935), nil, nil, nil, @@ -2454,14 +2483,14 @@ ProgramNode(0...3725)( 0, "foo" ), - SourceFileNode(1921...1929)("/fixtures/patterns.txt"), - (1918...1920) + SourceFileNode(1939...1947)("patterns.txt"), + (1936...1938) ), - MatchPredicateNode(1930...1945)( - CallNode(1930...1933)( + MatchPredicateNode(1948...1963)( + CallNode(1948...1951)( nil, nil, - (1930...1933), + (1948...1951), nil, nil, nil, @@ -2469,14 +2498,14 @@ ProgramNode(0...3725)( 0, "foo" ), - SourceLineNode(1937...1945)(), - (1934...1936) + SourceLineNode(1955...1963)(), + (1952...1954) ), - MatchPredicateNode(1946...1965)( - CallNode(1946...1949)( + MatchPredicateNode(1964...1983)( + CallNode(1964...1967)( nil, nil, - (1946...1949), + (1964...1967), nil, nil, nil, @@ -2484,14 +2513,14 @@ ProgramNode(0...3725)( 0, "foo" ), - SourceEncodingNode(1953...1965)(), - (1950...1952) + SourceEncodingNode(1971...1983)(), + (1968...1970) ), - MatchPredicateNode(1966...1983)( - CallNode(1966...1969)( + MatchPredicateNode(1984...2001)( + CallNode(1984...1987)( nil, nil, - (1966...1969), + (1984...1987), nil, nil, nil, @@ -2499,21 +2528,21 @@ ProgramNode(0...3725)( 0, "foo" ), - LambdaNode(1973...1983)( + LambdaNode(1991...2001)( [], - (1973...1975), + (1991...1993), nil, - StatementsNode(1978...1981)( - [LocalVariableReadNode(1978...1981)(:bar, 1)] + StatementsNode(1996...1999)( + [LocalVariableReadNode(1996...1999)(:bar, 1)] ) ), - (1970...1972) + (1988...1990) ), - CaseNode(1985...2010)( - CallNode(1990...1993)( + CaseNode(2003...2028)( + CallNode(2008...2011)( nil, nil, - (1990...1993), + (2008...2011), nil, nil, nil, @@ -2521,27 +2550,27 @@ ProgramNode(0...3725)( 0, "foo" ), - [InNode(1995...2006)( - LocalVariableWriteNode(1998...2001)( + [InNode(2013...2024)( + LocalVariableWriteNode(2016...2019)( :bar, 0, nil, - (1998...2001), + (2016...2019), nil ), nil, - (1995...1997), - (2002...2006) + (2013...2015), + (2020...2024) )], nil, - (1985...1989), - (2007...2010) + (2003...2007), + (2025...2028) ), - CaseNode(2011...2034)( - CallNode(2016...2019)( + CaseNode(2029...2052)( + CallNode(2034...2037)( nil, nil, - (2016...2019), + (2034...2037), nil, nil, nil, @@ -2549,21 +2578,21 @@ ProgramNode(0...3725)( 0, "foo" ), - [InNode(2021...2030)( - IntegerNode(2024...2025)(), + [InNode(2039...2048)( + IntegerNode(2042...2043)(), nil, - (2021...2023), - (2026...2030) + (2039...2041), + (2044...2048) )], nil, - (2011...2015), - (2031...2034) + (2029...2033), + (2049...2052) ), - CaseNode(2035...2060)( - CallNode(2040...2043)( + CaseNode(2053...2078)( + CallNode(2058...2061)( nil, nil, - (2040...2043), + (2058...2061), nil, nil, nil, @@ -2571,21 +2600,21 @@ ProgramNode(0...3725)( 0, "foo" ), - [InNode(2045...2056)( - FloatNode(2048...2051)(), + [InNode(2063...2074)( + FloatNode(2066...2069)(), nil, - (2045...2047), - (2052...2056) + (2063...2065), + (2070...2074) )], nil, - (2035...2039), - (2057...2060) + (2053...2057), + (2075...2078) ), - CaseNode(2061...2085)( - CallNode(2066...2069)( + CaseNode(2079...2103)( + CallNode(2084...2087)( nil, nil, - (2066...2069), + (2084...2087), nil, nil, nil, @@ -2593,21 +2622,21 @@ ProgramNode(0...3725)( 0, "foo" ), - [InNode(2071...2081)( - ImaginaryNode(2074...2076)(IntegerNode(2074...2075)()), + [InNode(2089...2099)( + ImaginaryNode(2092...2094)(IntegerNode(2092...2093)()), nil, - (2071...2073), - (2077...2081) + (2089...2091), + (2095...2099) )], nil, - (2061...2065), - (2082...2085) + (2079...2083), + (2100...2103) ), - CaseNode(2086...2110)( - CallNode(2091...2094)( + CaseNode(2104...2128)( + CallNode(2109...2112)( nil, nil, - (2091...2094), + (2109...2112), nil, nil, nil, @@ -2615,21 +2644,21 @@ ProgramNode(0...3725)( 0, "foo" ), - [InNode(2096...2106)( - RationalNode(2099...2101)(IntegerNode(2099...2100)()), + [InNode(2114...2124)( + RationalNode(2117...2119)(IntegerNode(2117...2118)()), nil, - (2096...2098), - (2102...2106) + (2114...2116), + (2120...2124) )], nil, - (2086...2090), - (2107...2110) + (2104...2108), + (2125...2128) ), - CaseNode(2111...2137)( - CallNode(2116...2119)( + CaseNode(2129...2155)( + CallNode(2134...2137)( nil, nil, - (2116...2119), + (2134...2137), nil, nil, nil, @@ -2637,21 +2666,21 @@ ProgramNode(0...3725)( 0, "foo" ), - [InNode(2121...2133)( - SymbolNode(2124...2128)((2124...2125), (2125...2128), nil, "foo"), + [InNode(2139...2151)( + SymbolNode(2142...2146)((2142...2143), (2143...2146), nil, "foo"), nil, - (2121...2123), - (2129...2133) + (2139...2141), + (2147...2151) )], nil, - (2111...2115), - (2134...2137) + (2129...2133), + (2152...2155) ), - CaseNode(2138...2167)( - CallNode(2143...2146)( + CaseNode(2156...2185)( + CallNode(2161...2164)( nil, nil, - (2143...2146), + (2161...2164), nil, nil, nil, @@ -2659,26 +2688,26 @@ ProgramNode(0...3725)( 0, "foo" ), - [InNode(2148...2163)( - SymbolNode(2151...2158)( - (2151...2154), - (2154...2157), - (2157...2158), + [InNode(2166...2181)( + SymbolNode(2169...2176)( + (2169...2172), + (2172...2175), + (2175...2176), "foo" ), nil, - (2148...2150), - (2159...2163) + (2166...2168), + (2177...2181) )], nil, - (2138...2142), - (2164...2167) + (2156...2160), + (2182...2185) ), - CaseNode(2168...2196)( - CallNode(2173...2176)( + CaseNode(2186...2214)( + CallNode(2191...2194)( nil, nil, - (2173...2176), + (2191...2194), nil, nil, nil, @@ -2686,25 +2715,25 @@ ProgramNode(0...3725)( 0, "foo" ), - [InNode(2178...2192)( - InterpolatedSymbolNode(2181...2187)( - (2181...2183), - [StringNode(2183...2186)(nil, (2183...2186), nil, "foo")], - (2186...2187) + [InNode(2196...2210)( + InterpolatedSymbolNode(2199...2205)( + (2199...2201), + [StringNode(2201...2204)(nil, (2201...2204), nil, "foo")], + (2204...2205) ), nil, - (2178...2180), - (2188...2192) + (2196...2198), + (2206...2210) )], nil, - (2168...2172), - (2193...2196) + (2186...2190), + (2211...2214) ), - CaseNode(2197...2224)( - CallNode(2202...2205)( + CaseNode(2215...2242)( + CallNode(2220...2223)( nil, nil, - (2202...2205), + (2220...2223), nil, nil, nil, @@ -2712,27 +2741,27 @@ ProgramNode(0...3725)( 0, "foo" ), - [InNode(2207...2220)( - RegularExpressionNode(2210...2215)( - (2210...2211), - (2211...2214), - (2214...2215), + [InNode(2225...2238)( + RegularExpressionNode(2228...2233)( + (2228...2229), + (2229...2232), + (2232...2233), "foo", 0 ), nil, - (2207...2209), - (2216...2220) + (2225...2227), + (2234...2238) )], nil, - (2197...2201), - (2221...2224) + (2215...2219), + (2239...2242) ), - CaseNode(2225...2252)( - CallNode(2230...2233)( + CaseNode(2243...2270)( + CallNode(2248...2251)( nil, nil, - (2230...2233), + (2248...2251), nil, nil, nil, @@ -2740,26 +2769,26 @@ ProgramNode(0...3725)( 0, "foo" ), - [InNode(2235...2248)( - XStringNode(2238...2243)( - (2238...2239), - (2239...2242), - (2242...2243), + [InNode(2253...2266)( + XStringNode(2256...2261)( + (2256...2257), + (2257...2260), + (2260...2261), "foo" ), nil, - (2235...2237), - (2244...2248) + (2253...2255), + (2262...2266) )], nil, - (2225...2229), - (2249...2252) + (2243...2247), + (2267...2270) ), - CaseNode(2253...2282)( - CallNode(2258...2261)( + CaseNode(2271...2300)( + CallNode(2276...2279)( nil, nil, - (2258...2261), + (2276...2279), nil, nil, nil, @@ -2767,26 +2796,26 @@ ProgramNode(0...3725)( 0, "foo" ), - [InNode(2263...2278)( - XStringNode(2266...2273)( - (2266...2269), - (2269...2272), - (2272...2273), + [InNode(2281...2296)( + XStringNode(2284...2291)( + (2284...2287), + (2287...2290), + (2290...2291), "foo" ), nil, - (2263...2265), - (2274...2278) + (2281...2283), + (2292...2296) )], nil, - (2253...2257), - (2279...2282) + (2271...2275), + (2297...2300) ), - CaseNode(2283...2312)( - CallNode(2288...2291)( + CaseNode(2301...2330)( + CallNode(2306...2309)( nil, nil, - (2288...2291), + (2306...2309), nil, nil, nil, @@ -2794,25 +2823,25 @@ ProgramNode(0...3725)( 0, "foo" ), - [InNode(2293...2308)( - ArrayNode(2296...2303)( - [SymbolNode(2299...2302)(nil, (2299...2302), nil, "foo")], - (2296...2299), - (2302...2303) + [InNode(2311...2326)( + ArrayNode(2314...2321)( + [SymbolNode(2317...2320)(nil, (2317...2320), nil, "foo")], + (2314...2317), + (2320...2321) ), nil, - (2293...2295), - (2304...2308) + (2311...2313), + (2322...2326) )], nil, - (2283...2287), - (2309...2312) + (2301...2305), + (2327...2330) ), - CaseNode(2313...2342)( - CallNode(2318...2321)( + CaseNode(2331...2360)( + CallNode(2336...2339)( nil, nil, - (2318...2321), + (2336...2339), nil, nil, nil, @@ -2820,25 +2849,25 @@ ProgramNode(0...3725)( 0, "foo" ), - [InNode(2323...2338)( - ArrayNode(2326...2333)( - [SymbolNode(2329...2332)(nil, (2329...2332), nil, "foo")], - (2326...2329), - (2332...2333) + [InNode(2341...2356)( + ArrayNode(2344...2351)( + [SymbolNode(2347...2350)(nil, (2347...2350), nil, "foo")], + (2344...2347), + (2350...2351) ), nil, - (2323...2325), - (2334...2338) + (2341...2343), + (2352...2356) )], nil, - (2313...2317), - (2339...2342) + (2331...2335), + (2357...2360) ), - CaseNode(2343...2372)( - CallNode(2348...2351)( + CaseNode(2361...2390)( + CallNode(2366...2369)( nil, nil, - (2348...2351), + (2366...2369), nil, nil, nil, @@ -2846,25 +2875,25 @@ ProgramNode(0...3725)( 0, "foo" ), - [InNode(2353...2368)( - ArrayNode(2356...2363)( - [StringNode(2359...2362)(nil, (2359...2362), nil, "foo")], - (2356...2359), - (2362...2363) + [InNode(2371...2386)( + ArrayNode(2374...2381)( + [StringNode(2377...2380)(nil, (2377...2380), nil, "foo")], + (2374...2377), + (2380...2381) ), nil, - (2353...2355), - (2364...2368) + (2371...2373), + (2382...2386) )], nil, - (2343...2347), - (2369...2372) + (2361...2365), + (2387...2390) ), - CaseNode(2373...2402)( - CallNode(2378...2381)( + CaseNode(2391...2420)( + CallNode(2396...2399)( nil, nil, - (2378...2381), + (2396...2399), nil, nil, nil, @@ -2872,25 +2901,25 @@ ProgramNode(0...3725)( 0, "foo" ), - [InNode(2383...2398)( - ArrayNode(2386...2393)( - [StringNode(2389...2392)(nil, (2389...2392), nil, "foo")], - (2386...2389), - (2392...2393) + [InNode(2401...2416)( + ArrayNode(2404...2411)( + [StringNode(2407...2410)(nil, (2407...2410), nil, "foo")], + (2404...2407), + (2410...2411) ), nil, - (2383...2385), - (2394...2398) + (2401...2403), + (2412...2416) )], nil, - (2373...2377), - (2399...2402) + (2391...2395), + (2417...2420) ), - CaseNode(2403...2432)( - CallNode(2408...2411)( + CaseNode(2421...2450)( + CallNode(2426...2429)( nil, nil, - (2408...2411), + (2426...2429), nil, nil, nil, @@ -2898,26 +2927,26 @@ ProgramNode(0...3725)( 0, "foo" ), - [InNode(2413...2428)( - StringNode(2416...2423)( - (2416...2419), - (2419...2422), - (2422...2423), + [InNode(2431...2446)( + StringNode(2434...2441)( + (2434...2437), + (2437...2440), + (2440...2441), "foo" ), nil, - (2413...2415), - (2424...2428) + (2431...2433), + (2442...2446) )], nil, - (2403...2407), - (2429...2432) + (2421...2425), + (2447...2450) ), - CaseNode(2433...2462)( - CallNode(2438...2441)( + CaseNode(2451...2480)( + CallNode(2456...2459)( nil, nil, - (2438...2441), + (2456...2459), nil, nil, nil, @@ -2925,26 +2954,26 @@ ProgramNode(0...3725)( 0, "foo" ), - [InNode(2443...2458)( - StringNode(2446...2453)( - (2446...2449), - (2449...2452), - (2452...2453), + [InNode(2461...2476)( + StringNode(2464...2471)( + (2464...2467), + (2467...2470), + (2470...2471), "foo" ), nil, - (2443...2445), - (2454...2458) + (2461...2463), + (2472...2476) )], nil, - (2433...2437), - (2459...2462) + (2451...2455), + (2477...2480) ), - CaseNode(2463...2490)( - CallNode(2468...2471)( + CaseNode(2481...2508)( + CallNode(2486...2489)( nil, nil, - (2468...2471), + (2486...2489), nil, nil, nil, @@ -2952,26 +2981,26 @@ ProgramNode(0...3725)( 0, "foo" ), - [InNode(2473...2486)( - StringNode(2476...2481)( - (2476...2477), - (2477...2480), - (2480...2481), + [InNode(2491...2504)( + StringNode(2494...2499)( + (2494...2495), + (2495...2498), + (2498...2499), "foo" ), nil, - (2473...2475), - (2482...2486) + (2491...2493), + (2500...2504) )], nil, - (2463...2467), - (2487...2490) + (2481...2485), + (2505...2508) ), - CaseNode(2491...2516)( - CallNode(2496...2499)( + CaseNode(2509...2534)( + CallNode(2514...2517)( nil, nil, - (2496...2499), + (2514...2517), nil, nil, nil, @@ -2979,21 +3008,21 @@ ProgramNode(0...3725)( 0, "foo" ), - [InNode(2501...2512)( - NilNode(2504...2507)(), + [InNode(2519...2530)( + NilNode(2522...2525)(), nil, - (2501...2503), - (2508...2512) + (2519...2521), + (2526...2530) )], nil, - (2491...2495), - (2513...2516) + (2509...2513), + (2531...2534) ), - CaseNode(2517...2543)( - CallNode(2522...2525)( + CaseNode(2535...2561)( + CallNode(2540...2543)( nil, nil, - (2522...2525), + (2540...2543), nil, nil, nil, @@ -3001,21 +3030,21 @@ ProgramNode(0...3725)( 0, "foo" ), - [InNode(2527...2539)( - SelfNode(2530...2534)(), + [InNode(2545...2557)( + SelfNode(2548...2552)(), nil, - (2527...2529), - (2535...2539) + (2545...2547), + (2553...2557) )], nil, - (2517...2521), - (2540...2543) + (2535...2539), + (2558...2561) ), - CaseNode(2544...2570)( - CallNode(2549...2552)( + CaseNode(2562...2588)( + CallNode(2567...2570)( nil, nil, - (2549...2552), + (2567...2570), nil, nil, nil, @@ -3023,21 +3052,21 @@ ProgramNode(0...3725)( 0, "foo" ), - [InNode(2554...2566)( - TrueNode(2557...2561)(), + [InNode(2572...2584)( + TrueNode(2575...2579)(), nil, - (2554...2556), - (2562...2566) + (2572...2574), + (2580...2584) )], nil, - (2544...2548), - (2567...2570) + (2562...2566), + (2585...2588) ), - CaseNode(2571...2598)( - CallNode(2576...2579)( + CaseNode(2589...2616)( + CallNode(2594...2597)( nil, nil, - (2576...2579), + (2594...2597), nil, nil, nil, @@ -3045,21 +3074,21 @@ ProgramNode(0...3725)( 0, "foo" ), - [InNode(2581...2594)( - FalseNode(2584...2589)(), + [InNode(2599...2612)( + FalseNode(2602...2607)(), nil, - (2581...2583), - (2590...2594) + (2599...2601), + (2608...2612) )], nil, - (2571...2575), - (2595...2598) + (2589...2593), + (2613...2616) ), - CaseNode(2599...2629)( - CallNode(2604...2607)( + CaseNode(2617...2647)( + CallNode(2622...2625)( nil, nil, - (2604...2607), + (2622...2625), nil, nil, nil, @@ -3067,21 +3096,21 @@ ProgramNode(0...3725)( 0, "foo" ), - [InNode(2609...2625)( - SourceFileNode(2612...2620)("/fixtures/patterns.txt"), + [InNode(2627...2643)( + SourceFileNode(2630...2638)("patterns.txt"), nil, - (2609...2611), - (2621...2625) + (2627...2629), + (2639...2643) )], nil, - (2599...2603), - (2626...2629) + (2617...2621), + (2644...2647) ), - CaseNode(2630...2660)( - CallNode(2635...2638)( + CaseNode(2648...2678)( + CallNode(2653...2656)( nil, nil, - (2635...2638), + (2653...2656), nil, nil, nil, @@ -3089,21 +3118,21 @@ ProgramNode(0...3725)( 0, "foo" ), - [InNode(2640...2656)( - SourceLineNode(2643...2651)(), + [InNode(2658...2674)( + SourceLineNode(2661...2669)(), nil, - (2640...2642), - (2652...2656) + (2658...2660), + (2670...2674) )], nil, - (2630...2634), - (2657...2660) + (2648...2652), + (2675...2678) ), - CaseNode(2661...2695)( - CallNode(2666...2669)( + CaseNode(2679...2713)( + CallNode(2684...2687)( nil, nil, - (2666...2669), + (2684...2687), nil, nil, nil, @@ -3111,21 +3140,21 @@ ProgramNode(0...3725)( 0, "foo" ), - [InNode(2671...2691)( - SourceEncodingNode(2674...2686)(), + [InNode(2689...2709)( + SourceEncodingNode(2692...2704)(), nil, - (2671...2673), - (2687...2691) + (2689...2691), + (2705...2709) )], nil, - (2661...2665), - (2692...2695) + (2679...2683), + (2710...2713) ), - CaseNode(2696...2728)( - CallNode(2701...2704)( + CaseNode(2714...2746)( + CallNode(2719...2722)( nil, nil, - (2701...2704), + (2719...2722), nil, nil, nil, @@ -3133,28 +3162,28 @@ ProgramNode(0...3725)( 0, "foo" ), - [InNode(2706...2724)( - LambdaNode(2709...2719)( + [InNode(2724...2742)( + LambdaNode(2727...2737)( [], - (2709...2711), + (2727...2729), nil, - StatementsNode(2714...2717)( - [LocalVariableReadNode(2714...2717)(:bar, 1)] + StatementsNode(2732...2735)( + [LocalVariableReadNode(2732...2735)(:bar, 1)] ) ), nil, - (2706...2708), - (2720...2724) + (2724...2726), + (2738...2742) )], nil, - (2696...2700), - (2725...2728) + (2714...2718), + (2743...2746) ), - CaseNode(2730...2762)( - CallNode(2735...2738)( + CaseNode(2748...2780)( + CallNode(2753...2756)( nil, nil, - (2735...2738), + (2753...2756), nil, nil, nil, @@ -3162,16 +3191,16 @@ ProgramNode(0...3725)( 0, "foo" ), - [InNode(2740...2758)( - IfNode(2743...2753)( - (2747...2749), - LocalVariableReadNode(2750...2753)(:baz, 0), - StatementsNode(2743...2746)( - [LocalVariableWriteNode(2743...2746)( + [InNode(2758...2776)( + IfNode(2761...2771)( + (2765...2767), + LocalVariableReadNode(2768...2771)(:baz, 0), + StatementsNode(2761...2764)( + [LocalVariableWriteNode(2761...2764)( :bar, 0, nil, - (2743...2746), + (2761...2764), nil )] ), @@ -3179,18 +3208,18 @@ ProgramNode(0...3725)( nil ), nil, - (2740...2742), - (2754...2758) + (2758...2760), + (2772...2776) )], nil, - (2730...2734), - (2759...2762) + (2748...2752), + (2777...2780) ), - CaseNode(2763...2793)( - CallNode(2768...2771)( + CaseNode(2781...2811)( + CallNode(2786...2789)( nil, nil, - (2768...2771), + (2786...2789), nil, nil, nil, @@ -3198,27 +3227,27 @@ ProgramNode(0...3725)( 0, "foo" ), - [InNode(2773...2789)( - IfNode(2776...2784)( - (2778...2780), - LocalVariableReadNode(2781...2784)(:baz, 0), - StatementsNode(2776...2777)([IntegerNode(2776...2777)()]), + [InNode(2791...2807)( + IfNode(2794...2802)( + (2796...2798), + LocalVariableReadNode(2799...2802)(:baz, 0), + StatementsNode(2794...2795)([IntegerNode(2794...2795)()]), nil, nil ), nil, - (2773...2775), - (2785...2789) + (2791...2793), + (2803...2807) )], nil, - (2763...2767), - (2790...2793) + (2781...2785), + (2808...2811) ), - CaseNode(2794...2826)( - CallNode(2799...2802)( + CaseNode(2812...2844)( + CallNode(2817...2820)( nil, nil, - (2799...2802), + (2817...2820), nil, nil, nil, @@ -3226,27 +3255,27 @@ ProgramNode(0...3725)( 0, "foo" ), - [InNode(2804...2822)( - IfNode(2807...2817)( - (2811...2813), - LocalVariableReadNode(2814...2817)(:baz, 0), - StatementsNode(2807...2810)([FloatNode(2807...2810)()]), + [InNode(2822...2840)( + IfNode(2825...2835)( + (2829...2831), + LocalVariableReadNode(2832...2835)(:baz, 0), + StatementsNode(2825...2828)([FloatNode(2825...2828)()]), nil, nil ), nil, - (2804...2806), - (2818...2822) + (2822...2824), + (2836...2840) )], nil, - (2794...2798), - (2823...2826) + (2812...2816), + (2841...2844) ), - CaseNode(2827...2858)( - CallNode(2832...2835)( + CaseNode(2845...2876)( + CallNode(2850...2853)( nil, nil, - (2832...2835), + (2850...2853), nil, nil, nil, @@ -3254,29 +3283,29 @@ ProgramNode(0...3725)( 0, "foo" ), - [InNode(2837...2854)( - IfNode(2840...2849)( - (2843...2845), - LocalVariableReadNode(2846...2849)(:baz, 0), - StatementsNode(2840...2842)( - [ImaginaryNode(2840...2842)(IntegerNode(2840...2841)())] + [InNode(2855...2872)( + IfNode(2858...2867)( + (2861...2863), + LocalVariableReadNode(2864...2867)(:baz, 0), + StatementsNode(2858...2860)( + [ImaginaryNode(2858...2860)(IntegerNode(2858...2859)())] ), nil, nil ), nil, - (2837...2839), - (2850...2854) + (2855...2857), + (2868...2872) )], nil, - (2827...2831), - (2855...2858) + (2845...2849), + (2873...2876) ), - CaseNode(2859...2890)( - CallNode(2864...2867)( + CaseNode(2877...2908)( + CallNode(2882...2885)( nil, nil, - (2864...2867), + (2882...2885), nil, nil, nil, @@ -3284,29 +3313,29 @@ ProgramNode(0...3725)( 0, "foo" ), - [InNode(2869...2886)( - IfNode(2872...2881)( - (2875...2877), - LocalVariableReadNode(2878...2881)(:baz, 0), - StatementsNode(2872...2874)( - [RationalNode(2872...2874)(IntegerNode(2872...2873)())] + [InNode(2887...2904)( + IfNode(2890...2899)( + (2893...2895), + LocalVariableReadNode(2896...2899)(:baz, 0), + StatementsNode(2890...2892)( + [RationalNode(2890...2892)(IntegerNode(2890...2891)())] ), nil, nil ), nil, - (2869...2871), - (2882...2886) + (2887...2889), + (2900...2904) )], nil, - (2859...2863), - (2887...2890) + (2877...2881), + (2905...2908) ), - CaseNode(2891...2924)( - CallNode(2896...2899)( + CaseNode(2909...2942)( + CallNode(2914...2917)( nil, nil, - (2896...2899), + (2914...2917), nil, nil, nil, @@ -3314,14 +3343,14 @@ ProgramNode(0...3725)( 0, "foo" ), - [InNode(2901...2920)( - IfNode(2904...2915)( - (2909...2911), - LocalVariableReadNode(2912...2915)(:baz, 0), - StatementsNode(2904...2908)( - [SymbolNode(2904...2908)( - (2904...2905), - (2905...2908), + [InNode(2919...2938)( + IfNode(2922...2933)( + (2927...2929), + LocalVariableReadNode(2930...2933)(:baz, 0), + StatementsNode(2922...2926)( + [SymbolNode(2922...2926)( + (2922...2923), + (2923...2926), nil, "foo" )] @@ -3330,18 +3359,18 @@ ProgramNode(0...3725)( nil ), nil, - (2901...2903), - (2916...2920) + (2919...2921), + (2934...2938) )], nil, - (2891...2895), - (2921...2924) + (2909...2913), + (2939...2942) ), - CaseNode(2925...2961)( - CallNode(2930...2933)( + CaseNode(2943...2979)( + CallNode(2948...2951)( nil, nil, - (2930...2933), + (2948...2951), nil, nil, nil, @@ -3349,15 +3378,15 @@ ProgramNode(0...3725)( 0, "foo" ), - [InNode(2935...2957)( - IfNode(2938...2952)( - (2946...2948), - LocalVariableReadNode(2949...2952)(:baz, 0), - StatementsNode(2938...2945)( - [SymbolNode(2938...2945)( - (2938...2941), - (2941...2944), - (2944...2945), + [InNode(2953...2975)( + IfNode(2956...2970)( + (2964...2966), + LocalVariableReadNode(2967...2970)(:baz, 0), + StatementsNode(2956...2963)( + [SymbolNode(2956...2963)( + (2956...2959), + (2959...2962), + (2962...2963), "foo" )] ), @@ -3365,18 +3394,18 @@ ProgramNode(0...3725)( nil ), nil, - (2935...2937), - (2953...2957) + (2953...2955), + (2971...2975) )], nil, - (2925...2929), - (2958...2961) + (2943...2947), + (2976...2979) ), - CaseNode(2962...2997)( - CallNode(2967...2970)( + CaseNode(2980...3015)( + CallNode(2985...2988)( nil, nil, - (2967...2970), + (2985...2988), nil, nil, nil, @@ -3384,33 +3413,33 @@ ProgramNode(0...3725)( 0, "foo" ), - [InNode(2972...2993)( - IfNode(2975...2988)( - (2982...2984), - LocalVariableReadNode(2985...2988)(:baz, 0), - StatementsNode(2975...2981)( - [InterpolatedSymbolNode(2975...2981)( - (2975...2977), - [StringNode(2977...2980)(nil, (2977...2980), nil, "foo")], - (2980...2981) + [InNode(2990...3011)( + IfNode(2993...3006)( + (3000...3002), + LocalVariableReadNode(3003...3006)(:baz, 0), + StatementsNode(2993...2999)( + [InterpolatedSymbolNode(2993...2999)( + (2993...2995), + [StringNode(2995...2998)(nil, (2995...2998), nil, "foo")], + (2998...2999) )] ), nil, nil ), nil, - (2972...2974), - (2989...2993) + (2990...2992), + (3007...3011) )], nil, - (2962...2966), - (2994...2997) + (2980...2984), + (3012...3015) ), - CaseNode(2998...3032)( - CallNode(3003...3006)( + CaseNode(3016...3050)( + CallNode(3021...3024)( nil, nil, - (3003...3006), + (3021...3024), nil, nil, nil, @@ -3418,15 +3447,15 @@ ProgramNode(0...3725)( 0, "foo" ), - [InNode(3008...3028)( - IfNode(3011...3023)( - (3017...3019), - LocalVariableReadNode(3020...3023)(:baz, 0), - StatementsNode(3011...3016)( - [RegularExpressionNode(3011...3016)( - (3011...3012), - (3012...3015), - (3015...3016), + [InNode(3026...3046)( + IfNode(3029...3041)( + (3035...3037), + LocalVariableReadNode(3038...3041)(:baz, 0), + StatementsNode(3029...3034)( + [RegularExpressionNode(3029...3034)( + (3029...3030), + (3030...3033), + (3033...3034), "foo", 0 )] @@ -3435,18 +3464,18 @@ ProgramNode(0...3725)( nil ), nil, - (3008...3010), - (3024...3028) + (3026...3028), + (3042...3046) )], nil, - (2998...3002), - (3029...3032) + (3016...3020), + (3047...3050) ), - CaseNode(3033...3067)( - CallNode(3038...3041)( + CaseNode(3051...3085)( + CallNode(3056...3059)( nil, nil, - (3038...3041), + (3056...3059), nil, nil, nil, @@ -3454,15 +3483,15 @@ ProgramNode(0...3725)( 0, "foo" ), - [InNode(3043...3063)( - IfNode(3046...3058)( - (3052...3054), - LocalVariableReadNode(3055...3058)(:baz, 0), - StatementsNode(3046...3051)( - [XStringNode(3046...3051)( - (3046...3047), - (3047...3050), - (3050...3051), + [InNode(3061...3081)( + IfNode(3064...3076)( + (3070...3072), + LocalVariableReadNode(3073...3076)(:baz, 0), + StatementsNode(3064...3069)( + [XStringNode(3064...3069)( + (3064...3065), + (3065...3068), + (3068...3069), "foo" )] ), @@ -3470,18 +3499,18 @@ ProgramNode(0...3725)( nil ), nil, - (3043...3045), - (3059...3063) + (3061...3063), + (3077...3081) )], nil, - (3033...3037), - (3064...3067) + (3051...3055), + (3082...3085) ), - CaseNode(3068...3104)( - CallNode(3073...3076)( + CaseNode(3086...3122)( + CallNode(3091...3094)( nil, nil, - (3073...3076), + (3091...3094), nil, nil, nil, @@ -3489,15 +3518,15 @@ ProgramNode(0...3725)( 0, "foo" ), - [InNode(3078...3100)( - IfNode(3081...3095)( - (3089...3091), - LocalVariableReadNode(3092...3095)(:baz, 0), - StatementsNode(3081...3088)( - [XStringNode(3081...3088)( - (3081...3084), - (3084...3087), - (3087...3088), + [InNode(3096...3118)( + IfNode(3099...3113)( + (3107...3109), + LocalVariableReadNode(3110...3113)(:baz, 0), + StatementsNode(3099...3106)( + [XStringNode(3099...3106)( + (3099...3102), + (3102...3105), + (3105...3106), "foo" )] ), @@ -3505,18 +3534,18 @@ ProgramNode(0...3725)( nil ), nil, - (3078...3080), - (3096...3100) + (3096...3098), + (3114...3118) )], nil, - (3068...3072), - (3101...3104) + (3086...3090), + (3119...3122) ), - CaseNode(3105...3141)( - CallNode(3110...3113)( + CaseNode(3123...3159)( + CallNode(3128...3131)( nil, nil, - (3110...3113), + (3128...3131), nil, nil, nil, @@ -3524,33 +3553,33 @@ ProgramNode(0...3725)( 0, "foo" ), - [InNode(3115...3137)( - IfNode(3118...3132)( - (3126...3128), - LocalVariableReadNode(3129...3132)(:baz, 0), - StatementsNode(3118...3125)( - [ArrayNode(3118...3125)( - [SymbolNode(3121...3124)(nil, (3121...3124), nil, "foo")], - (3118...3121), - (3124...3125) + [InNode(3133...3155)( + IfNode(3136...3150)( + (3144...3146), + LocalVariableReadNode(3147...3150)(:baz, 0), + StatementsNode(3136...3143)( + [ArrayNode(3136...3143)( + [SymbolNode(3139...3142)(nil, (3139...3142), nil, "foo")], + (3136...3139), + (3142...3143) )] ), nil, nil ), nil, - (3115...3117), - (3133...3137) + (3133...3135), + (3151...3155) )], nil, - (3105...3109), - (3138...3141) + (3123...3127), + (3156...3159) ), - CaseNode(3142...3178)( - CallNode(3147...3150)( + CaseNode(3160...3196)( + CallNode(3165...3168)( nil, nil, - (3147...3150), + (3165...3168), nil, nil, nil, @@ -3558,33 +3587,33 @@ ProgramNode(0...3725)( 0, "foo" ), - [InNode(3152...3174)( - IfNode(3155...3169)( - (3163...3165), - LocalVariableReadNode(3166...3169)(:baz, 0), - StatementsNode(3155...3162)( - [ArrayNode(3155...3162)( - [SymbolNode(3158...3161)(nil, (3158...3161), nil, "foo")], - (3155...3158), - (3161...3162) + [InNode(3170...3192)( + IfNode(3173...3187)( + (3181...3183), + LocalVariableReadNode(3184...3187)(:baz, 0), + StatementsNode(3173...3180)( + [ArrayNode(3173...3180)( + [SymbolNode(3176...3179)(nil, (3176...3179), nil, "foo")], + (3173...3176), + (3179...3180) )] ), nil, nil ), nil, - (3152...3154), - (3170...3174) + (3170...3172), + (3188...3192) )], nil, - (3142...3146), - (3175...3178) + (3160...3164), + (3193...3196) ), - CaseNode(3179...3215)( - CallNode(3184...3187)( + CaseNode(3197...3233)( + CallNode(3202...3205)( nil, nil, - (3184...3187), + (3202...3205), nil, nil, nil, @@ -3592,33 +3621,33 @@ ProgramNode(0...3725)( 0, "foo" ), - [InNode(3189...3211)( - IfNode(3192...3206)( - (3200...3202), - LocalVariableReadNode(3203...3206)(:baz, 0), - StatementsNode(3192...3199)( - [ArrayNode(3192...3199)( - [StringNode(3195...3198)(nil, (3195...3198), nil, "foo")], - (3192...3195), - (3198...3199) + [InNode(3207...3229)( + IfNode(3210...3224)( + (3218...3220), + LocalVariableReadNode(3221...3224)(:baz, 0), + StatementsNode(3210...3217)( + [ArrayNode(3210...3217)( + [StringNode(3213...3216)(nil, (3213...3216), nil, "foo")], + (3210...3213), + (3216...3217) )] ), nil, nil ), nil, - (3189...3191), - (3207...3211) + (3207...3209), + (3225...3229) )], nil, - (3179...3183), - (3212...3215) + (3197...3201), + (3230...3233) ), - CaseNode(3216...3252)( - CallNode(3221...3224)( + CaseNode(3234...3270)( + CallNode(3239...3242)( nil, nil, - (3221...3224), + (3239...3242), nil, nil, nil, @@ -3626,33 +3655,33 @@ ProgramNode(0...3725)( 0, "foo" ), - [InNode(3226...3248)( - IfNode(3229...3243)( - (3237...3239), - LocalVariableReadNode(3240...3243)(:baz, 0), - StatementsNode(3229...3236)( - [ArrayNode(3229...3236)( - [StringNode(3232...3235)(nil, (3232...3235), nil, "foo")], - (3229...3232), - (3235...3236) + [InNode(3244...3266)( + IfNode(3247...3261)( + (3255...3257), + LocalVariableReadNode(3258...3261)(:baz, 0), + StatementsNode(3247...3254)( + [ArrayNode(3247...3254)( + [StringNode(3250...3253)(nil, (3250...3253), nil, "foo")], + (3247...3250), + (3253...3254) )] ), nil, nil ), nil, - (3226...3228), - (3244...3248) + (3244...3246), + (3262...3266) )], nil, - (3216...3220), - (3249...3252) + (3234...3238), + (3267...3270) ), - CaseNode(3253...3289)( - CallNode(3258...3261)( + CaseNode(3271...3307)( + CallNode(3276...3279)( nil, nil, - (3258...3261), + (3276...3279), nil, nil, nil, @@ -3660,15 +3689,15 @@ ProgramNode(0...3725)( 0, "foo" ), - [InNode(3263...3285)( - IfNode(3266...3280)( - (3274...3276), - LocalVariableReadNode(3277...3280)(:baz, 0), - StatementsNode(3266...3273)( - [StringNode(3266...3273)( - (3266...3269), - (3269...3272), - (3272...3273), + [InNode(3281...3303)( + IfNode(3284...3298)( + (3292...3294), + LocalVariableReadNode(3295...3298)(:baz, 0), + StatementsNode(3284...3291)( + [StringNode(3284...3291)( + (3284...3287), + (3287...3290), + (3290...3291), "foo" )] ), @@ -3676,18 +3705,18 @@ ProgramNode(0...3725)( nil ), nil, - (3263...3265), - (3281...3285) + (3281...3283), + (3299...3303) )], nil, - (3253...3257), - (3286...3289) + (3271...3275), + (3304...3307) ), - CaseNode(3290...3326)( - CallNode(3295...3298)( + CaseNode(3308...3344)( + CallNode(3313...3316)( nil, nil, - (3295...3298), + (3313...3316), nil, nil, nil, @@ -3695,15 +3724,15 @@ ProgramNode(0...3725)( 0, "foo" ), - [InNode(3300...3322)( - IfNode(3303...3317)( - (3311...3313), - LocalVariableReadNode(3314...3317)(:baz, 0), - StatementsNode(3303...3310)( - [StringNode(3303...3310)( - (3303...3306), - (3306...3309), - (3309...3310), + [InNode(3318...3340)( + IfNode(3321...3335)( + (3329...3331), + LocalVariableReadNode(3332...3335)(:baz, 0), + StatementsNode(3321...3328)( + [StringNode(3321...3328)( + (3321...3324), + (3324...3327), + (3327...3328), "foo" )] ), @@ -3711,18 +3740,18 @@ ProgramNode(0...3725)( nil ), nil, - (3300...3302), - (3318...3322) + (3318...3320), + (3336...3340) )], nil, - (3290...3294), - (3323...3326) + (3308...3312), + (3341...3344) ), - CaseNode(3327...3361)( - CallNode(3332...3335)( + CaseNode(3345...3379)( + CallNode(3350...3353)( nil, nil, - (3332...3335), + (3350...3353), nil, nil, nil, @@ -3730,15 +3759,15 @@ ProgramNode(0...3725)( 0, "foo" ), - [InNode(3337...3357)( - IfNode(3340...3352)( - (3346...3348), - LocalVariableReadNode(3349...3352)(:baz, 0), - StatementsNode(3340...3345)( - [StringNode(3340...3345)( - (3340...3341), - (3341...3344), - (3344...3345), + [InNode(3355...3375)( + IfNode(3358...3370)( + (3364...3366), + LocalVariableReadNode(3367...3370)(:baz, 0), + StatementsNode(3358...3363)( + [StringNode(3358...3363)( + (3358...3359), + (3359...3362), + (3362...3363), "foo" )] ), @@ -3746,18 +3775,18 @@ ProgramNode(0...3725)( nil ), nil, - (3337...3339), - (3353...3357) + (3355...3357), + (3371...3375) )], nil, - (3327...3331), - (3358...3361) + (3345...3349), + (3376...3379) ), - CaseNode(3362...3394)( - CallNode(3367...3370)( + CaseNode(3380...3412)( + CallNode(3385...3388)( nil, nil, - (3367...3370), + (3385...3388), nil, nil, nil, @@ -3765,27 +3794,27 @@ ProgramNode(0...3725)( 0, "foo" ), - [InNode(3372...3390)( - IfNode(3375...3385)( - (3379...3381), - LocalVariableReadNode(3382...3385)(:baz, 0), - StatementsNode(3375...3378)([NilNode(3375...3378)()]), + [InNode(3390...3408)( + IfNode(3393...3403)( + (3397...3399), + LocalVariableReadNode(3400...3403)(:baz, 0), + StatementsNode(3393...3396)([NilNode(3393...3396)()]), nil, nil ), nil, - (3372...3374), - (3386...3390) + (3390...3392), + (3404...3408) )], nil, - (3362...3366), - (3391...3394) + (3380...3384), + (3409...3412) ), - CaseNode(3395...3428)( - CallNode(3400...3403)( + CaseNode(3413...3446)( + CallNode(3418...3421)( nil, nil, - (3400...3403), + (3418...3421), nil, nil, nil, @@ -3793,27 +3822,27 @@ ProgramNode(0...3725)( 0, "foo" ), - [InNode(3405...3424)( - IfNode(3408...3419)( - (3413...3415), - LocalVariableReadNode(3416...3419)(:baz, 0), - StatementsNode(3408...3412)([SelfNode(3408...3412)()]), + [InNode(3423...3442)( + IfNode(3426...3437)( + (3431...3433), + LocalVariableReadNode(3434...3437)(:baz, 0), + StatementsNode(3426...3430)([SelfNode(3426...3430)()]), nil, nil ), nil, - (3405...3407), - (3420...3424) + (3423...3425), + (3438...3442) )], nil, - (3395...3399), - (3425...3428) + (3413...3417), + (3443...3446) ), - CaseNode(3429...3462)( - CallNode(3434...3437)( + CaseNode(3447...3480)( + CallNode(3452...3455)( nil, nil, - (3434...3437), + (3452...3455), nil, nil, nil, @@ -3821,27 +3850,27 @@ ProgramNode(0...3725)( 0, "foo" ), - [InNode(3439...3458)( - IfNode(3442...3453)( - (3447...3449), - LocalVariableReadNode(3450...3453)(:baz, 0), - StatementsNode(3442...3446)([TrueNode(3442...3446)()]), + [InNode(3457...3476)( + IfNode(3460...3471)( + (3465...3467), + LocalVariableReadNode(3468...3471)(:baz, 0), + StatementsNode(3460...3464)([TrueNode(3460...3464)()]), nil, nil ), nil, - (3439...3441), - (3454...3458) + (3457...3459), + (3472...3476) )], nil, - (3429...3433), - (3459...3462) + (3447...3451), + (3477...3480) ), - CaseNode(3463...3497)( - CallNode(3468...3471)( + CaseNode(3481...3515)( + CallNode(3486...3489)( nil, nil, - (3468...3471), + (3486...3489), nil, nil, nil, @@ -3849,27 +3878,27 @@ ProgramNode(0...3725)( 0, "foo" ), - [InNode(3473...3493)( - IfNode(3476...3488)( - (3482...3484), - LocalVariableReadNode(3485...3488)(:baz, 0), - StatementsNode(3476...3481)([FalseNode(3476...3481)()]), + [InNode(3491...3511)( + IfNode(3494...3506)( + (3500...3502), + LocalVariableReadNode(3503...3506)(:baz, 0), + StatementsNode(3494...3499)([FalseNode(3494...3499)()]), nil, nil ), nil, - (3473...3475), - (3489...3493) + (3491...3493), + (3507...3511) )], nil, - (3463...3467), - (3494...3497) + (3481...3485), + (3512...3515) ), - CaseNode(3498...3535)( - CallNode(3503...3506)( + CaseNode(3516...3553)( + CallNode(3521...3524)( nil, nil, - (3503...3506), + (3521...3524), nil, nil, nil, @@ -3877,29 +3906,29 @@ ProgramNode(0...3725)( 0, "foo" ), - [InNode(3508...3531)( - IfNode(3511...3526)( - (3520...3522), - LocalVariableReadNode(3523...3526)(:baz, 0), - StatementsNode(3511...3519)( - [SourceFileNode(3511...3519)("/fixtures/patterns.txt")] + [InNode(3526...3549)( + IfNode(3529...3544)( + (3538...3540), + LocalVariableReadNode(3541...3544)(:baz, 0), + StatementsNode(3529...3537)( + [SourceFileNode(3529...3537)("patterns.txt")] ), nil, nil ), nil, - (3508...3510), - (3527...3531) + (3526...3528), + (3545...3549) )], nil, - (3498...3502), - (3532...3535) + (3516...3520), + (3550...3553) ), - CaseNode(3536...3573)( - CallNode(3541...3544)( + CaseNode(3554...3591)( + CallNode(3559...3562)( nil, nil, - (3541...3544), + (3559...3562), nil, nil, nil, @@ -3907,27 +3936,27 @@ ProgramNode(0...3725)( 0, "foo" ), - [InNode(3546...3569)( - IfNode(3549...3564)( - (3558...3560), - LocalVariableReadNode(3561...3564)(:baz, 0), - StatementsNode(3549...3557)([SourceLineNode(3549...3557)()]), + [InNode(3564...3587)( + IfNode(3567...3582)( + (3576...3578), + LocalVariableReadNode(3579...3582)(:baz, 0), + StatementsNode(3567...3575)([SourceLineNode(3567...3575)()]), nil, nil ), nil, - (3546...3548), - (3565...3569) + (3564...3566), + (3583...3587) )], nil, - (3536...3540), - (3570...3573) + (3554...3558), + (3588...3591) ), - CaseNode(3574...3615)( - CallNode(3579...3582)( + CaseNode(3592...3633)( + CallNode(3597...3600)( nil, nil, - (3579...3582), + (3597...3600), nil, nil, nil, @@ -3935,27 +3964,27 @@ ProgramNode(0...3725)( 0, "foo" ), - [InNode(3584...3611)( - IfNode(3587...3606)( - (3600...3602), - LocalVariableReadNode(3603...3606)(:baz, 0), - StatementsNode(3587...3599)([SourceEncodingNode(3587...3599)()]), + [InNode(3602...3629)( + IfNode(3605...3624)( + (3618...3620), + LocalVariableReadNode(3621...3624)(:baz, 0), + StatementsNode(3605...3617)([SourceEncodingNode(3605...3617)()]), nil, nil ), nil, - (3584...3586), - (3607...3611) + (3602...3604), + (3625...3629) )], nil, - (3574...3578), - (3612...3615) + (3592...3596), + (3630...3633) ), - CaseNode(3616...3655)( - CallNode(3621...3624)( + CaseNode(3634...3673)( + CallNode(3639...3642)( nil, nil, - (3621...3624), + (3639...3642), nil, nil, nil, @@ -3963,17 +3992,17 @@ ProgramNode(0...3725)( 0, "foo" ), - [InNode(3626...3651)( - IfNode(3629...3646)( - (3640...3642), - LocalVariableReadNode(3643...3646)(:baz, 0), - StatementsNode(3629...3639)( - [LambdaNode(3629...3639)( + [InNode(3644...3669)( + IfNode(3647...3664)( + (3658...3660), + LocalVariableReadNode(3661...3664)(:baz, 0), + StatementsNode(3647...3657)( + [LambdaNode(3647...3657)( [], - (3629...3631), + (3647...3649), nil, - StatementsNode(3634...3637)( - [LocalVariableReadNode(3634...3637)(:bar, 1)] + StatementsNode(3652...3655)( + [LocalVariableReadNode(3652...3655)(:bar, 1)] ) )] ), @@ -3981,20 +4010,20 @@ ProgramNode(0...3725)( nil ), nil, - (3626...3628), - (3647...3651) + (3644...3646), + (3665...3669) )], nil, - (3616...3620), - (3652...3655) + (3634...3638), + (3670...3673) ), - IfNode(3657...3671)( - (3657...3659), - MatchPredicateNode(3660...3667)( - CallNode(3660...3661)( + IfNode(3675...3689)( + (3675...3677), + MatchPredicateNode(3678...3685)( + CallNode(3678...3679)( nil, nil, - (3660...3661), + (3678...3679), nil, nil, nil, @@ -4002,25 +4031,25 @@ ProgramNode(0...3725)( 0, "a" ), - ArrayPatternNode(3665...3667)( + ArrayPatternNode(3683...3685)( nil, [], nil, [], - (3665...3666), - (3666...3667) + (3683...3684), + (3684...3685) ), - (3662...3664) + (3680...3682) ), nil, nil, - (3668...3671) + (3686...3689) ), - MatchRequiredNode(3673...3685)( - CallNode(3673...3674)( + MatchRequiredNode(3691...3703)( + CallNode(3691...3692)( nil, nil, - (3673...3674), + (3691...3692), nil, nil, nil, @@ -4028,21 +4057,21 @@ ProgramNode(0...3725)( 0, "a" ), - ArrayPatternNode(3678...3685)( + ArrayPatternNode(3696...3703)( nil, - [LocalVariableWriteNode(3682...3683)(:b, 0, nil, (3682...3683), nil)], + [LocalVariableWriteNode(3700...3701)(:b, 0, nil, (3700...3701), nil)], nil, [], - (3678...3679), - (3684...3685) + (3696...3697), + (3702...3703) ), - (3675...3677) + (3693...3695) ), - MatchPredicateNode(3687...3725)( - CallNode(3687...3690)( + MatchPredicateNode(3705...3743)( + CallNode(3705...3708)( nil, nil, - (3687...3690), + (3705...3708), nil, nil, nil, @@ -4050,39 +4079,39 @@ ProgramNode(0...3725)( 0, "foo" ), - HashPatternNode(3694...3725)( - ConstantReadNode(3694...3695)(), - [AssocNode(3699...3723)( - SymbolNode(3699...3703)(nil, (3699...3702), (3702...3703), "bar"), - HashPatternNode(3704...3723)( - ConstantReadNode(3704...3705)(), - [AssocNode(3711...3719)( - SymbolNode(3711...3717)( + HashPatternNode(3712...3743)( + ConstantReadNode(3712...3713)(), + [AssocNode(3717...3741)( + SymbolNode(3717...3721)(nil, (3717...3720), (3720...3721), "bar"), + HashPatternNode(3722...3741)( + ConstantReadNode(3722...3723)(), + [AssocNode(3729...3737)( + SymbolNode(3729...3735)( nil, - (3711...3716), - (3716...3717), + (3729...3734), + (3734...3735), "value" ), - LocalVariableWriteNode(3718...3719)( + LocalVariableWriteNode(3736...3737)( :a, 0, nil, - (3718...3719), + (3736...3737), nil ), nil )], nil, - (3705...3706), - (3722...3723) + (3723...3724), + (3740...3741) ), nil )], nil, - (3695...3696), - (3724...3725) + (3713...3714), + (3742...3743) ), - (3691...3693) + (3709...3711) )] ) ) diff --git a/test/yarp/snapshots/unparser/corpus/literal/pragma.txt b/test/yarp/snapshots/unparser/corpus/literal/pragma.txt index a50b8d7942..26e9f4c56d 100644 --- a/test/yarp/snapshots/unparser/corpus/literal/pragma.txt +++ b/test/yarp/snapshots/unparser/corpus/literal/pragma.txt @@ -2,7 +2,7 @@ ProgramNode(0...38)( [], StatementsNode(0...38)( [SourceEncodingNode(0...12)(), - SourceFileNode(13...21)("/fixtures/unparser/corpus/literal/pragma.txt"), + SourceFileNode(13...21)("unparser/corpus/literal/pragma.txt"), SourceLineNode(22...30)(), CallNode(31...38)(nil, nil, (31...38), nil, nil, nil, nil, 0, "__dir__")] ) diff --git a/test/yarp/snapshots/whitequark/pattern_matching__FILE__LINE_literals.txt b/test/yarp/snapshots/whitequark/pattern_matching__FILE__LINE_literals.txt index 12c279f896..55938adfd8 100644 --- a/test/yarp/snapshots/whitequark/pattern_matching__FILE__LINE_literals.txt +++ b/test/yarp/snapshots/whitequark/pattern_matching__FILE__LINE_literals.txt @@ -3,7 +3,9 @@ ProgramNode(8...111)( StatementsNode(8...111)( [CaseNode(8...111)( ArrayNode(13...51)( - [SourceFileNode(14...22)("/fixtures/whitequark/pattern_matching__FILE__LINE_literals.txt"), + [SourceFileNode(14...22)( + "whitequark/pattern_matching__FILE__LINE_literals.txt" + ), CallNode(24...36)( SourceLineNode(24...32)(), nil, @@ -22,7 +24,9 @@ ProgramNode(8...111)( [InNode(62...99)( ArrayPatternNode(65...99)( nil, - [SourceFileNode(66...74)("/fixtures/whitequark/pattern_matching__FILE__LINE_literals.txt"), + [SourceFileNode(66...74)( + "whitequark/pattern_matching__FILE__LINE_literals.txt" + ), SourceLineNode(76...84)(), SourceEncodingNode(86...98)()], nil, diff --git a/test/yarp/snapshots/whitequark/string___FILE__.txt b/test/yarp/snapshots/whitequark/string___FILE__.txt index 31d5437b21..83e601222d 100644 --- a/test/yarp/snapshots/whitequark/string___FILE__.txt +++ b/test/yarp/snapshots/whitequark/string___FILE__.txt @@ -1,6 +1,6 @@ ProgramNode(0...8)( [], StatementsNode(0...8)( - [SourceFileNode(0...8)("/fixtures/whitequark/string___FILE__.txt")] + [SourceFileNode(0...8)("whitequark/string___FILE__.txt")] ) ) diff --git a/yarp/api_node.c b/yarp/api_node.c index 6e82bc6a07..65a7816eb4 100644 --- a/yarp/api_node.c +++ b/yarp/api_node.c @@ -9,13 +9,14 @@ #include "yarp/extension.h" extern VALUE rb_cYARP; +extern VALUE rb_cYARPSource; extern VALUE rb_cYARPToken; extern VALUE rb_cYARPLocation; static VALUE -location_new(yp_parser_t *parser, const char *start, const char *end) { - VALUE argv[] = { LONG2FIX(start - parser->start), LONG2FIX(end - start) }; - return rb_class_new_instance(2, argv, rb_cYARPLocation); +location_new(yp_parser_t *parser, const char *start, const char *end, VALUE source) { + VALUE argv[] = { source, LONG2FIX(start - parser->start), LONG2FIX(end - start) }; + return rb_class_new_instance(3, argv, rb_cYARPLocation); } static VALUE @@ -23,254 +24,219 @@ yp_string_new(yp_string_t *string, rb_encoding *encoding) { return rb_enc_str_new(yp_string_source(string), yp_string_length(string), encoding); } -VALUE -yp_token_new(yp_parser_t *parser, yp_token_t *token, rb_encoding *encoding) { - ID type = rb_intern(yp_token_type_to_str(token->type)); - VALUE argv[] = { - ID2SYM(type), - rb_enc_str_new(token->start, token->end - token->start, encoding), - LONG2FIX(token->start - parser->start), - LONG2FIX(token->end - token->start) - }; - - return rb_class_new_instance(4, argv, rb_cYARPToken); -} - -VALUE -yp_node_new(yp_parser_t *parser, yp_node_t *node, rb_encoding *encoding, ID *constants) { +static VALUE +yp_node_new(yp_parser_t *parser, yp_node_t *node, VALUE source, rb_encoding *encoding, ID *constants) { switch (node->type) { -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_ALIAS_NODE: { yp_alias_node_t *cast = (yp_alias_node_t *) node; - VALUE argv[5]; + VALUE argv[4]; // new_name - argv[0] = yp_node_new(parser, (yp_node_t *) cast->new_name, encoding, constants); + argv[0] = yp_node_new(parser, (yp_node_t *) cast->new_name, source, encoding, constants); // old_name - argv[1] = yp_node_new(parser, (yp_node_t *) cast->old_name, encoding, constants); + argv[1] = yp_node_new(parser, (yp_node_t *) cast->old_name, source, encoding, constants); // keyword_loc - argv[2] = location_new(parser, cast->keyword_loc.start, cast->keyword_loc.end); + argv[2] = location_new(parser, cast->keyword_loc.start, cast->keyword_loc.end, source); // location - argv[3] = LONG2FIX(node->location.start - parser->start); - argv[4] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(5, argv, rb_const_get_at(rb_cYARP, rb_intern("AliasNode"))); + argv[3] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(4, argv, rb_const_get_at(rb_cYARP, rb_intern("AliasNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_ALTERNATION_PATTERN_NODE: { yp_alternation_pattern_node_t *cast = (yp_alternation_pattern_node_t *) node; - VALUE argv[5]; + VALUE argv[4]; // left - argv[0] = yp_node_new(parser, (yp_node_t *) cast->left, encoding, constants); + argv[0] = yp_node_new(parser, (yp_node_t *) cast->left, source, encoding, constants); // right - argv[1] = yp_node_new(parser, (yp_node_t *) cast->right, encoding, constants); + argv[1] = yp_node_new(parser, (yp_node_t *) cast->right, source, encoding, constants); // operator_loc - argv[2] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end); + argv[2] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source); // location - argv[3] = LONG2FIX(node->location.start - parser->start); - argv[4] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(5, argv, rb_const_get_at(rb_cYARP, rb_intern("AlternationPatternNode"))); + argv[3] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(4, argv, rb_const_get_at(rb_cYARP, rb_intern("AlternationPatternNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_AND_NODE: { yp_and_node_t *cast = (yp_and_node_t *) node; - VALUE argv[5]; + VALUE argv[4]; // left - argv[0] = yp_node_new(parser, (yp_node_t *) cast->left, encoding, constants); + argv[0] = yp_node_new(parser, (yp_node_t *) cast->left, source, encoding, constants); // right - argv[1] = yp_node_new(parser, (yp_node_t *) cast->right, encoding, constants); + argv[1] = yp_node_new(parser, (yp_node_t *) cast->right, source, encoding, constants); // operator_loc - argv[2] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end); + argv[2] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source); // location - argv[3] = LONG2FIX(node->location.start - parser->start); - argv[4] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(5, argv, rb_const_get_at(rb_cYARP, rb_intern("AndNode"))); + argv[3] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(4, argv, rb_const_get_at(rb_cYARP, rb_intern("AndNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_ARGUMENTS_NODE: { yp_arguments_node_t *cast = (yp_arguments_node_t *) node; - VALUE argv[3]; + VALUE argv[2]; // arguments argv[0] = rb_ary_new(); for (size_t index = 0; index < cast->arguments.size; index++) { - rb_ary_push(argv[0], yp_node_new(parser, cast->arguments.nodes[index], encoding, constants)); + rb_ary_push(argv[0], yp_node_new(parser, cast->arguments.nodes[index], source, encoding, constants)); } // location - argv[1] = LONG2FIX(node->location.start - parser->start); - argv[2] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(3, argv, rb_const_get_at(rb_cYARP, rb_intern("ArgumentsNode"))); + argv[1] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(2, argv, rb_const_get_at(rb_cYARP, rb_intern("ArgumentsNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_ARRAY_NODE: { yp_array_node_t *cast = (yp_array_node_t *) node; - VALUE argv[5]; + VALUE argv[4]; // elements argv[0] = rb_ary_new(); for (size_t index = 0; index < cast->elements.size; index++) { - rb_ary_push(argv[0], yp_node_new(parser, cast->elements.nodes[index], encoding, constants)); + rb_ary_push(argv[0], yp_node_new(parser, cast->elements.nodes[index], source, encoding, constants)); } // opening_loc - argv[1] = cast->opening_loc.start == NULL ? Qnil : location_new(parser, cast->opening_loc.start, cast->opening_loc.end); + argv[1] = cast->opening_loc.start == NULL ? Qnil : location_new(parser, cast->opening_loc.start, cast->opening_loc.end, source); // closing_loc - argv[2] = cast->closing_loc.start == NULL ? Qnil : location_new(parser, cast->closing_loc.start, cast->closing_loc.end); + argv[2] = cast->closing_loc.start == NULL ? Qnil : location_new(parser, cast->closing_loc.start, cast->closing_loc.end, source); // location - argv[3] = LONG2FIX(node->location.start - parser->start); - argv[4] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(5, argv, rb_const_get_at(rb_cYARP, rb_intern("ArrayNode"))); + argv[3] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(4, argv, rb_const_get_at(rb_cYARP, rb_intern("ArrayNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_ARRAY_PATTERN_NODE: { yp_array_pattern_node_t *cast = (yp_array_pattern_node_t *) node; - VALUE argv[8]; + VALUE argv[7]; // constant - argv[0] = cast->constant == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->constant, encoding, constants); + argv[0] = cast->constant == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->constant, source, encoding, constants); // requireds argv[1] = rb_ary_new(); for (size_t index = 0; index < cast->requireds.size; index++) { - rb_ary_push(argv[1], yp_node_new(parser, cast->requireds.nodes[index], encoding, constants)); + rb_ary_push(argv[1], yp_node_new(parser, cast->requireds.nodes[index], source, encoding, constants)); } // rest - argv[2] = cast->rest == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->rest, encoding, constants); + argv[2] = cast->rest == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->rest, source, encoding, constants); // posts argv[3] = rb_ary_new(); for (size_t index = 0; index < cast->posts.size; index++) { - rb_ary_push(argv[3], yp_node_new(parser, cast->posts.nodes[index], encoding, constants)); + rb_ary_push(argv[3], yp_node_new(parser, cast->posts.nodes[index], source, encoding, constants)); } // opening_loc - argv[4] = cast->opening_loc.start == NULL ? Qnil : location_new(parser, cast->opening_loc.start, cast->opening_loc.end); + argv[4] = cast->opening_loc.start == NULL ? Qnil : location_new(parser, cast->opening_loc.start, cast->opening_loc.end, source); // closing_loc - argv[5] = cast->closing_loc.start == NULL ? Qnil : location_new(parser, cast->closing_loc.start, cast->closing_loc.end); + argv[5] = cast->closing_loc.start == NULL ? Qnil : location_new(parser, cast->closing_loc.start, cast->closing_loc.end, source); // location - argv[6] = LONG2FIX(node->location.start - parser->start); - argv[7] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(8, argv, rb_const_get_at(rb_cYARP, rb_intern("ArrayPatternNode"))); + argv[6] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(7, argv, rb_const_get_at(rb_cYARP, rb_intern("ArrayPatternNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_ASSOC_NODE: { yp_assoc_node_t *cast = (yp_assoc_node_t *) node; - VALUE argv[5]; + VALUE argv[4]; // key - argv[0] = yp_node_new(parser, (yp_node_t *) cast->key, encoding, constants); + argv[0] = yp_node_new(parser, (yp_node_t *) cast->key, source, encoding, constants); // value - argv[1] = cast->value == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->value, encoding, constants); + argv[1] = cast->value == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->value, source, encoding, constants); // operator_loc - argv[2] = cast->operator_loc.start == NULL ? Qnil : location_new(parser, cast->operator_loc.start, cast->operator_loc.end); + argv[2] = cast->operator_loc.start == NULL ? Qnil : location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source); // location - argv[3] = LONG2FIX(node->location.start - parser->start); - argv[4] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(5, argv, rb_const_get_at(rb_cYARP, rb_intern("AssocNode"))); + argv[3] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(4, argv, rb_const_get_at(rb_cYARP, rb_intern("AssocNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_ASSOC_SPLAT_NODE: { yp_assoc_splat_node_t *cast = (yp_assoc_splat_node_t *) node; - VALUE argv[4]; + VALUE argv[3]; // value - argv[0] = cast->value == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->value, encoding, constants); + argv[0] = cast->value == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->value, source, encoding, constants); // operator_loc - argv[1] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end); + argv[1] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source); // location - argv[2] = LONG2FIX(node->location.start - parser->start); - argv[3] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(4, argv, rb_const_get_at(rb_cYARP, rb_intern("AssocSplatNode"))); + argv[2] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(3, argv, rb_const_get_at(rb_cYARP, rb_intern("AssocSplatNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_BACK_REFERENCE_READ_NODE: { - VALUE argv[2]; + VALUE argv[1]; // location - argv[0] = LONG2FIX(node->location.start - parser->start); - argv[1] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(2, argv, rb_const_get_at(rb_cYARP, rb_intern("BackReferenceReadNode"))); + argv[0] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(1, argv, rb_const_get_at(rb_cYARP, rb_intern("BackReferenceReadNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_BEGIN_NODE: { yp_begin_node_t *cast = (yp_begin_node_t *) node; - VALUE argv[8]; + VALUE argv[7]; // begin_keyword_loc - argv[0] = cast->begin_keyword_loc.start == NULL ? Qnil : location_new(parser, cast->begin_keyword_loc.start, cast->begin_keyword_loc.end); + argv[0] = cast->begin_keyword_loc.start == NULL ? Qnil : location_new(parser, cast->begin_keyword_loc.start, cast->begin_keyword_loc.end, source); // statements - argv[1] = cast->statements == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->statements, encoding, constants); + argv[1] = cast->statements == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->statements, source, encoding, constants); // rescue_clause - argv[2] = cast->rescue_clause == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->rescue_clause, encoding, constants); + argv[2] = cast->rescue_clause == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->rescue_clause, source, encoding, constants); // else_clause - argv[3] = cast->else_clause == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->else_clause, encoding, constants); + argv[3] = cast->else_clause == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->else_clause, source, encoding, constants); // ensure_clause - argv[4] = cast->ensure_clause == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->ensure_clause, encoding, constants); + argv[4] = cast->ensure_clause == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->ensure_clause, source, encoding, constants); // end_keyword_loc - argv[5] = cast->end_keyword_loc.start == NULL ? Qnil : location_new(parser, cast->end_keyword_loc.start, cast->end_keyword_loc.end); + argv[5] = cast->end_keyword_loc.start == NULL ? Qnil : location_new(parser, cast->end_keyword_loc.start, cast->end_keyword_loc.end, source); // location - argv[6] = LONG2FIX(node->location.start - parser->start); - argv[7] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(8, argv, rb_const_get_at(rb_cYARP, rb_intern("BeginNode"))); + argv[6] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(7, argv, rb_const_get_at(rb_cYARP, rb_intern("BeginNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_BLOCK_ARGUMENT_NODE: { yp_block_argument_node_t *cast = (yp_block_argument_node_t *) node; - VALUE argv[4]; + VALUE argv[3]; // expression - argv[0] = cast->expression == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->expression, encoding, constants); + argv[0] = cast->expression == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->expression, source, encoding, constants); // operator_loc - argv[1] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end); + argv[1] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source); // location - argv[2] = LONG2FIX(node->location.start - parser->start); - argv[3] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(4, argv, rb_const_get_at(rb_cYARP, rb_intern("BlockArgumentNode"))); + argv[2] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(3, argv, rb_const_get_at(rb_cYARP, rb_intern("BlockArgumentNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_BLOCK_NODE: { yp_block_node_t *cast = (yp_block_node_t *) node; - VALUE argv[7]; + VALUE argv[6]; // locals argv[0] = rb_ary_new(); @@ -279,109 +245,101 @@ yp_node_new(yp_parser_t *parser, yp_node_t *node, rb_encoding *encoding, ID *con } // parameters - argv[1] = cast->parameters == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->parameters, encoding, constants); + argv[1] = cast->parameters == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->parameters, source, encoding, constants); // statements - argv[2] = cast->statements == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->statements, encoding, constants); + argv[2] = cast->statements == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->statements, source, encoding, constants); // opening_loc - argv[3] = location_new(parser, cast->opening_loc.start, cast->opening_loc.end); + argv[3] = location_new(parser, cast->opening_loc.start, cast->opening_loc.end, source); // closing_loc - argv[4] = location_new(parser, cast->closing_loc.start, cast->closing_loc.end); + argv[4] = location_new(parser, cast->closing_loc.start, cast->closing_loc.end, source); // location - argv[5] = LONG2FIX(node->location.start - parser->start); - argv[6] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(7, argv, rb_const_get_at(rb_cYARP, rb_intern("BlockNode"))); + argv[5] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(6, argv, rb_const_get_at(rb_cYARP, rb_intern("BlockNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_BLOCK_PARAMETER_NODE: { yp_block_parameter_node_t *cast = (yp_block_parameter_node_t *) node; - VALUE argv[4]; + VALUE argv[3]; // name_loc - argv[0] = cast->name_loc.start == NULL ? Qnil : location_new(parser, cast->name_loc.start, cast->name_loc.end); + argv[0] = cast->name_loc.start == NULL ? Qnil : location_new(parser, cast->name_loc.start, cast->name_loc.end, source); // operator_loc - argv[1] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end); + argv[1] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source); // location - argv[2] = LONG2FIX(node->location.start - parser->start); - argv[3] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(4, argv, rb_const_get_at(rb_cYARP, rb_intern("BlockParameterNode"))); + argv[2] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(3, argv, rb_const_get_at(rb_cYARP, rb_intern("BlockParameterNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_BLOCK_PARAMETERS_NODE: { yp_block_parameters_node_t *cast = (yp_block_parameters_node_t *) node; - VALUE argv[6]; + VALUE argv[5]; // parameters - argv[0] = cast->parameters == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->parameters, encoding, constants); + argv[0] = cast->parameters == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->parameters, source, encoding, constants); // locals argv[1] = rb_ary_new(); for (size_t index = 0; index < cast->locals.size; index++) { yp_location_t location = cast->locals.locations[index]; - rb_ary_push(argv[1], location_new(parser, location.start, location.end)); + rb_ary_push(argv[1], location_new(parser, location.start, location.end, source)); } // opening_loc - argv[2] = cast->opening_loc.start == NULL ? Qnil : location_new(parser, cast->opening_loc.start, cast->opening_loc.end); + argv[2] = cast->opening_loc.start == NULL ? Qnil : location_new(parser, cast->opening_loc.start, cast->opening_loc.end, source); // closing_loc - argv[3] = cast->closing_loc.start == NULL ? Qnil : location_new(parser, cast->closing_loc.start, cast->closing_loc.end); + argv[3] = cast->closing_loc.start == NULL ? Qnil : location_new(parser, cast->closing_loc.start, cast->closing_loc.end, source); // location - argv[4] = LONG2FIX(node->location.start - parser->start); - argv[5] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(6, argv, rb_const_get_at(rb_cYARP, rb_intern("BlockParametersNode"))); + argv[4] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(5, argv, rb_const_get_at(rb_cYARP, rb_intern("BlockParametersNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_BREAK_NODE: { yp_break_node_t *cast = (yp_break_node_t *) node; - VALUE argv[4]; + VALUE argv[3]; // arguments - argv[0] = cast->arguments == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->arguments, encoding, constants); + argv[0] = cast->arguments == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->arguments, source, encoding, constants); // keyword_loc - argv[1] = location_new(parser, cast->keyword_loc.start, cast->keyword_loc.end); + argv[1] = location_new(parser, cast->keyword_loc.start, cast->keyword_loc.end, source); // location - argv[2] = LONG2FIX(node->location.start - parser->start); - argv[3] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(4, argv, rb_const_get_at(rb_cYARP, rb_intern("BreakNode"))); + argv[2] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(3, argv, rb_const_get_at(rb_cYARP, rb_intern("BreakNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_CALL_NODE: { yp_call_node_t *cast = (yp_call_node_t *) node; - VALUE argv[11]; + VALUE argv[10]; // receiver - argv[0] = cast->receiver == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->receiver, encoding, constants); + argv[0] = cast->receiver == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->receiver, source, encoding, constants); // operator_loc - argv[1] = cast->operator_loc.start == NULL ? Qnil : location_new(parser, cast->operator_loc.start, cast->operator_loc.end); + argv[1] = cast->operator_loc.start == NULL ? Qnil : location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source); // message_loc - argv[2] = cast->message_loc.start == NULL ? Qnil : location_new(parser, cast->message_loc.start, cast->message_loc.end); + argv[2] = cast->message_loc.start == NULL ? Qnil : location_new(parser, cast->message_loc.start, cast->message_loc.end, source); // opening_loc - argv[3] = cast->opening_loc.start == NULL ? Qnil : location_new(parser, cast->opening_loc.start, cast->opening_loc.end); + argv[3] = cast->opening_loc.start == NULL ? Qnil : location_new(parser, cast->opening_loc.start, cast->opening_loc.end, source); // arguments - argv[4] = cast->arguments == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->arguments, encoding, constants); + argv[4] = cast->arguments == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->arguments, source, encoding, constants); // closing_loc - argv[5] = cast->closing_loc.start == NULL ? Qnil : location_new(parser, cast->closing_loc.start, cast->closing_loc.end); + argv[5] = cast->closing_loc.start == NULL ? Qnil : location_new(parser, cast->closing_loc.start, cast->closing_loc.end, source); // block - argv[6] = cast->block == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->block, encoding, constants); + argv[6] = cast->block == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->block, source, encoding, constants); // flags argv[7] = ULONG2NUM(cast->flags); @@ -390,127 +348,115 @@ yp_node_new(yp_parser_t *parser, yp_node_t *node, rb_encoding *encoding, ID *con argv[8] = yp_string_new(&cast->name, encoding); // location - argv[9] = LONG2FIX(node->location.start - parser->start); - argv[10] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(11, argv, rb_const_get_at(rb_cYARP, rb_intern("CallNode"))); + argv[9] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(10, argv, rb_const_get_at(rb_cYARP, rb_intern("CallNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_CALL_OPERATOR_AND_WRITE_NODE: { yp_call_operator_and_write_node_t *cast = (yp_call_operator_and_write_node_t *) node; - VALUE argv[5]; + VALUE argv[4]; // target - argv[0] = yp_node_new(parser, (yp_node_t *) cast->target, encoding, constants); + argv[0] = yp_node_new(parser, (yp_node_t *) cast->target, source, encoding, constants); // operator_loc - argv[1] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end); + argv[1] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source); // value - argv[2] = yp_node_new(parser, (yp_node_t *) cast->value, encoding, constants); + argv[2] = yp_node_new(parser, (yp_node_t *) cast->value, source, encoding, constants); // location - argv[3] = LONG2FIX(node->location.start - parser->start); - argv[4] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(5, argv, rb_const_get_at(rb_cYARP, rb_intern("CallOperatorAndWriteNode"))); + argv[3] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(4, argv, rb_const_get_at(rb_cYARP, rb_intern("CallOperatorAndWriteNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_CALL_OPERATOR_OR_WRITE_NODE: { yp_call_operator_or_write_node_t *cast = (yp_call_operator_or_write_node_t *) node; - VALUE argv[5]; + VALUE argv[4]; // target - argv[0] = yp_node_new(parser, (yp_node_t *) cast->target, encoding, constants); + argv[0] = yp_node_new(parser, (yp_node_t *) cast->target, source, encoding, constants); // value - argv[1] = yp_node_new(parser, (yp_node_t *) cast->value, encoding, constants); + argv[1] = yp_node_new(parser, (yp_node_t *) cast->value, source, encoding, constants); // operator_loc - argv[2] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end); + argv[2] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source); // location - argv[3] = LONG2FIX(node->location.start - parser->start); - argv[4] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(5, argv, rb_const_get_at(rb_cYARP, rb_intern("CallOperatorOrWriteNode"))); + argv[3] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(4, argv, rb_const_get_at(rb_cYARP, rb_intern("CallOperatorOrWriteNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_CALL_OPERATOR_WRITE_NODE: { yp_call_operator_write_node_t *cast = (yp_call_operator_write_node_t *) node; - VALUE argv[6]; + VALUE argv[5]; // target - argv[0] = yp_node_new(parser, (yp_node_t *) cast->target, encoding, constants); + argv[0] = yp_node_new(parser, (yp_node_t *) cast->target, source, encoding, constants); // operator_loc - argv[1] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end); + argv[1] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source); // value - argv[2] = yp_node_new(parser, (yp_node_t *) cast->value, encoding, constants); + argv[2] = yp_node_new(parser, (yp_node_t *) cast->value, source, encoding, constants); // operator_id argv[3] = rb_id2sym(constants[cast->operator_id - 1]); // location - argv[4] = LONG2FIX(node->location.start - parser->start); - argv[5] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(6, argv, rb_const_get_at(rb_cYARP, rb_intern("CallOperatorWriteNode"))); + argv[4] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(5, argv, rb_const_get_at(rb_cYARP, rb_intern("CallOperatorWriteNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_CAPTURE_PATTERN_NODE: { yp_capture_pattern_node_t *cast = (yp_capture_pattern_node_t *) node; - VALUE argv[5]; + VALUE argv[4]; // value - argv[0] = yp_node_new(parser, (yp_node_t *) cast->value, encoding, constants); + argv[0] = yp_node_new(parser, (yp_node_t *) cast->value, source, encoding, constants); // target - argv[1] = yp_node_new(parser, (yp_node_t *) cast->target, encoding, constants); + argv[1] = yp_node_new(parser, (yp_node_t *) cast->target, source, encoding, constants); // operator_loc - argv[2] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end); + argv[2] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source); // location - argv[3] = LONG2FIX(node->location.start - parser->start); - argv[4] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(5, argv, rb_const_get_at(rb_cYARP, rb_intern("CapturePatternNode"))); + argv[3] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(4, argv, rb_const_get_at(rb_cYARP, rb_intern("CapturePatternNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_CASE_NODE: { yp_case_node_t *cast = (yp_case_node_t *) node; - VALUE argv[7]; + VALUE argv[6]; // predicate - argv[0] = cast->predicate == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->predicate, encoding, constants); + argv[0] = cast->predicate == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->predicate, source, encoding, constants); // conditions argv[1] = rb_ary_new(); for (size_t index = 0; index < cast->conditions.size; index++) { - rb_ary_push(argv[1], yp_node_new(parser, cast->conditions.nodes[index], encoding, constants)); + rb_ary_push(argv[1], yp_node_new(parser, cast->conditions.nodes[index], source, encoding, constants)); } // consequent - argv[2] = cast->consequent == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->consequent, encoding, constants); + argv[2] = cast->consequent == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->consequent, source, encoding, constants); // case_keyword_loc - argv[3] = location_new(parser, cast->case_keyword_loc.start, cast->case_keyword_loc.end); + argv[3] = location_new(parser, cast->case_keyword_loc.start, cast->case_keyword_loc.end, source); // end_keyword_loc - argv[4] = location_new(parser, cast->end_keyword_loc.start, cast->end_keyword_loc.end); + argv[4] = location_new(parser, cast->end_keyword_loc.start, cast->end_keyword_loc.end, source); // location - argv[5] = LONG2FIX(node->location.start - parser->start); - argv[6] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(7, argv, rb_const_get_at(rb_cYARP, rb_intern("CaseNode"))); + argv[5] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(6, argv, rb_const_get_at(rb_cYARP, rb_intern("CaseNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_CLASS_NODE: { yp_class_node_t *cast = (yp_class_node_t *) node; - VALUE argv[9]; + VALUE argv[8]; // locals argv[0] = rb_ary_new(); @@ -519,314 +465,284 @@ yp_node_new(yp_parser_t *parser, yp_node_t *node, rb_encoding *encoding, ID *con } // class_keyword_loc - argv[1] = location_new(parser, cast->class_keyword_loc.start, cast->class_keyword_loc.end); + argv[1] = location_new(parser, cast->class_keyword_loc.start, cast->class_keyword_loc.end, source); // constant_path - argv[2] = yp_node_new(parser, (yp_node_t *) cast->constant_path, encoding, constants); + argv[2] = yp_node_new(parser, (yp_node_t *) cast->constant_path, source, encoding, constants); // inheritance_operator_loc - argv[3] = cast->inheritance_operator_loc.start == NULL ? Qnil : location_new(parser, cast->inheritance_operator_loc.start, cast->inheritance_operator_loc.end); + argv[3] = cast->inheritance_operator_loc.start == NULL ? Qnil : location_new(parser, cast->inheritance_operator_loc.start, cast->inheritance_operator_loc.end, source); // superclass - argv[4] = cast->superclass == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->superclass, encoding, constants); + argv[4] = cast->superclass == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->superclass, source, encoding, constants); // statements - argv[5] = cast->statements == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->statements, encoding, constants); + argv[5] = cast->statements == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->statements, source, encoding, constants); // end_keyword_loc - argv[6] = location_new(parser, cast->end_keyword_loc.start, cast->end_keyword_loc.end); + argv[6] = location_new(parser, cast->end_keyword_loc.start, cast->end_keyword_loc.end, source); // location - argv[7] = LONG2FIX(node->location.start - parser->start); - argv[8] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(9, argv, rb_const_get_at(rb_cYARP, rb_intern("ClassNode"))); + argv[7] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(8, argv, rb_const_get_at(rb_cYARP, rb_intern("ClassNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_CLASS_VARIABLE_OPERATOR_AND_WRITE_NODE: { yp_class_variable_operator_and_write_node_t *cast = (yp_class_variable_operator_and_write_node_t *) node; - VALUE argv[5]; + VALUE argv[4]; // name_loc - argv[0] = location_new(parser, cast->name_loc.start, cast->name_loc.end); + argv[0] = location_new(parser, cast->name_loc.start, cast->name_loc.end, source); // operator_loc - argv[1] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end); + argv[1] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source); // value - argv[2] = yp_node_new(parser, (yp_node_t *) cast->value, encoding, constants); + argv[2] = yp_node_new(parser, (yp_node_t *) cast->value, source, encoding, constants); // location - argv[3] = LONG2FIX(node->location.start - parser->start); - argv[4] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(5, argv, rb_const_get_at(rb_cYARP, rb_intern("ClassVariableOperatorAndWriteNode"))); + argv[3] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(4, argv, rb_const_get_at(rb_cYARP, rb_intern("ClassVariableOperatorAndWriteNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_CLASS_VARIABLE_OPERATOR_OR_WRITE_NODE: { yp_class_variable_operator_or_write_node_t *cast = (yp_class_variable_operator_or_write_node_t *) node; - VALUE argv[5]; + VALUE argv[4]; // name_loc - argv[0] = location_new(parser, cast->name_loc.start, cast->name_loc.end); + argv[0] = location_new(parser, cast->name_loc.start, cast->name_loc.end, source); // operator_loc - argv[1] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end); + argv[1] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source); // value - argv[2] = yp_node_new(parser, (yp_node_t *) cast->value, encoding, constants); + argv[2] = yp_node_new(parser, (yp_node_t *) cast->value, source, encoding, constants); // location - argv[3] = LONG2FIX(node->location.start - parser->start); - argv[4] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(5, argv, rb_const_get_at(rb_cYARP, rb_intern("ClassVariableOperatorOrWriteNode"))); + argv[3] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(4, argv, rb_const_get_at(rb_cYARP, rb_intern("ClassVariableOperatorOrWriteNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_CLASS_VARIABLE_OPERATOR_WRITE_NODE: { yp_class_variable_operator_write_node_t *cast = (yp_class_variable_operator_write_node_t *) node; - VALUE argv[6]; + VALUE argv[5]; // name_loc - argv[0] = location_new(parser, cast->name_loc.start, cast->name_loc.end); + argv[0] = location_new(parser, cast->name_loc.start, cast->name_loc.end, source); // operator_loc - argv[1] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end); + argv[1] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source); // value - argv[2] = yp_node_new(parser, (yp_node_t *) cast->value, encoding, constants); + argv[2] = yp_node_new(parser, (yp_node_t *) cast->value, source, encoding, constants); // operator argv[3] = rb_id2sym(constants[cast->operator - 1]); // location - argv[4] = LONG2FIX(node->location.start - parser->start); - argv[5] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(6, argv, rb_const_get_at(rb_cYARP, rb_intern("ClassVariableOperatorWriteNode"))); + argv[4] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(5, argv, rb_const_get_at(rb_cYARP, rb_intern("ClassVariableOperatorWriteNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_CLASS_VARIABLE_READ_NODE: { - VALUE argv[2]; + VALUE argv[1]; // location - argv[0] = LONG2FIX(node->location.start - parser->start); - argv[1] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(2, argv, rb_const_get_at(rb_cYARP, rb_intern("ClassVariableReadNode"))); + argv[0] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(1, argv, rb_const_get_at(rb_cYARP, rb_intern("ClassVariableReadNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_CLASS_VARIABLE_WRITE_NODE: { yp_class_variable_write_node_t *cast = (yp_class_variable_write_node_t *) node; - VALUE argv[5]; + VALUE argv[4]; // name_loc - argv[0] = location_new(parser, cast->name_loc.start, cast->name_loc.end); + argv[0] = location_new(parser, cast->name_loc.start, cast->name_loc.end, source); // value - argv[1] = cast->value == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->value, encoding, constants); + argv[1] = cast->value == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->value, source, encoding, constants); // operator_loc - argv[2] = cast->operator_loc.start == NULL ? Qnil : location_new(parser, cast->operator_loc.start, cast->operator_loc.end); + argv[2] = cast->operator_loc.start == NULL ? Qnil : location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source); // location - argv[3] = LONG2FIX(node->location.start - parser->start); - argv[4] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(5, argv, rb_const_get_at(rb_cYARP, rb_intern("ClassVariableWriteNode"))); + argv[3] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(4, argv, rb_const_get_at(rb_cYARP, rb_intern("ClassVariableWriteNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_CONSTANT_OPERATOR_AND_WRITE_NODE: { yp_constant_operator_and_write_node_t *cast = (yp_constant_operator_and_write_node_t *) node; - VALUE argv[5]; + VALUE argv[4]; // name_loc - argv[0] = location_new(parser, cast->name_loc.start, cast->name_loc.end); + argv[0] = location_new(parser, cast->name_loc.start, cast->name_loc.end, source); // operator_loc - argv[1] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end); + argv[1] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source); // value - argv[2] = yp_node_new(parser, (yp_node_t *) cast->value, encoding, constants); + argv[2] = yp_node_new(parser, (yp_node_t *) cast->value, source, encoding, constants); // location - argv[3] = LONG2FIX(node->location.start - parser->start); - argv[4] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(5, argv, rb_const_get_at(rb_cYARP, rb_intern("ConstantOperatorAndWriteNode"))); + argv[3] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(4, argv, rb_const_get_at(rb_cYARP, rb_intern("ConstantOperatorAndWriteNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_CONSTANT_OPERATOR_OR_WRITE_NODE: { yp_constant_operator_or_write_node_t *cast = (yp_constant_operator_or_write_node_t *) node; - VALUE argv[5]; + VALUE argv[4]; // name_loc - argv[0] = location_new(parser, cast->name_loc.start, cast->name_loc.end); + argv[0] = location_new(parser, cast->name_loc.start, cast->name_loc.end, source); // operator_loc - argv[1] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end); + argv[1] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source); // value - argv[2] = yp_node_new(parser, (yp_node_t *) cast->value, encoding, constants); + argv[2] = yp_node_new(parser, (yp_node_t *) cast->value, source, encoding, constants); // location - argv[3] = LONG2FIX(node->location.start - parser->start); - argv[4] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(5, argv, rb_const_get_at(rb_cYARP, rb_intern("ConstantOperatorOrWriteNode"))); + argv[3] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(4, argv, rb_const_get_at(rb_cYARP, rb_intern("ConstantOperatorOrWriteNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_CONSTANT_OPERATOR_WRITE_NODE: { yp_constant_operator_write_node_t *cast = (yp_constant_operator_write_node_t *) node; - VALUE argv[6]; + VALUE argv[5]; // name_loc - argv[0] = location_new(parser, cast->name_loc.start, cast->name_loc.end); + argv[0] = location_new(parser, cast->name_loc.start, cast->name_loc.end, source); // operator_loc - argv[1] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end); + argv[1] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source); // value - argv[2] = yp_node_new(parser, (yp_node_t *) cast->value, encoding, constants); + argv[2] = yp_node_new(parser, (yp_node_t *) cast->value, source, encoding, constants); // operator argv[3] = rb_id2sym(constants[cast->operator - 1]); // location - argv[4] = LONG2FIX(node->location.start - parser->start); - argv[5] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(6, argv, rb_const_get_at(rb_cYARP, rb_intern("ConstantOperatorWriteNode"))); + argv[4] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(5, argv, rb_const_get_at(rb_cYARP, rb_intern("ConstantOperatorWriteNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_CONSTANT_PATH_NODE: { yp_constant_path_node_t *cast = (yp_constant_path_node_t *) node; - VALUE argv[5]; + VALUE argv[4]; // parent - argv[0] = cast->parent == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->parent, encoding, constants); + argv[0] = cast->parent == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->parent, source, encoding, constants); // child - argv[1] = yp_node_new(parser, (yp_node_t *) cast->child, encoding, constants); + argv[1] = yp_node_new(parser, (yp_node_t *) cast->child, source, encoding, constants); // delimiter_loc - argv[2] = location_new(parser, cast->delimiter_loc.start, cast->delimiter_loc.end); + argv[2] = location_new(parser, cast->delimiter_loc.start, cast->delimiter_loc.end, source); // location - argv[3] = LONG2FIX(node->location.start - parser->start); - argv[4] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(5, argv, rb_const_get_at(rb_cYARP, rb_intern("ConstantPathNode"))); + argv[3] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(4, argv, rb_const_get_at(rb_cYARP, rb_intern("ConstantPathNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_CONSTANT_PATH_OPERATOR_AND_WRITE_NODE: { yp_constant_path_operator_and_write_node_t *cast = (yp_constant_path_operator_and_write_node_t *) node; - VALUE argv[5]; + VALUE argv[4]; // target - argv[0] = yp_node_new(parser, (yp_node_t *) cast->target, encoding, constants); + argv[0] = yp_node_new(parser, (yp_node_t *) cast->target, source, encoding, constants); // operator_loc - argv[1] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end); + argv[1] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source); // value - argv[2] = yp_node_new(parser, (yp_node_t *) cast->value, encoding, constants); + argv[2] = yp_node_new(parser, (yp_node_t *) cast->value, source, encoding, constants); // location - argv[3] = LONG2FIX(node->location.start - parser->start); - argv[4] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(5, argv, rb_const_get_at(rb_cYARP, rb_intern("ConstantPathOperatorAndWriteNode"))); + argv[3] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(4, argv, rb_const_get_at(rb_cYARP, rb_intern("ConstantPathOperatorAndWriteNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_CONSTANT_PATH_OPERATOR_OR_WRITE_NODE: { yp_constant_path_operator_or_write_node_t *cast = (yp_constant_path_operator_or_write_node_t *) node; - VALUE argv[5]; + VALUE argv[4]; // target - argv[0] = yp_node_new(parser, (yp_node_t *) cast->target, encoding, constants); + argv[0] = yp_node_new(parser, (yp_node_t *) cast->target, source, encoding, constants); // operator_loc - argv[1] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end); + argv[1] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source); // value - argv[2] = yp_node_new(parser, (yp_node_t *) cast->value, encoding, constants); + argv[2] = yp_node_new(parser, (yp_node_t *) cast->value, source, encoding, constants); // location - argv[3] = LONG2FIX(node->location.start - parser->start); - argv[4] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(5, argv, rb_const_get_at(rb_cYARP, rb_intern("ConstantPathOperatorOrWriteNode"))); + argv[3] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(4, argv, rb_const_get_at(rb_cYARP, rb_intern("ConstantPathOperatorOrWriteNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_CONSTANT_PATH_OPERATOR_WRITE_NODE: { yp_constant_path_operator_write_node_t *cast = (yp_constant_path_operator_write_node_t *) node; - VALUE argv[6]; + VALUE argv[5]; // target - argv[0] = yp_node_new(parser, (yp_node_t *) cast->target, encoding, constants); + argv[0] = yp_node_new(parser, (yp_node_t *) cast->target, source, encoding, constants); // operator_loc - argv[1] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end); + argv[1] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source); // value - argv[2] = yp_node_new(parser, (yp_node_t *) cast->value, encoding, constants); + argv[2] = yp_node_new(parser, (yp_node_t *) cast->value, source, encoding, constants); // operator argv[3] = rb_id2sym(constants[cast->operator - 1]); // location - argv[4] = LONG2FIX(node->location.start - parser->start); - argv[5] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(6, argv, rb_const_get_at(rb_cYARP, rb_intern("ConstantPathOperatorWriteNode"))); + argv[4] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(5, argv, rb_const_get_at(rb_cYARP, rb_intern("ConstantPathOperatorWriteNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_CONSTANT_PATH_WRITE_NODE: { yp_constant_path_write_node_t *cast = (yp_constant_path_write_node_t *) node; - VALUE argv[5]; + VALUE argv[4]; // target - argv[0] = yp_node_new(parser, (yp_node_t *) cast->target, encoding, constants); + argv[0] = yp_node_new(parser, (yp_node_t *) cast->target, source, encoding, constants); // operator_loc - argv[1] = cast->operator_loc.start == NULL ? Qnil : location_new(parser, cast->operator_loc.start, cast->operator_loc.end); + argv[1] = cast->operator_loc.start == NULL ? Qnil : location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source); // value - argv[2] = cast->value == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->value, encoding, constants); + argv[2] = cast->value == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->value, source, encoding, constants); // location - argv[3] = LONG2FIX(node->location.start - parser->start); - argv[4] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(5, argv, rb_const_get_at(rb_cYARP, rb_intern("ConstantPathWriteNode"))); + argv[3] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(4, argv, rb_const_get_at(rb_cYARP, rb_intern("ConstantPathWriteNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_CONSTANT_READ_NODE: { - VALUE argv[2]; + VALUE argv[1]; // location - argv[0] = LONG2FIX(node->location.start - parser->start); - argv[1] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(2, argv, rb_const_get_at(rb_cYARP, rb_intern("ConstantReadNode"))); + argv[0] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(1, argv, rb_const_get_at(rb_cYARP, rb_intern("ConstantReadNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_DEF_NODE: { yp_def_node_t *cast = (yp_def_node_t *) node; - VALUE argv[13]; + VALUE argv[12]; // name_loc - argv[0] = location_new(parser, cast->name_loc.start, cast->name_loc.end); + argv[0] = location_new(parser, cast->name_loc.start, cast->name_loc.end, source); // receiver - argv[1] = cast->receiver == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->receiver, encoding, constants); + argv[1] = cast->receiver == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->receiver, source, encoding, constants); // parameters - argv[2] = cast->parameters == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->parameters, encoding, constants); + argv[2] = cast->parameters == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->parameters, source, encoding, constants); // statements - argv[3] = cast->statements == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->statements, encoding, constants); + argv[3] = cast->statements == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->statements, source, encoding, constants); // locals argv[4] = rb_ary_new(); @@ -835,708 +751,636 @@ yp_node_new(yp_parser_t *parser, yp_node_t *node, rb_encoding *encoding, ID *con } // def_keyword_loc - argv[5] = location_new(parser, cast->def_keyword_loc.start, cast->def_keyword_loc.end); + argv[5] = location_new(parser, cast->def_keyword_loc.start, cast->def_keyword_loc.end, source); // operator_loc - argv[6] = cast->operator_loc.start == NULL ? Qnil : location_new(parser, cast->operator_loc.start, cast->operator_loc.end); + argv[6] = cast->operator_loc.start == NULL ? Qnil : location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source); // lparen_loc - argv[7] = cast->lparen_loc.start == NULL ? Qnil : location_new(parser, cast->lparen_loc.start, cast->lparen_loc.end); + argv[7] = cast->lparen_loc.start == NULL ? Qnil : location_new(parser, cast->lparen_loc.start, cast->lparen_loc.end, source); // rparen_loc - argv[8] = cast->rparen_loc.start == NULL ? Qnil : location_new(parser, cast->rparen_loc.start, cast->rparen_loc.end); + argv[8] = cast->rparen_loc.start == NULL ? Qnil : location_new(parser, cast->rparen_loc.start, cast->rparen_loc.end, source); // equal_loc - argv[9] = cast->equal_loc.start == NULL ? Qnil : location_new(parser, cast->equal_loc.start, cast->equal_loc.end); + argv[9] = cast->equal_loc.start == NULL ? Qnil : location_new(parser, cast->equal_loc.start, cast->equal_loc.end, source); // end_keyword_loc - argv[10] = cast->end_keyword_loc.start == NULL ? Qnil : location_new(parser, cast->end_keyword_loc.start, cast->end_keyword_loc.end); + argv[10] = cast->end_keyword_loc.start == NULL ? Qnil : location_new(parser, cast->end_keyword_loc.start, cast->end_keyword_loc.end, source); // location - argv[11] = LONG2FIX(node->location.start - parser->start); - argv[12] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(13, argv, rb_const_get_at(rb_cYARP, rb_intern("DefNode"))); + argv[11] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(12, argv, rb_const_get_at(rb_cYARP, rb_intern("DefNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_DEFINED_NODE: { yp_defined_node_t *cast = (yp_defined_node_t *) node; - VALUE argv[6]; + VALUE argv[5]; // lparen_loc - argv[0] = cast->lparen_loc.start == NULL ? Qnil : location_new(parser, cast->lparen_loc.start, cast->lparen_loc.end); + argv[0] = cast->lparen_loc.start == NULL ? Qnil : location_new(parser, cast->lparen_loc.start, cast->lparen_loc.end, source); // value - argv[1] = yp_node_new(parser, (yp_node_t *) cast->value, encoding, constants); + argv[1] = yp_node_new(parser, (yp_node_t *) cast->value, source, encoding, constants); // rparen_loc - argv[2] = cast->rparen_loc.start == NULL ? Qnil : location_new(parser, cast->rparen_loc.start, cast->rparen_loc.end); + argv[2] = cast->rparen_loc.start == NULL ? Qnil : location_new(parser, cast->rparen_loc.start, cast->rparen_loc.end, source); // keyword_loc - argv[3] = location_new(parser, cast->keyword_loc.start, cast->keyword_loc.end); + argv[3] = location_new(parser, cast->keyword_loc.start, cast->keyword_loc.end, source); // location - argv[4] = LONG2FIX(node->location.start - parser->start); - argv[5] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(6, argv, rb_const_get_at(rb_cYARP, rb_intern("DefinedNode"))); + argv[4] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(5, argv, rb_const_get_at(rb_cYARP, rb_intern("DefinedNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_ELSE_NODE: { yp_else_node_t *cast = (yp_else_node_t *) node; - VALUE argv[5]; + VALUE argv[4]; // else_keyword_loc - argv[0] = location_new(parser, cast->else_keyword_loc.start, cast->else_keyword_loc.end); + argv[0] = location_new(parser, cast->else_keyword_loc.start, cast->else_keyword_loc.end, source); // statements - argv[1] = cast->statements == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->statements, encoding, constants); + argv[1] = cast->statements == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->statements, source, encoding, constants); // end_keyword_loc - argv[2] = cast->end_keyword_loc.start == NULL ? Qnil : location_new(parser, cast->end_keyword_loc.start, cast->end_keyword_loc.end); + argv[2] = cast->end_keyword_loc.start == NULL ? Qnil : location_new(parser, cast->end_keyword_loc.start, cast->end_keyword_loc.end, source); // location - argv[3] = LONG2FIX(node->location.start - parser->start); - argv[4] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(5, argv, rb_const_get_at(rb_cYARP, rb_intern("ElseNode"))); + argv[3] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(4, argv, rb_const_get_at(rb_cYARP, rb_intern("ElseNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_EMBEDDED_STATEMENTS_NODE: { yp_embedded_statements_node_t *cast = (yp_embedded_statements_node_t *) node; - VALUE argv[5]; + VALUE argv[4]; // opening_loc - argv[0] = location_new(parser, cast->opening_loc.start, cast->opening_loc.end); + argv[0] = location_new(parser, cast->opening_loc.start, cast->opening_loc.end, source); // statements - argv[1] = cast->statements == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->statements, encoding, constants); + argv[1] = cast->statements == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->statements, source, encoding, constants); // closing_loc - argv[2] = location_new(parser, cast->closing_loc.start, cast->closing_loc.end); + argv[2] = location_new(parser, cast->closing_loc.start, cast->closing_loc.end, source); // location - argv[3] = LONG2FIX(node->location.start - parser->start); - argv[4] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(5, argv, rb_const_get_at(rb_cYARP, rb_intern("EmbeddedStatementsNode"))); + argv[3] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(4, argv, rb_const_get_at(rb_cYARP, rb_intern("EmbeddedStatementsNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_EMBEDDED_VARIABLE_NODE: { yp_embedded_variable_node_t *cast = (yp_embedded_variable_node_t *) node; - VALUE argv[4]; + VALUE argv[3]; // operator_loc - argv[0] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end); + argv[0] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source); // variable - argv[1] = yp_node_new(parser, (yp_node_t *) cast->variable, encoding, constants); + argv[1] = yp_node_new(parser, (yp_node_t *) cast->variable, source, encoding, constants); // location - argv[2] = LONG2FIX(node->location.start - parser->start); - argv[3] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(4, argv, rb_const_get_at(rb_cYARP, rb_intern("EmbeddedVariableNode"))); + argv[2] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(3, argv, rb_const_get_at(rb_cYARP, rb_intern("EmbeddedVariableNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_ENSURE_NODE: { yp_ensure_node_t *cast = (yp_ensure_node_t *) node; - VALUE argv[5]; + VALUE argv[4]; // ensure_keyword_loc - argv[0] = location_new(parser, cast->ensure_keyword_loc.start, cast->ensure_keyword_loc.end); + argv[0] = location_new(parser, cast->ensure_keyword_loc.start, cast->ensure_keyword_loc.end, source); // statements - argv[1] = cast->statements == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->statements, encoding, constants); + argv[1] = cast->statements == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->statements, source, encoding, constants); // end_keyword_loc - argv[2] = location_new(parser, cast->end_keyword_loc.start, cast->end_keyword_loc.end); + argv[2] = location_new(parser, cast->end_keyword_loc.start, cast->end_keyword_loc.end, source); // location - argv[3] = LONG2FIX(node->location.start - parser->start); - argv[4] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(5, argv, rb_const_get_at(rb_cYARP, rb_intern("EnsureNode"))); + argv[3] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(4, argv, rb_const_get_at(rb_cYARP, rb_intern("EnsureNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_FALSE_NODE: { - VALUE argv[2]; + VALUE argv[1]; // location - argv[0] = LONG2FIX(node->location.start - parser->start); - argv[1] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(2, argv, rb_const_get_at(rb_cYARP, rb_intern("FalseNode"))); + argv[0] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(1, argv, rb_const_get_at(rb_cYARP, rb_intern("FalseNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_FIND_PATTERN_NODE: { yp_find_pattern_node_t *cast = (yp_find_pattern_node_t *) node; - VALUE argv[8]; + VALUE argv[7]; // constant - argv[0] = cast->constant == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->constant, encoding, constants); + argv[0] = cast->constant == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->constant, source, encoding, constants); // left - argv[1] = yp_node_new(parser, (yp_node_t *) cast->left, encoding, constants); + argv[1] = yp_node_new(parser, (yp_node_t *) cast->left, source, encoding, constants); // requireds argv[2] = rb_ary_new(); for (size_t index = 0; index < cast->requireds.size; index++) { - rb_ary_push(argv[2], yp_node_new(parser, cast->requireds.nodes[index], encoding, constants)); + rb_ary_push(argv[2], yp_node_new(parser, cast->requireds.nodes[index], source, encoding, constants)); } // right - argv[3] = yp_node_new(parser, (yp_node_t *) cast->right, encoding, constants); + argv[3] = yp_node_new(parser, (yp_node_t *) cast->right, source, encoding, constants); // opening_loc - argv[4] = cast->opening_loc.start == NULL ? Qnil : location_new(parser, cast->opening_loc.start, cast->opening_loc.end); + argv[4] = cast->opening_loc.start == NULL ? Qnil : location_new(parser, cast->opening_loc.start, cast->opening_loc.end, source); // closing_loc - argv[5] = cast->closing_loc.start == NULL ? Qnil : location_new(parser, cast->closing_loc.start, cast->closing_loc.end); + argv[5] = cast->closing_loc.start == NULL ? Qnil : location_new(parser, cast->closing_loc.start, cast->closing_loc.end, source); // location - argv[6] = LONG2FIX(node->location.start - parser->start); - argv[7] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(8, argv, rb_const_get_at(rb_cYARP, rb_intern("FindPatternNode"))); + argv[6] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(7, argv, rb_const_get_at(rb_cYARP, rb_intern("FindPatternNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_FLOAT_NODE: { - VALUE argv[2]; + VALUE argv[1]; // location - argv[0] = LONG2FIX(node->location.start - parser->start); - argv[1] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(2, argv, rb_const_get_at(rb_cYARP, rb_intern("FloatNode"))); + argv[0] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(1, argv, rb_const_get_at(rb_cYARP, rb_intern("FloatNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_FOR_NODE: { yp_for_node_t *cast = (yp_for_node_t *) node; - VALUE argv[9]; + VALUE argv[8]; // index - argv[0] = yp_node_new(parser, (yp_node_t *) cast->index, encoding, constants); + argv[0] = yp_node_new(parser, (yp_node_t *) cast->index, source, encoding, constants); // collection - argv[1] = yp_node_new(parser, (yp_node_t *) cast->collection, encoding, constants); + argv[1] = yp_node_new(parser, (yp_node_t *) cast->collection, source, encoding, constants); // statements - argv[2] = cast->statements == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->statements, encoding, constants); + argv[2] = cast->statements == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->statements, source, encoding, constants); // for_keyword_loc - argv[3] = location_new(parser, cast->for_keyword_loc.start, cast->for_keyword_loc.end); + argv[3] = location_new(parser, cast->for_keyword_loc.start, cast->for_keyword_loc.end, source); // in_keyword_loc - argv[4] = location_new(parser, cast->in_keyword_loc.start, cast->in_keyword_loc.end); + argv[4] = location_new(parser, cast->in_keyword_loc.start, cast->in_keyword_loc.end, source); // do_keyword_loc - argv[5] = cast->do_keyword_loc.start == NULL ? Qnil : location_new(parser, cast->do_keyword_loc.start, cast->do_keyword_loc.end); + argv[5] = cast->do_keyword_loc.start == NULL ? Qnil : location_new(parser, cast->do_keyword_loc.start, cast->do_keyword_loc.end, source); // end_keyword_loc - argv[6] = location_new(parser, cast->end_keyword_loc.start, cast->end_keyword_loc.end); + argv[6] = location_new(parser, cast->end_keyword_loc.start, cast->end_keyword_loc.end, source); // location - argv[7] = LONG2FIX(node->location.start - parser->start); - argv[8] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(9, argv, rb_const_get_at(rb_cYARP, rb_intern("ForNode"))); + argv[7] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(8, argv, rb_const_get_at(rb_cYARP, rb_intern("ForNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_FORWARDING_ARGUMENTS_NODE: { - VALUE argv[2]; + VALUE argv[1]; // location - argv[0] = LONG2FIX(node->location.start - parser->start); - argv[1] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(2, argv, rb_const_get_at(rb_cYARP, rb_intern("ForwardingArgumentsNode"))); + argv[0] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(1, argv, rb_const_get_at(rb_cYARP, rb_intern("ForwardingArgumentsNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_FORWARDING_PARAMETER_NODE: { - VALUE argv[2]; + VALUE argv[1]; // location - argv[0] = LONG2FIX(node->location.start - parser->start); - argv[1] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(2, argv, rb_const_get_at(rb_cYARP, rb_intern("ForwardingParameterNode"))); + argv[0] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(1, argv, rb_const_get_at(rb_cYARP, rb_intern("ForwardingParameterNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_FORWARDING_SUPER_NODE: { yp_forwarding_super_node_t *cast = (yp_forwarding_super_node_t *) node; - VALUE argv[3]; + VALUE argv[2]; // block - argv[0] = cast->block == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->block, encoding, constants); + argv[0] = cast->block == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->block, source, encoding, constants); // location - argv[1] = LONG2FIX(node->location.start - parser->start); - argv[2] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(3, argv, rb_const_get_at(rb_cYARP, rb_intern("ForwardingSuperNode"))); + argv[1] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(2, argv, rb_const_get_at(rb_cYARP, rb_intern("ForwardingSuperNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_GLOBAL_VARIABLE_OPERATOR_AND_WRITE_NODE: { yp_global_variable_operator_and_write_node_t *cast = (yp_global_variable_operator_and_write_node_t *) node; - VALUE argv[5]; + VALUE argv[4]; // name_loc - argv[0] = location_new(parser, cast->name_loc.start, cast->name_loc.end); + argv[0] = location_new(parser, cast->name_loc.start, cast->name_loc.end, source); // operator_loc - argv[1] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end); + argv[1] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source); // value - argv[2] = yp_node_new(parser, (yp_node_t *) cast->value, encoding, constants); + argv[2] = yp_node_new(parser, (yp_node_t *) cast->value, source, encoding, constants); // location - argv[3] = LONG2FIX(node->location.start - parser->start); - argv[4] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(5, argv, rb_const_get_at(rb_cYARP, rb_intern("GlobalVariableOperatorAndWriteNode"))); + argv[3] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(4, argv, rb_const_get_at(rb_cYARP, rb_intern("GlobalVariableOperatorAndWriteNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_GLOBAL_VARIABLE_OPERATOR_OR_WRITE_NODE: { yp_global_variable_operator_or_write_node_t *cast = (yp_global_variable_operator_or_write_node_t *) node; - VALUE argv[5]; + VALUE argv[4]; // name_loc - argv[0] = location_new(parser, cast->name_loc.start, cast->name_loc.end); + argv[0] = location_new(parser, cast->name_loc.start, cast->name_loc.end, source); // operator_loc - argv[1] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end); + argv[1] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source); // value - argv[2] = yp_node_new(parser, (yp_node_t *) cast->value, encoding, constants); + argv[2] = yp_node_new(parser, (yp_node_t *) cast->value, source, encoding, constants); // location - argv[3] = LONG2FIX(node->location.start - parser->start); - argv[4] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(5, argv, rb_const_get_at(rb_cYARP, rb_intern("GlobalVariableOperatorOrWriteNode"))); + argv[3] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(4, argv, rb_const_get_at(rb_cYARP, rb_intern("GlobalVariableOperatorOrWriteNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_GLOBAL_VARIABLE_OPERATOR_WRITE_NODE: { yp_global_variable_operator_write_node_t *cast = (yp_global_variable_operator_write_node_t *) node; - VALUE argv[6]; + VALUE argv[5]; // name_loc - argv[0] = location_new(parser, cast->name_loc.start, cast->name_loc.end); + argv[0] = location_new(parser, cast->name_loc.start, cast->name_loc.end, source); // operator_loc - argv[1] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end); + argv[1] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source); // value - argv[2] = yp_node_new(parser, (yp_node_t *) cast->value, encoding, constants); + argv[2] = yp_node_new(parser, (yp_node_t *) cast->value, source, encoding, constants); // operator argv[3] = rb_id2sym(constants[cast->operator - 1]); // location - argv[4] = LONG2FIX(node->location.start - parser->start); - argv[5] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(6, argv, rb_const_get_at(rb_cYARP, rb_intern("GlobalVariableOperatorWriteNode"))); + argv[4] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(5, argv, rb_const_get_at(rb_cYARP, rb_intern("GlobalVariableOperatorWriteNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_GLOBAL_VARIABLE_READ_NODE: { - VALUE argv[2]; + VALUE argv[1]; // location - argv[0] = LONG2FIX(node->location.start - parser->start); - argv[1] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(2, argv, rb_const_get_at(rb_cYARP, rb_intern("GlobalVariableReadNode"))); + argv[0] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(1, argv, rb_const_get_at(rb_cYARP, rb_intern("GlobalVariableReadNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_GLOBAL_VARIABLE_WRITE_NODE: { yp_global_variable_write_node_t *cast = (yp_global_variable_write_node_t *) node; - VALUE argv[5]; + VALUE argv[4]; // name_loc - argv[0] = location_new(parser, cast->name_loc.start, cast->name_loc.end); + argv[0] = location_new(parser, cast->name_loc.start, cast->name_loc.end, source); // operator_loc - argv[1] = cast->operator_loc.start == NULL ? Qnil : location_new(parser, cast->operator_loc.start, cast->operator_loc.end); + argv[1] = cast->operator_loc.start == NULL ? Qnil : location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source); // value - argv[2] = cast->value == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->value, encoding, constants); + argv[2] = cast->value == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->value, source, encoding, constants); // location - argv[3] = LONG2FIX(node->location.start - parser->start); - argv[4] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(5, argv, rb_const_get_at(rb_cYARP, rb_intern("GlobalVariableWriteNode"))); + argv[3] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(4, argv, rb_const_get_at(rb_cYARP, rb_intern("GlobalVariableWriteNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_HASH_NODE: { yp_hash_node_t *cast = (yp_hash_node_t *) node; - VALUE argv[5]; + VALUE argv[4]; // opening_loc - argv[0] = location_new(parser, cast->opening_loc.start, cast->opening_loc.end); + argv[0] = location_new(parser, cast->opening_loc.start, cast->opening_loc.end, source); // elements argv[1] = rb_ary_new(); for (size_t index = 0; index < cast->elements.size; index++) { - rb_ary_push(argv[1], yp_node_new(parser, cast->elements.nodes[index], encoding, constants)); + rb_ary_push(argv[1], yp_node_new(parser, cast->elements.nodes[index], source, encoding, constants)); } // closing_loc - argv[2] = location_new(parser, cast->closing_loc.start, cast->closing_loc.end); + argv[2] = location_new(parser, cast->closing_loc.start, cast->closing_loc.end, source); // location - argv[3] = LONG2FIX(node->location.start - parser->start); - argv[4] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(5, argv, rb_const_get_at(rb_cYARP, rb_intern("HashNode"))); + argv[3] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(4, argv, rb_const_get_at(rb_cYARP, rb_intern("HashNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_HASH_PATTERN_NODE: { yp_hash_pattern_node_t *cast = (yp_hash_pattern_node_t *) node; - VALUE argv[7]; + VALUE argv[6]; // constant - argv[0] = cast->constant == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->constant, encoding, constants); + argv[0] = cast->constant == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->constant, source, encoding, constants); // assocs argv[1] = rb_ary_new(); for (size_t index = 0; index < cast->assocs.size; index++) { - rb_ary_push(argv[1], yp_node_new(parser, cast->assocs.nodes[index], encoding, constants)); + rb_ary_push(argv[1], yp_node_new(parser, cast->assocs.nodes[index], source, encoding, constants)); } // kwrest - argv[2] = cast->kwrest == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->kwrest, encoding, constants); + argv[2] = cast->kwrest == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->kwrest, source, encoding, constants); // opening_loc - argv[3] = cast->opening_loc.start == NULL ? Qnil : location_new(parser, cast->opening_loc.start, cast->opening_loc.end); + argv[3] = cast->opening_loc.start == NULL ? Qnil : location_new(parser, cast->opening_loc.start, cast->opening_loc.end, source); // closing_loc - argv[4] = cast->closing_loc.start == NULL ? Qnil : location_new(parser, cast->closing_loc.start, cast->closing_loc.end); + argv[4] = cast->closing_loc.start == NULL ? Qnil : location_new(parser, cast->closing_loc.start, cast->closing_loc.end, source); // location - argv[5] = LONG2FIX(node->location.start - parser->start); - argv[6] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(7, argv, rb_const_get_at(rb_cYARP, rb_intern("HashPatternNode"))); + argv[5] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(6, argv, rb_const_get_at(rb_cYARP, rb_intern("HashPatternNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_IF_NODE: { yp_if_node_t *cast = (yp_if_node_t *) node; - VALUE argv[7]; + VALUE argv[6]; // if_keyword_loc - argv[0] = cast->if_keyword_loc.start == NULL ? Qnil : location_new(parser, cast->if_keyword_loc.start, cast->if_keyword_loc.end); + argv[0] = cast->if_keyword_loc.start == NULL ? Qnil : location_new(parser, cast->if_keyword_loc.start, cast->if_keyword_loc.end, source); // predicate - argv[1] = yp_node_new(parser, (yp_node_t *) cast->predicate, encoding, constants); + argv[1] = yp_node_new(parser, (yp_node_t *) cast->predicate, source, encoding, constants); // statements - argv[2] = cast->statements == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->statements, encoding, constants); + argv[2] = cast->statements == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->statements, source, encoding, constants); // consequent - argv[3] = cast->consequent == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->consequent, encoding, constants); + argv[3] = cast->consequent == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->consequent, source, encoding, constants); // end_keyword_loc - argv[4] = cast->end_keyword_loc.start == NULL ? Qnil : location_new(parser, cast->end_keyword_loc.start, cast->end_keyword_loc.end); + argv[4] = cast->end_keyword_loc.start == NULL ? Qnil : location_new(parser, cast->end_keyword_loc.start, cast->end_keyword_loc.end, source); // location - argv[5] = LONG2FIX(node->location.start - parser->start); - argv[6] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(7, argv, rb_const_get_at(rb_cYARP, rb_intern("IfNode"))); + argv[5] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(6, argv, rb_const_get_at(rb_cYARP, rb_intern("IfNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_IMAGINARY_NODE: { yp_imaginary_node_t *cast = (yp_imaginary_node_t *) node; - VALUE argv[3]; + VALUE argv[2]; // numeric - argv[0] = yp_node_new(parser, (yp_node_t *) cast->numeric, encoding, constants); + argv[0] = yp_node_new(parser, (yp_node_t *) cast->numeric, source, encoding, constants); // location - argv[1] = LONG2FIX(node->location.start - parser->start); - argv[2] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(3, argv, rb_const_get_at(rb_cYARP, rb_intern("ImaginaryNode"))); + argv[1] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(2, argv, rb_const_get_at(rb_cYARP, rb_intern("ImaginaryNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_IN_NODE: { yp_in_node_t *cast = (yp_in_node_t *) node; - VALUE argv[6]; + VALUE argv[5]; // pattern - argv[0] = yp_node_new(parser, (yp_node_t *) cast->pattern, encoding, constants); + argv[0] = yp_node_new(parser, (yp_node_t *) cast->pattern, source, encoding, constants); // statements - argv[1] = cast->statements == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->statements, encoding, constants); + argv[1] = cast->statements == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->statements, source, encoding, constants); // in_loc - argv[2] = location_new(parser, cast->in_loc.start, cast->in_loc.end); + argv[2] = location_new(parser, cast->in_loc.start, cast->in_loc.end, source); // then_loc - argv[3] = cast->then_loc.start == NULL ? Qnil : location_new(parser, cast->then_loc.start, cast->then_loc.end); + argv[3] = cast->then_loc.start == NULL ? Qnil : location_new(parser, cast->then_loc.start, cast->then_loc.end, source); // location - argv[4] = LONG2FIX(node->location.start - parser->start); - argv[5] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(6, argv, rb_const_get_at(rb_cYARP, rb_intern("InNode"))); + argv[4] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(5, argv, rb_const_get_at(rb_cYARP, rb_intern("InNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_INSTANCE_VARIABLE_OPERATOR_AND_WRITE_NODE: { yp_instance_variable_operator_and_write_node_t *cast = (yp_instance_variable_operator_and_write_node_t *) node; - VALUE argv[5]; + VALUE argv[4]; // name_loc - argv[0] = location_new(parser, cast->name_loc.start, cast->name_loc.end); + argv[0] = location_new(parser, cast->name_loc.start, cast->name_loc.end, source); // operator_loc - argv[1] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end); + argv[1] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source); // value - argv[2] = yp_node_new(parser, (yp_node_t *) cast->value, encoding, constants); + argv[2] = yp_node_new(parser, (yp_node_t *) cast->value, source, encoding, constants); // location - argv[3] = LONG2FIX(node->location.start - parser->start); - argv[4] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(5, argv, rb_const_get_at(rb_cYARP, rb_intern("InstanceVariableOperatorAndWriteNode"))); + argv[3] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(4, argv, rb_const_get_at(rb_cYARP, rb_intern("InstanceVariableOperatorAndWriteNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_INSTANCE_VARIABLE_OPERATOR_OR_WRITE_NODE: { yp_instance_variable_operator_or_write_node_t *cast = (yp_instance_variable_operator_or_write_node_t *) node; - VALUE argv[5]; + VALUE argv[4]; // name_loc - argv[0] = location_new(parser, cast->name_loc.start, cast->name_loc.end); + argv[0] = location_new(parser, cast->name_loc.start, cast->name_loc.end, source); // operator_loc - argv[1] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end); + argv[1] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source); // value - argv[2] = yp_node_new(parser, (yp_node_t *) cast->value, encoding, constants); + argv[2] = yp_node_new(parser, (yp_node_t *) cast->value, source, encoding, constants); // location - argv[3] = LONG2FIX(node->location.start - parser->start); - argv[4] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(5, argv, rb_const_get_at(rb_cYARP, rb_intern("InstanceVariableOperatorOrWriteNode"))); + argv[3] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(4, argv, rb_const_get_at(rb_cYARP, rb_intern("InstanceVariableOperatorOrWriteNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_INSTANCE_VARIABLE_OPERATOR_WRITE_NODE: { yp_instance_variable_operator_write_node_t *cast = (yp_instance_variable_operator_write_node_t *) node; - VALUE argv[6]; + VALUE argv[5]; // name_loc - argv[0] = location_new(parser, cast->name_loc.start, cast->name_loc.end); + argv[0] = location_new(parser, cast->name_loc.start, cast->name_loc.end, source); // operator_loc - argv[1] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end); + argv[1] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source); // value - argv[2] = yp_node_new(parser, (yp_node_t *) cast->value, encoding, constants); + argv[2] = yp_node_new(parser, (yp_node_t *) cast->value, source, encoding, constants); // operator argv[3] = rb_id2sym(constants[cast->operator - 1]); // location - argv[4] = LONG2FIX(node->location.start - parser->start); - argv[5] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(6, argv, rb_const_get_at(rb_cYARP, rb_intern("InstanceVariableOperatorWriteNode"))); + argv[4] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(5, argv, rb_const_get_at(rb_cYARP, rb_intern("InstanceVariableOperatorWriteNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_INSTANCE_VARIABLE_READ_NODE: { - VALUE argv[2]; + VALUE argv[1]; // location - argv[0] = LONG2FIX(node->location.start - parser->start); - argv[1] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(2, argv, rb_const_get_at(rb_cYARP, rb_intern("InstanceVariableReadNode"))); + argv[0] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(1, argv, rb_const_get_at(rb_cYARP, rb_intern("InstanceVariableReadNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_INSTANCE_VARIABLE_WRITE_NODE: { yp_instance_variable_write_node_t *cast = (yp_instance_variable_write_node_t *) node; - VALUE argv[5]; + VALUE argv[4]; // name_loc - argv[0] = location_new(parser, cast->name_loc.start, cast->name_loc.end); + argv[0] = location_new(parser, cast->name_loc.start, cast->name_loc.end, source); // value - argv[1] = cast->value == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->value, encoding, constants); + argv[1] = cast->value == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->value, source, encoding, constants); // operator_loc - argv[2] = cast->operator_loc.start == NULL ? Qnil : location_new(parser, cast->operator_loc.start, cast->operator_loc.end); + argv[2] = cast->operator_loc.start == NULL ? Qnil : location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source); // location - argv[3] = LONG2FIX(node->location.start - parser->start); - argv[4] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(5, argv, rb_const_get_at(rb_cYARP, rb_intern("InstanceVariableWriteNode"))); + argv[3] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(4, argv, rb_const_get_at(rb_cYARP, rb_intern("InstanceVariableWriteNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_INTEGER_NODE: { - VALUE argv[2]; + VALUE argv[1]; // location - argv[0] = LONG2FIX(node->location.start - parser->start); - argv[1] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(2, argv, rb_const_get_at(rb_cYARP, rb_intern("IntegerNode"))); + argv[0] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(1, argv, rb_const_get_at(rb_cYARP, rb_intern("IntegerNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_INTERPOLATED_REGULAR_EXPRESSION_NODE: { yp_interpolated_regular_expression_node_t *cast = (yp_interpolated_regular_expression_node_t *) node; - VALUE argv[6]; + VALUE argv[5]; // opening_loc - argv[0] = location_new(parser, cast->opening_loc.start, cast->opening_loc.end); + argv[0] = location_new(parser, cast->opening_loc.start, cast->opening_loc.end, source); // parts argv[1] = rb_ary_new(); for (size_t index = 0; index < cast->parts.size; index++) { - rb_ary_push(argv[1], yp_node_new(parser, cast->parts.nodes[index], encoding, constants)); + rb_ary_push(argv[1], yp_node_new(parser, cast->parts.nodes[index], source, encoding, constants)); } // closing_loc - argv[2] = location_new(parser, cast->closing_loc.start, cast->closing_loc.end); + argv[2] = location_new(parser, cast->closing_loc.start, cast->closing_loc.end, source); // flags argv[3] = ULONG2NUM(cast->flags); // location - argv[4] = LONG2FIX(node->location.start - parser->start); - argv[5] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(6, argv, rb_const_get_at(rb_cYARP, rb_intern("InterpolatedRegularExpressionNode"))); + argv[4] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(5, argv, rb_const_get_at(rb_cYARP, rb_intern("InterpolatedRegularExpressionNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_INTERPOLATED_STRING_NODE: { yp_interpolated_string_node_t *cast = (yp_interpolated_string_node_t *) node; - VALUE argv[5]; + VALUE argv[4]; // opening_loc - argv[0] = cast->opening_loc.start == NULL ? Qnil : location_new(parser, cast->opening_loc.start, cast->opening_loc.end); + argv[0] = cast->opening_loc.start == NULL ? Qnil : location_new(parser, cast->opening_loc.start, cast->opening_loc.end, source); // parts argv[1] = rb_ary_new(); for (size_t index = 0; index < cast->parts.size; index++) { - rb_ary_push(argv[1], yp_node_new(parser, cast->parts.nodes[index], encoding, constants)); + rb_ary_push(argv[1], yp_node_new(parser, cast->parts.nodes[index], source, encoding, constants)); } // closing_loc - argv[2] = cast->closing_loc.start == NULL ? Qnil : location_new(parser, cast->closing_loc.start, cast->closing_loc.end); + argv[2] = cast->closing_loc.start == NULL ? Qnil : location_new(parser, cast->closing_loc.start, cast->closing_loc.end, source); // location - argv[3] = LONG2FIX(node->location.start - parser->start); - argv[4] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(5, argv, rb_const_get_at(rb_cYARP, rb_intern("InterpolatedStringNode"))); + argv[3] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(4, argv, rb_const_get_at(rb_cYARP, rb_intern("InterpolatedStringNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_INTERPOLATED_SYMBOL_NODE: { yp_interpolated_symbol_node_t *cast = (yp_interpolated_symbol_node_t *) node; - VALUE argv[5]; + VALUE argv[4]; // opening_loc - argv[0] = cast->opening_loc.start == NULL ? Qnil : location_new(parser, cast->opening_loc.start, cast->opening_loc.end); + argv[0] = cast->opening_loc.start == NULL ? Qnil : location_new(parser, cast->opening_loc.start, cast->opening_loc.end, source); // parts argv[1] = rb_ary_new(); for (size_t index = 0; index < cast->parts.size; index++) { - rb_ary_push(argv[1], yp_node_new(parser, cast->parts.nodes[index], encoding, constants)); + rb_ary_push(argv[1], yp_node_new(parser, cast->parts.nodes[index], source, encoding, constants)); } // closing_loc - argv[2] = cast->closing_loc.start == NULL ? Qnil : location_new(parser, cast->closing_loc.start, cast->closing_loc.end); + argv[2] = cast->closing_loc.start == NULL ? Qnil : location_new(parser, cast->closing_loc.start, cast->closing_loc.end, source); // location - argv[3] = LONG2FIX(node->location.start - parser->start); - argv[4] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(5, argv, rb_const_get_at(rb_cYARP, rb_intern("InterpolatedSymbolNode"))); + argv[3] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(4, argv, rb_const_get_at(rb_cYARP, rb_intern("InterpolatedSymbolNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_INTERPOLATED_X_STRING_NODE: { yp_interpolated_x_string_node_t *cast = (yp_interpolated_x_string_node_t *) node; - VALUE argv[5]; + VALUE argv[4]; // opening_loc - argv[0] = location_new(parser, cast->opening_loc.start, cast->opening_loc.end); + argv[0] = location_new(parser, cast->opening_loc.start, cast->opening_loc.end, source); // parts argv[1] = rb_ary_new(); for (size_t index = 0; index < cast->parts.size; index++) { - rb_ary_push(argv[1], yp_node_new(parser, cast->parts.nodes[index], encoding, constants)); + rb_ary_push(argv[1], yp_node_new(parser, cast->parts.nodes[index], source, encoding, constants)); } // closing_loc - argv[2] = location_new(parser, cast->closing_loc.start, cast->closing_loc.end); + argv[2] = location_new(parser, cast->closing_loc.start, cast->closing_loc.end, source); // location - argv[3] = LONG2FIX(node->location.start - parser->start); - argv[4] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(5, argv, rb_const_get_at(rb_cYARP, rb_intern("InterpolatedXStringNode"))); + argv[3] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(4, argv, rb_const_get_at(rb_cYARP, rb_intern("InterpolatedXStringNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_KEYWORD_HASH_NODE: { yp_keyword_hash_node_t *cast = (yp_keyword_hash_node_t *) node; - VALUE argv[3]; + VALUE argv[2]; // elements argv[0] = rb_ary_new(); for (size_t index = 0; index < cast->elements.size; index++) { - rb_ary_push(argv[0], yp_node_new(parser, cast->elements.nodes[index], encoding, constants)); + rb_ary_push(argv[0], yp_node_new(parser, cast->elements.nodes[index], source, encoding, constants)); } // location - argv[1] = LONG2FIX(node->location.start - parser->start); - argv[2] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(3, argv, rb_const_get_at(rb_cYARP, rb_intern("KeywordHashNode"))); + argv[1] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(2, argv, rb_const_get_at(rb_cYARP, rb_intern("KeywordHashNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_KEYWORD_PARAMETER_NODE: { yp_keyword_parameter_node_t *cast = (yp_keyword_parameter_node_t *) node; - VALUE argv[4]; + VALUE argv[3]; // name_loc - argv[0] = location_new(parser, cast->name_loc.start, cast->name_loc.end); + argv[0] = location_new(parser, cast->name_loc.start, cast->name_loc.end, source); // value - argv[1] = cast->value == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->value, encoding, constants); + argv[1] = cast->value == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->value, source, encoding, constants); // location - argv[2] = LONG2FIX(node->location.start - parser->start); - argv[3] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(4, argv, rb_const_get_at(rb_cYARP, rb_intern("KeywordParameterNode"))); + argv[2] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(3, argv, rb_const_get_at(rb_cYARP, rb_intern("KeywordParameterNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_KEYWORD_REST_PARAMETER_NODE: { yp_keyword_rest_parameter_node_t *cast = (yp_keyword_rest_parameter_node_t *) node; - VALUE argv[4]; + VALUE argv[3]; // operator_loc - argv[0] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end); + argv[0] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source); // name_loc - argv[1] = cast->name_loc.start == NULL ? Qnil : location_new(parser, cast->name_loc.start, cast->name_loc.end); + argv[1] = cast->name_loc.start == NULL ? Qnil : location_new(parser, cast->name_loc.start, cast->name_loc.end, source); // location - argv[2] = LONG2FIX(node->location.start - parser->start); - argv[3] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(4, argv, rb_const_get_at(rb_cYARP, rb_intern("KeywordRestParameterNode"))); + argv[2] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(3, argv, rb_const_get_at(rb_cYARP, rb_intern("KeywordRestParameterNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_LAMBDA_NODE: { yp_lambda_node_t *cast = (yp_lambda_node_t *) node; - VALUE argv[6]; + VALUE argv[5]; // locals argv[0] = rb_ary_new(); @@ -1545,79 +1389,73 @@ yp_node_new(yp_parser_t *parser, yp_node_t *node, rb_encoding *encoding, ID *con } // opening_loc - argv[1] = location_new(parser, cast->opening_loc.start, cast->opening_loc.end); + argv[1] = location_new(parser, cast->opening_loc.start, cast->opening_loc.end, source); // parameters - argv[2] = cast->parameters == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->parameters, encoding, constants); + argv[2] = cast->parameters == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->parameters, source, encoding, constants); // statements - argv[3] = cast->statements == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->statements, encoding, constants); + argv[3] = cast->statements == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->statements, source, encoding, constants); // location - argv[4] = LONG2FIX(node->location.start - parser->start); - argv[5] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(6, argv, rb_const_get_at(rb_cYARP, rb_intern("LambdaNode"))); + argv[4] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(5, argv, rb_const_get_at(rb_cYARP, rb_intern("LambdaNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_LOCAL_VARIABLE_OPERATOR_AND_WRITE_NODE: { yp_local_variable_operator_and_write_node_t *cast = (yp_local_variable_operator_and_write_node_t *) node; - VALUE argv[6]; + VALUE argv[5]; // name_loc - argv[0] = location_new(parser, cast->name_loc.start, cast->name_loc.end); + argv[0] = location_new(parser, cast->name_loc.start, cast->name_loc.end, source); // operator_loc - argv[1] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end); + argv[1] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source); // value - argv[2] = yp_node_new(parser, (yp_node_t *) cast->value, encoding, constants); + argv[2] = yp_node_new(parser, (yp_node_t *) cast->value, source, encoding, constants); // constant_id argv[3] = rb_id2sym(constants[cast->constant_id - 1]); // location - argv[4] = LONG2FIX(node->location.start - parser->start); - argv[5] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(6, argv, rb_const_get_at(rb_cYARP, rb_intern("LocalVariableOperatorAndWriteNode"))); + argv[4] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(5, argv, rb_const_get_at(rb_cYARP, rb_intern("LocalVariableOperatorAndWriteNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_LOCAL_VARIABLE_OPERATOR_OR_WRITE_NODE: { yp_local_variable_operator_or_write_node_t *cast = (yp_local_variable_operator_or_write_node_t *) node; - VALUE argv[6]; + VALUE argv[5]; // name_loc - argv[0] = location_new(parser, cast->name_loc.start, cast->name_loc.end); + argv[0] = location_new(parser, cast->name_loc.start, cast->name_loc.end, source); // operator_loc - argv[1] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end); + argv[1] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source); // value - argv[2] = yp_node_new(parser, (yp_node_t *) cast->value, encoding, constants); + argv[2] = yp_node_new(parser, (yp_node_t *) cast->value, source, encoding, constants); // constant_id argv[3] = rb_id2sym(constants[cast->constant_id - 1]); // location - argv[4] = LONG2FIX(node->location.start - parser->start); - argv[5] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(6, argv, rb_const_get_at(rb_cYARP, rb_intern("LocalVariableOperatorOrWriteNode"))); + argv[4] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(5, argv, rb_const_get_at(rb_cYARP, rb_intern("LocalVariableOperatorOrWriteNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_LOCAL_VARIABLE_OPERATOR_WRITE_NODE: { yp_local_variable_operator_write_node_t *cast = (yp_local_variable_operator_write_node_t *) node; - VALUE argv[7]; + VALUE argv[6]; // name_loc - argv[0] = location_new(parser, cast->name_loc.start, cast->name_loc.end); + argv[0] = location_new(parser, cast->name_loc.start, cast->name_loc.end, source); // operator_loc - argv[1] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end); + argv[1] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source); // value - argv[2] = yp_node_new(parser, (yp_node_t *) cast->value, encoding, constants); + argv[2] = yp_node_new(parser, (yp_node_t *) cast->value, source, encoding, constants); // constant_id argv[3] = rb_id2sym(constants[cast->constant_id - 1]); @@ -1626,15 +1464,13 @@ yp_node_new(yp_parser_t *parser, yp_node_t *node, rb_encoding *encoding, ID *con argv[4] = rb_id2sym(constants[cast->operator_id - 1]); // location - argv[5] = LONG2FIX(node->location.start - parser->start); - argv[6] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(7, argv, rb_const_get_at(rb_cYARP, rb_intern("LocalVariableOperatorWriteNode"))); + argv[5] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(6, argv, rb_const_get_at(rb_cYARP, rb_intern("LocalVariableOperatorWriteNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_LOCAL_VARIABLE_READ_NODE: { yp_local_variable_read_node_t *cast = (yp_local_variable_read_node_t *) node; - VALUE argv[4]; + VALUE argv[3]; // constant_id argv[0] = rb_id2sym(constants[cast->constant_id - 1]); @@ -1643,15 +1479,13 @@ yp_node_new(yp_parser_t *parser, yp_node_t *node, rb_encoding *encoding, ID *con argv[1] = ULONG2NUM(cast->depth); // location - argv[2] = LONG2FIX(node->location.start - parser->start); - argv[3] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(4, argv, rb_const_get_at(rb_cYARP, rb_intern("LocalVariableReadNode"))); + argv[2] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(3, argv, rb_const_get_at(rb_cYARP, rb_intern("LocalVariableReadNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_LOCAL_VARIABLE_WRITE_NODE: { yp_local_variable_write_node_t *cast = (yp_local_variable_write_node_t *) node; - VALUE argv[7]; + VALUE argv[6]; // constant_id argv[0] = rb_id2sym(constants[cast->constant_id - 1]); @@ -1660,74 +1494,66 @@ yp_node_new(yp_parser_t *parser, yp_node_t *node, rb_encoding *encoding, ID *con argv[1] = ULONG2NUM(cast->depth); // value - argv[2] = cast->value == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->value, encoding, constants); + argv[2] = cast->value == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->value, source, encoding, constants); // name_loc - argv[3] = location_new(parser, cast->name_loc.start, cast->name_loc.end); + argv[3] = location_new(parser, cast->name_loc.start, cast->name_loc.end, source); // operator_loc - argv[4] = cast->operator_loc.start == NULL ? Qnil : location_new(parser, cast->operator_loc.start, cast->operator_loc.end); + argv[4] = cast->operator_loc.start == NULL ? Qnil : location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source); // location - argv[5] = LONG2FIX(node->location.start - parser->start); - argv[6] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(7, argv, rb_const_get_at(rb_cYARP, rb_intern("LocalVariableWriteNode"))); + argv[5] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(6, argv, rb_const_get_at(rb_cYARP, rb_intern("LocalVariableWriteNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_MATCH_PREDICATE_NODE: { yp_match_predicate_node_t *cast = (yp_match_predicate_node_t *) node; - VALUE argv[5]; + VALUE argv[4]; // value - argv[0] = yp_node_new(parser, (yp_node_t *) cast->value, encoding, constants); + argv[0] = yp_node_new(parser, (yp_node_t *) cast->value, source, encoding, constants); // pattern - argv[1] = yp_node_new(parser, (yp_node_t *) cast->pattern, encoding, constants); + argv[1] = yp_node_new(parser, (yp_node_t *) cast->pattern, source, encoding, constants); // operator_loc - argv[2] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end); + argv[2] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source); // location - argv[3] = LONG2FIX(node->location.start - parser->start); - argv[4] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(5, argv, rb_const_get_at(rb_cYARP, rb_intern("MatchPredicateNode"))); + argv[3] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(4, argv, rb_const_get_at(rb_cYARP, rb_intern("MatchPredicateNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_MATCH_REQUIRED_NODE: { yp_match_required_node_t *cast = (yp_match_required_node_t *) node; - VALUE argv[5]; + VALUE argv[4]; // value - argv[0] = yp_node_new(parser, (yp_node_t *) cast->value, encoding, constants); + argv[0] = yp_node_new(parser, (yp_node_t *) cast->value, source, encoding, constants); // pattern - argv[1] = yp_node_new(parser, (yp_node_t *) cast->pattern, encoding, constants); + argv[1] = yp_node_new(parser, (yp_node_t *) cast->pattern, source, encoding, constants); // operator_loc - argv[2] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end); + argv[2] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source); // location - argv[3] = LONG2FIX(node->location.start - parser->start); - argv[4] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(5, argv, rb_const_get_at(rb_cYARP, rb_intern("MatchRequiredNode"))); + argv[3] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(4, argv, rb_const_get_at(rb_cYARP, rb_intern("MatchRequiredNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_MISSING_NODE: { - VALUE argv[2]; + VALUE argv[1]; // location - argv[0] = LONG2FIX(node->location.start - parser->start); - argv[1] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(2, argv, rb_const_get_at(rb_cYARP, rb_intern("MissingNode"))); + argv[0] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(1, argv, rb_const_get_at(rb_cYARP, rb_intern("MissingNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_MODULE_NODE: { yp_module_node_t *cast = (yp_module_node_t *) node; - VALUE argv[7]; + VALUE argv[6]; // locals argv[0] = rb_ary_new(); @@ -1736,303 +1562,275 @@ yp_node_new(yp_parser_t *parser, yp_node_t *node, rb_encoding *encoding, ID *con } // module_keyword_loc - argv[1] = location_new(parser, cast->module_keyword_loc.start, cast->module_keyword_loc.end); + argv[1] = location_new(parser, cast->module_keyword_loc.start, cast->module_keyword_loc.end, source); // constant_path - argv[2] = yp_node_new(parser, (yp_node_t *) cast->constant_path, encoding, constants); + argv[2] = yp_node_new(parser, (yp_node_t *) cast->constant_path, source, encoding, constants); // statements - argv[3] = cast->statements == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->statements, encoding, constants); + argv[3] = cast->statements == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->statements, source, encoding, constants); // end_keyword_loc - argv[4] = location_new(parser, cast->end_keyword_loc.start, cast->end_keyword_loc.end); + argv[4] = location_new(parser, cast->end_keyword_loc.start, cast->end_keyword_loc.end, source); // location - argv[5] = LONG2FIX(node->location.start - parser->start); - argv[6] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(7, argv, rb_const_get_at(rb_cYARP, rb_intern("ModuleNode"))); + argv[5] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(6, argv, rb_const_get_at(rb_cYARP, rb_intern("ModuleNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_MULTI_WRITE_NODE: { yp_multi_write_node_t *cast = (yp_multi_write_node_t *) node; - VALUE argv[7]; + VALUE argv[6]; // targets argv[0] = rb_ary_new(); for (size_t index = 0; index < cast->targets.size; index++) { - rb_ary_push(argv[0], yp_node_new(parser, cast->targets.nodes[index], encoding, constants)); + rb_ary_push(argv[0], yp_node_new(parser, cast->targets.nodes[index], source, encoding, constants)); } // operator_loc - argv[1] = cast->operator_loc.start == NULL ? Qnil : location_new(parser, cast->operator_loc.start, cast->operator_loc.end); + argv[1] = cast->operator_loc.start == NULL ? Qnil : location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source); // value - argv[2] = cast->value == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->value, encoding, constants); + argv[2] = cast->value == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->value, source, encoding, constants); // lparen_loc - argv[3] = cast->lparen_loc.start == NULL ? Qnil : location_new(parser, cast->lparen_loc.start, cast->lparen_loc.end); + argv[3] = cast->lparen_loc.start == NULL ? Qnil : location_new(parser, cast->lparen_loc.start, cast->lparen_loc.end, source); // rparen_loc - argv[4] = cast->rparen_loc.start == NULL ? Qnil : location_new(parser, cast->rparen_loc.start, cast->rparen_loc.end); + argv[4] = cast->rparen_loc.start == NULL ? Qnil : location_new(parser, cast->rparen_loc.start, cast->rparen_loc.end, source); // location - argv[5] = LONG2FIX(node->location.start - parser->start); - argv[6] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(7, argv, rb_const_get_at(rb_cYARP, rb_intern("MultiWriteNode"))); + argv[5] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(6, argv, rb_const_get_at(rb_cYARP, rb_intern("MultiWriteNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_NEXT_NODE: { yp_next_node_t *cast = (yp_next_node_t *) node; - VALUE argv[4]; + VALUE argv[3]; // arguments - argv[0] = cast->arguments == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->arguments, encoding, constants); + argv[0] = cast->arguments == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->arguments, source, encoding, constants); // keyword_loc - argv[1] = location_new(parser, cast->keyword_loc.start, cast->keyword_loc.end); + argv[1] = location_new(parser, cast->keyword_loc.start, cast->keyword_loc.end, source); // location - argv[2] = LONG2FIX(node->location.start - parser->start); - argv[3] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(4, argv, rb_const_get_at(rb_cYARP, rb_intern("NextNode"))); + argv[2] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(3, argv, rb_const_get_at(rb_cYARP, rb_intern("NextNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_NIL_NODE: { - VALUE argv[2]; + VALUE argv[1]; // location - argv[0] = LONG2FIX(node->location.start - parser->start); - argv[1] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(2, argv, rb_const_get_at(rb_cYARP, rb_intern("NilNode"))); + argv[0] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(1, argv, rb_const_get_at(rb_cYARP, rb_intern("NilNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_NO_KEYWORDS_PARAMETER_NODE: { yp_no_keywords_parameter_node_t *cast = (yp_no_keywords_parameter_node_t *) node; - VALUE argv[4]; + VALUE argv[3]; // operator_loc - argv[0] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end); + argv[0] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source); // keyword_loc - argv[1] = location_new(parser, cast->keyword_loc.start, cast->keyword_loc.end); + argv[1] = location_new(parser, cast->keyword_loc.start, cast->keyword_loc.end, source); // location - argv[2] = LONG2FIX(node->location.start - parser->start); - argv[3] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(4, argv, rb_const_get_at(rb_cYARP, rb_intern("NoKeywordsParameterNode"))); + argv[2] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(3, argv, rb_const_get_at(rb_cYARP, rb_intern("NoKeywordsParameterNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_NUMBERED_REFERENCE_READ_NODE: { - VALUE argv[2]; + VALUE argv[1]; // location - argv[0] = LONG2FIX(node->location.start - parser->start); - argv[1] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(2, argv, rb_const_get_at(rb_cYARP, rb_intern("NumberedReferenceReadNode"))); + argv[0] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(1, argv, rb_const_get_at(rb_cYARP, rb_intern("NumberedReferenceReadNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_OPTIONAL_PARAMETER_NODE: { yp_optional_parameter_node_t *cast = (yp_optional_parameter_node_t *) node; - VALUE argv[6]; + VALUE argv[5]; // constant_id argv[0] = rb_id2sym(constants[cast->constant_id - 1]); // name_loc - argv[1] = location_new(parser, cast->name_loc.start, cast->name_loc.end); + argv[1] = location_new(parser, cast->name_loc.start, cast->name_loc.end, source); // operator_loc - argv[2] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end); + argv[2] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source); // value - argv[3] = yp_node_new(parser, (yp_node_t *) cast->value, encoding, constants); + argv[3] = yp_node_new(parser, (yp_node_t *) cast->value, source, encoding, constants); // location - argv[4] = LONG2FIX(node->location.start - parser->start); - argv[5] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(6, argv, rb_const_get_at(rb_cYARP, rb_intern("OptionalParameterNode"))); + argv[4] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(5, argv, rb_const_get_at(rb_cYARP, rb_intern("OptionalParameterNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_OR_NODE: { yp_or_node_t *cast = (yp_or_node_t *) node; - VALUE argv[5]; + VALUE argv[4]; // left - argv[0] = yp_node_new(parser, (yp_node_t *) cast->left, encoding, constants); + argv[0] = yp_node_new(parser, (yp_node_t *) cast->left, source, encoding, constants); // right - argv[1] = yp_node_new(parser, (yp_node_t *) cast->right, encoding, constants); + argv[1] = yp_node_new(parser, (yp_node_t *) cast->right, source, encoding, constants); // operator_loc - argv[2] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end); + argv[2] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source); // location - argv[3] = LONG2FIX(node->location.start - parser->start); - argv[4] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(5, argv, rb_const_get_at(rb_cYARP, rb_intern("OrNode"))); + argv[3] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(4, argv, rb_const_get_at(rb_cYARP, rb_intern("OrNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_PARAMETERS_NODE: { yp_parameters_node_t *cast = (yp_parameters_node_t *) node; - VALUE argv[9]; + VALUE argv[8]; // requireds argv[0] = rb_ary_new(); for (size_t index = 0; index < cast->requireds.size; index++) { - rb_ary_push(argv[0], yp_node_new(parser, cast->requireds.nodes[index], encoding, constants)); + rb_ary_push(argv[0], yp_node_new(parser, cast->requireds.nodes[index], source, encoding, constants)); } // optionals argv[1] = rb_ary_new(); for (size_t index = 0; index < cast->optionals.size; index++) { - rb_ary_push(argv[1], yp_node_new(parser, cast->optionals.nodes[index], encoding, constants)); + rb_ary_push(argv[1], yp_node_new(parser, cast->optionals.nodes[index], source, encoding, constants)); } // posts argv[2] = rb_ary_new(); for (size_t index = 0; index < cast->posts.size; index++) { - rb_ary_push(argv[2], yp_node_new(parser, cast->posts.nodes[index], encoding, constants)); + rb_ary_push(argv[2], yp_node_new(parser, cast->posts.nodes[index], source, encoding, constants)); } // rest - argv[3] = cast->rest == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->rest, encoding, constants); + argv[3] = cast->rest == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->rest, source, encoding, constants); // keywords argv[4] = rb_ary_new(); for (size_t index = 0; index < cast->keywords.size; index++) { - rb_ary_push(argv[4], yp_node_new(parser, cast->keywords.nodes[index], encoding, constants)); + rb_ary_push(argv[4], yp_node_new(parser, cast->keywords.nodes[index], source, encoding, constants)); } // keyword_rest - argv[5] = cast->keyword_rest == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->keyword_rest, encoding, constants); + argv[5] = cast->keyword_rest == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->keyword_rest, source, encoding, constants); // block - argv[6] = cast->block == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->block, encoding, constants); + argv[6] = cast->block == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->block, source, encoding, constants); // location - argv[7] = LONG2FIX(node->location.start - parser->start); - argv[8] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(9, argv, rb_const_get_at(rb_cYARP, rb_intern("ParametersNode"))); + argv[7] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(8, argv, rb_const_get_at(rb_cYARP, rb_intern("ParametersNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_PARENTHESES_NODE: { yp_parentheses_node_t *cast = (yp_parentheses_node_t *) node; - VALUE argv[5]; + VALUE argv[4]; // statements - argv[0] = cast->statements == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->statements, encoding, constants); + argv[0] = cast->statements == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->statements, source, encoding, constants); // opening_loc - argv[1] = location_new(parser, cast->opening_loc.start, cast->opening_loc.end); + argv[1] = location_new(parser, cast->opening_loc.start, cast->opening_loc.end, source); // closing_loc - argv[2] = location_new(parser, cast->closing_loc.start, cast->closing_loc.end); + argv[2] = location_new(parser, cast->closing_loc.start, cast->closing_loc.end, source); // location - argv[3] = LONG2FIX(node->location.start - parser->start); - argv[4] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(5, argv, rb_const_get_at(rb_cYARP, rb_intern("ParenthesesNode"))); + argv[3] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(4, argv, rb_const_get_at(rb_cYARP, rb_intern("ParenthesesNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_PINNED_EXPRESSION_NODE: { yp_pinned_expression_node_t *cast = (yp_pinned_expression_node_t *) node; - VALUE argv[6]; + VALUE argv[5]; // expression - argv[0] = yp_node_new(parser, (yp_node_t *) cast->expression, encoding, constants); + argv[0] = yp_node_new(parser, (yp_node_t *) cast->expression, source, encoding, constants); // operator_loc - argv[1] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end); + argv[1] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source); // lparen_loc - argv[2] = location_new(parser, cast->lparen_loc.start, cast->lparen_loc.end); + argv[2] = location_new(parser, cast->lparen_loc.start, cast->lparen_loc.end, source); // rparen_loc - argv[3] = location_new(parser, cast->rparen_loc.start, cast->rparen_loc.end); + argv[3] = location_new(parser, cast->rparen_loc.start, cast->rparen_loc.end, source); // location - argv[4] = LONG2FIX(node->location.start - parser->start); - argv[5] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(6, argv, rb_const_get_at(rb_cYARP, rb_intern("PinnedExpressionNode"))); + argv[4] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(5, argv, rb_const_get_at(rb_cYARP, rb_intern("PinnedExpressionNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_PINNED_VARIABLE_NODE: { yp_pinned_variable_node_t *cast = (yp_pinned_variable_node_t *) node; - VALUE argv[4]; + VALUE argv[3]; // variable - argv[0] = yp_node_new(parser, (yp_node_t *) cast->variable, encoding, constants); + argv[0] = yp_node_new(parser, (yp_node_t *) cast->variable, source, encoding, constants); // operator_loc - argv[1] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end); + argv[1] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source); // location - argv[2] = LONG2FIX(node->location.start - parser->start); - argv[3] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(4, argv, rb_const_get_at(rb_cYARP, rb_intern("PinnedVariableNode"))); + argv[2] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(3, argv, rb_const_get_at(rb_cYARP, rb_intern("PinnedVariableNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_POST_EXECUTION_NODE: { yp_post_execution_node_t *cast = (yp_post_execution_node_t *) node; - VALUE argv[6]; + VALUE argv[5]; // statements - argv[0] = cast->statements == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->statements, encoding, constants); + argv[0] = cast->statements == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->statements, source, encoding, constants); // keyword_loc - argv[1] = location_new(parser, cast->keyword_loc.start, cast->keyword_loc.end); + argv[1] = location_new(parser, cast->keyword_loc.start, cast->keyword_loc.end, source); // opening_loc - argv[2] = location_new(parser, cast->opening_loc.start, cast->opening_loc.end); + argv[2] = location_new(parser, cast->opening_loc.start, cast->opening_loc.end, source); // closing_loc - argv[3] = location_new(parser, cast->closing_loc.start, cast->closing_loc.end); + argv[3] = location_new(parser, cast->closing_loc.start, cast->closing_loc.end, source); // location - argv[4] = LONG2FIX(node->location.start - parser->start); - argv[5] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(6, argv, rb_const_get_at(rb_cYARP, rb_intern("PostExecutionNode"))); + argv[4] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(5, argv, rb_const_get_at(rb_cYARP, rb_intern("PostExecutionNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_PRE_EXECUTION_NODE: { yp_pre_execution_node_t *cast = (yp_pre_execution_node_t *) node; - VALUE argv[6]; + VALUE argv[5]; // statements - argv[0] = cast->statements == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->statements, encoding, constants); + argv[0] = cast->statements == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->statements, source, encoding, constants); // keyword_loc - argv[1] = location_new(parser, cast->keyword_loc.start, cast->keyword_loc.end); + argv[1] = location_new(parser, cast->keyword_loc.start, cast->keyword_loc.end, source); // opening_loc - argv[2] = location_new(parser, cast->opening_loc.start, cast->opening_loc.end); + argv[2] = location_new(parser, cast->opening_loc.start, cast->opening_loc.end, source); // closing_loc - argv[3] = location_new(parser, cast->closing_loc.start, cast->closing_loc.end); + argv[3] = location_new(parser, cast->closing_loc.start, cast->closing_loc.end, source); // location - argv[4] = LONG2FIX(node->location.start - parser->start); - argv[5] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(6, argv, rb_const_get_at(rb_cYARP, rb_intern("PreExecutionNode"))); + argv[4] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(5, argv, rb_const_get_at(rb_cYARP, rb_intern("PreExecutionNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_PROGRAM_NODE: { yp_program_node_t *cast = (yp_program_node_t *) node; - VALUE argv[4]; + VALUE argv[3]; // locals argv[0] = rb_ary_new(); @@ -2041,74 +1839,66 @@ yp_node_new(yp_parser_t *parser, yp_node_t *node, rb_encoding *encoding, ID *con } // statements - argv[1] = yp_node_new(parser, (yp_node_t *) cast->statements, encoding, constants); + argv[1] = yp_node_new(parser, (yp_node_t *) cast->statements, source, encoding, constants); // location - argv[2] = LONG2FIX(node->location.start - parser->start); - argv[3] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(4, argv, rb_const_get_at(rb_cYARP, rb_intern("ProgramNode"))); + argv[2] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(3, argv, rb_const_get_at(rb_cYARP, rb_intern("ProgramNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_RANGE_NODE: { yp_range_node_t *cast = (yp_range_node_t *) node; - VALUE argv[6]; + VALUE argv[5]; // left - argv[0] = cast->left == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->left, encoding, constants); + argv[0] = cast->left == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->left, source, encoding, constants); // right - argv[1] = cast->right == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->right, encoding, constants); + argv[1] = cast->right == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->right, source, encoding, constants); // operator_loc - argv[2] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end); + argv[2] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source); // flags argv[3] = ULONG2NUM(cast->flags); // location - argv[4] = LONG2FIX(node->location.start - parser->start); - argv[5] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(6, argv, rb_const_get_at(rb_cYARP, rb_intern("RangeNode"))); + argv[4] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(5, argv, rb_const_get_at(rb_cYARP, rb_intern("RangeNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_RATIONAL_NODE: { yp_rational_node_t *cast = (yp_rational_node_t *) node; - VALUE argv[3]; + VALUE argv[2]; // numeric - argv[0] = yp_node_new(parser, (yp_node_t *) cast->numeric, encoding, constants); + argv[0] = yp_node_new(parser, (yp_node_t *) cast->numeric, source, encoding, constants); // location - argv[1] = LONG2FIX(node->location.start - parser->start); - argv[2] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(3, argv, rb_const_get_at(rb_cYARP, rb_intern("RationalNode"))); + argv[1] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(2, argv, rb_const_get_at(rb_cYARP, rb_intern("RationalNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_REDO_NODE: { - VALUE argv[2]; + VALUE argv[1]; // location - argv[0] = LONG2FIX(node->location.start - parser->start); - argv[1] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(2, argv, rb_const_get_at(rb_cYARP, rb_intern("RedoNode"))); + argv[0] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(1, argv, rb_const_get_at(rb_cYARP, rb_intern("RedoNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_REGULAR_EXPRESSION_NODE: { yp_regular_expression_node_t *cast = (yp_regular_expression_node_t *) node; - VALUE argv[7]; + VALUE argv[6]; // opening_loc - argv[0] = location_new(parser, cast->opening_loc.start, cast->opening_loc.end); + argv[0] = location_new(parser, cast->opening_loc.start, cast->opening_loc.end, source); // content_loc - argv[1] = location_new(parser, cast->content_loc.start, cast->content_loc.end); + argv[1] = location_new(parser, cast->content_loc.start, cast->content_loc.end, source); // closing_loc - argv[2] = location_new(parser, cast->closing_loc.start, cast->closing_loc.end); + argv[2] = location_new(parser, cast->closing_loc.start, cast->closing_loc.end, source); // unescaped argv[3] = yp_string_new(&cast->unescaped, encoding); @@ -2117,158 +1907,140 @@ yp_node_new(yp_parser_t *parser, yp_node_t *node, rb_encoding *encoding, ID *con argv[4] = ULONG2NUM(cast->flags); // location - argv[5] = LONG2FIX(node->location.start - parser->start); - argv[6] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(7, argv, rb_const_get_at(rb_cYARP, rb_intern("RegularExpressionNode"))); + argv[5] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(6, argv, rb_const_get_at(rb_cYARP, rb_intern("RegularExpressionNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_REQUIRED_DESTRUCTURED_PARAMETER_NODE: { yp_required_destructured_parameter_node_t *cast = (yp_required_destructured_parameter_node_t *) node; - VALUE argv[5]; + VALUE argv[4]; // parameters argv[0] = rb_ary_new(); for (size_t index = 0; index < cast->parameters.size; index++) { - rb_ary_push(argv[0], yp_node_new(parser, cast->parameters.nodes[index], encoding, constants)); + rb_ary_push(argv[0], yp_node_new(parser, cast->parameters.nodes[index], source, encoding, constants)); } // opening_loc - argv[1] = location_new(parser, cast->opening_loc.start, cast->opening_loc.end); + argv[1] = location_new(parser, cast->opening_loc.start, cast->opening_loc.end, source); // closing_loc - argv[2] = location_new(parser, cast->closing_loc.start, cast->closing_loc.end); + argv[2] = location_new(parser, cast->closing_loc.start, cast->closing_loc.end, source); // location - argv[3] = LONG2FIX(node->location.start - parser->start); - argv[4] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(5, argv, rb_const_get_at(rb_cYARP, rb_intern("RequiredDestructuredParameterNode"))); + argv[3] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(4, argv, rb_const_get_at(rb_cYARP, rb_intern("RequiredDestructuredParameterNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_REQUIRED_PARAMETER_NODE: { yp_required_parameter_node_t *cast = (yp_required_parameter_node_t *) node; - VALUE argv[3]; + VALUE argv[2]; // constant_id argv[0] = rb_id2sym(constants[cast->constant_id - 1]); // location - argv[1] = LONG2FIX(node->location.start - parser->start); - argv[2] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(3, argv, rb_const_get_at(rb_cYARP, rb_intern("RequiredParameterNode"))); + argv[1] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(2, argv, rb_const_get_at(rb_cYARP, rb_intern("RequiredParameterNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_RESCUE_MODIFIER_NODE: { yp_rescue_modifier_node_t *cast = (yp_rescue_modifier_node_t *) node; - VALUE argv[5]; + VALUE argv[4]; // expression - argv[0] = yp_node_new(parser, (yp_node_t *) cast->expression, encoding, constants); + argv[0] = yp_node_new(parser, (yp_node_t *) cast->expression, source, encoding, constants); // keyword_loc - argv[1] = location_new(parser, cast->keyword_loc.start, cast->keyword_loc.end); + argv[1] = location_new(parser, cast->keyword_loc.start, cast->keyword_loc.end, source); // rescue_expression - argv[2] = yp_node_new(parser, (yp_node_t *) cast->rescue_expression, encoding, constants); + argv[2] = yp_node_new(parser, (yp_node_t *) cast->rescue_expression, source, encoding, constants); // location - argv[3] = LONG2FIX(node->location.start - parser->start); - argv[4] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(5, argv, rb_const_get_at(rb_cYARP, rb_intern("RescueModifierNode"))); + argv[3] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(4, argv, rb_const_get_at(rb_cYARP, rb_intern("RescueModifierNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_RESCUE_NODE: { yp_rescue_node_t *cast = (yp_rescue_node_t *) node; - VALUE argv[8]; + VALUE argv[7]; // keyword_loc - argv[0] = location_new(parser, cast->keyword_loc.start, cast->keyword_loc.end); + argv[0] = location_new(parser, cast->keyword_loc.start, cast->keyword_loc.end, source); // exceptions argv[1] = rb_ary_new(); for (size_t index = 0; index < cast->exceptions.size; index++) { - rb_ary_push(argv[1], yp_node_new(parser, cast->exceptions.nodes[index], encoding, constants)); + rb_ary_push(argv[1], yp_node_new(parser, cast->exceptions.nodes[index], source, encoding, constants)); } // operator_loc - argv[2] = cast->operator_loc.start == NULL ? Qnil : location_new(parser, cast->operator_loc.start, cast->operator_loc.end); + argv[2] = cast->operator_loc.start == NULL ? Qnil : location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source); // exception - argv[3] = cast->exception == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->exception, encoding, constants); + argv[3] = cast->exception == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->exception, source, encoding, constants); // statements - argv[4] = cast->statements == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->statements, encoding, constants); + argv[4] = cast->statements == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->statements, source, encoding, constants); // consequent - argv[5] = cast->consequent == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->consequent, encoding, constants); + argv[5] = cast->consequent == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->consequent, source, encoding, constants); // location - argv[6] = LONG2FIX(node->location.start - parser->start); - argv[7] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(8, argv, rb_const_get_at(rb_cYARP, rb_intern("RescueNode"))); + argv[6] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(7, argv, rb_const_get_at(rb_cYARP, rb_intern("RescueNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_REST_PARAMETER_NODE: { yp_rest_parameter_node_t *cast = (yp_rest_parameter_node_t *) node; - VALUE argv[4]; + VALUE argv[3]; // operator_loc - argv[0] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end); + argv[0] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source); // name_loc - argv[1] = cast->name_loc.start == NULL ? Qnil : location_new(parser, cast->name_loc.start, cast->name_loc.end); + argv[1] = cast->name_loc.start == NULL ? Qnil : location_new(parser, cast->name_loc.start, cast->name_loc.end, source); // location - argv[2] = LONG2FIX(node->location.start - parser->start); - argv[3] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(4, argv, rb_const_get_at(rb_cYARP, rb_intern("RestParameterNode"))); + argv[2] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(3, argv, rb_const_get_at(rb_cYARP, rb_intern("RestParameterNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_RETRY_NODE: { - VALUE argv[2]; + VALUE argv[1]; // location - argv[0] = LONG2FIX(node->location.start - parser->start); - argv[1] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(2, argv, rb_const_get_at(rb_cYARP, rb_intern("RetryNode"))); + argv[0] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(1, argv, rb_const_get_at(rb_cYARP, rb_intern("RetryNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_RETURN_NODE: { yp_return_node_t *cast = (yp_return_node_t *) node; - VALUE argv[4]; + VALUE argv[3]; // keyword_loc - argv[0] = location_new(parser, cast->keyword_loc.start, cast->keyword_loc.end); + argv[0] = location_new(parser, cast->keyword_loc.start, cast->keyword_loc.end, source); // arguments - argv[1] = cast->arguments == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->arguments, encoding, constants); + argv[1] = cast->arguments == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->arguments, source, encoding, constants); // location - argv[2] = LONG2FIX(node->location.start - parser->start); - argv[3] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(4, argv, rb_const_get_at(rb_cYARP, rb_intern("ReturnNode"))); + argv[2] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(3, argv, rb_const_get_at(rb_cYARP, rb_intern("ReturnNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_SELF_NODE: { - VALUE argv[2]; + VALUE argv[1]; // location - argv[0] = LONG2FIX(node->location.start - parser->start); - argv[1] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(2, argv, rb_const_get_at(rb_cYARP, rb_intern("SelfNode"))); + argv[0] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(1, argv, rb_const_get_at(rb_cYARP, rb_intern("SelfNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_SINGLETON_CLASS_NODE: { yp_singleton_class_node_t *cast = (yp_singleton_class_node_t *) node; - VALUE argv[8]; + VALUE argv[7]; // locals argv[0] = rb_ary_new(); @@ -2277,355 +2049,348 @@ yp_node_new(yp_parser_t *parser, yp_node_t *node, rb_encoding *encoding, ID *con } // class_keyword_loc - argv[1] = location_new(parser, cast->class_keyword_loc.start, cast->class_keyword_loc.end); + argv[1] = location_new(parser, cast->class_keyword_loc.start, cast->class_keyword_loc.end, source); // operator_loc - argv[2] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end); + argv[2] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source); // expression - argv[3] = yp_node_new(parser, (yp_node_t *) cast->expression, encoding, constants); + argv[3] = yp_node_new(parser, (yp_node_t *) cast->expression, source, encoding, constants); // statements - argv[4] = cast->statements == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->statements, encoding, constants); + argv[4] = cast->statements == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->statements, source, encoding, constants); // end_keyword_loc - argv[5] = location_new(parser, cast->end_keyword_loc.start, cast->end_keyword_loc.end); + argv[5] = location_new(parser, cast->end_keyword_loc.start, cast->end_keyword_loc.end, source); // location - argv[6] = LONG2FIX(node->location.start - parser->start); - argv[7] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(8, argv, rb_const_get_at(rb_cYARP, rb_intern("SingletonClassNode"))); + argv[6] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(7, argv, rb_const_get_at(rb_cYARP, rb_intern("SingletonClassNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_SOURCE_ENCODING_NODE: { - VALUE argv[2]; + VALUE argv[1]; // location - argv[0] = LONG2FIX(node->location.start - parser->start); - argv[1] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(2, argv, rb_const_get_at(rb_cYARP, rb_intern("SourceEncodingNode"))); + argv[0] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(1, argv, rb_const_get_at(rb_cYARP, rb_intern("SourceEncodingNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_SOURCE_FILE_NODE: { yp_source_file_node_t *cast = (yp_source_file_node_t *) node; - VALUE argv[3]; + VALUE argv[2]; // filepath argv[0] = yp_string_new(&cast->filepath, encoding); // location - argv[1] = LONG2FIX(node->location.start - parser->start); - argv[2] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(3, argv, rb_const_get_at(rb_cYARP, rb_intern("SourceFileNode"))); + argv[1] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(2, argv, rb_const_get_at(rb_cYARP, rb_intern("SourceFileNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_SOURCE_LINE_NODE: { - VALUE argv[2]; + VALUE argv[1]; // location - argv[0] = LONG2FIX(node->location.start - parser->start); - argv[1] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(2, argv, rb_const_get_at(rb_cYARP, rb_intern("SourceLineNode"))); + argv[0] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(1, argv, rb_const_get_at(rb_cYARP, rb_intern("SourceLineNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_SPLAT_NODE: { yp_splat_node_t *cast = (yp_splat_node_t *) node; - VALUE argv[4]; + VALUE argv[3]; // operator_loc - argv[0] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end); + argv[0] = location_new(parser, cast->operator_loc.start, cast->operator_loc.end, source); // expression - argv[1] = cast->expression == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->expression, encoding, constants); + argv[1] = cast->expression == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->expression, source, encoding, constants); // location - argv[2] = LONG2FIX(node->location.start - parser->start); - argv[3] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(4, argv, rb_const_get_at(rb_cYARP, rb_intern("SplatNode"))); + argv[2] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(3, argv, rb_const_get_at(rb_cYARP, rb_intern("SplatNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_STATEMENTS_NODE: { yp_statements_node_t *cast = (yp_statements_node_t *) node; - VALUE argv[3]; + VALUE argv[2]; // body argv[0] = rb_ary_new(); for (size_t index = 0; index < cast->body.size; index++) { - rb_ary_push(argv[0], yp_node_new(parser, cast->body.nodes[index], encoding, constants)); + rb_ary_push(argv[0], yp_node_new(parser, cast->body.nodes[index], source, encoding, constants)); } // location - argv[1] = LONG2FIX(node->location.start - parser->start); - argv[2] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(3, argv, rb_const_get_at(rb_cYARP, rb_intern("StatementsNode"))); + argv[1] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(2, argv, rb_const_get_at(rb_cYARP, rb_intern("StatementsNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_STRING_CONCAT_NODE: { yp_string_concat_node_t *cast = (yp_string_concat_node_t *) node; - VALUE argv[4]; + VALUE argv[3]; // left - argv[0] = yp_node_new(parser, (yp_node_t *) cast->left, encoding, constants); + argv[0] = yp_node_new(parser, (yp_node_t *) cast->left, source, encoding, constants); // right - argv[1] = yp_node_new(parser, (yp_node_t *) cast->right, encoding, constants); + argv[1] = yp_node_new(parser, (yp_node_t *) cast->right, source, encoding, constants); // location - argv[2] = LONG2FIX(node->location.start - parser->start); - argv[3] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(4, argv, rb_const_get_at(rb_cYARP, rb_intern("StringConcatNode"))); + argv[2] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(3, argv, rb_const_get_at(rb_cYARP, rb_intern("StringConcatNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_STRING_NODE: { yp_string_node_t *cast = (yp_string_node_t *) node; - VALUE argv[6]; + VALUE argv[5]; // opening_loc - argv[0] = cast->opening_loc.start == NULL ? Qnil : location_new(parser, cast->opening_loc.start, cast->opening_loc.end); + argv[0] = cast->opening_loc.start == NULL ? Qnil : location_new(parser, cast->opening_loc.start, cast->opening_loc.end, source); // content_loc - argv[1] = location_new(parser, cast->content_loc.start, cast->content_loc.end); + argv[1] = location_new(parser, cast->content_loc.start, cast->content_loc.end, source); // closing_loc - argv[2] = cast->closing_loc.start == NULL ? Qnil : location_new(parser, cast->closing_loc.start, cast->closing_loc.end); + argv[2] = cast->closing_loc.start == NULL ? Qnil : location_new(parser, cast->closing_loc.start, cast->closing_loc.end, source); // unescaped argv[3] = yp_string_new(&cast->unescaped, encoding); // location - argv[4] = LONG2FIX(node->location.start - parser->start); - argv[5] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(6, argv, rb_const_get_at(rb_cYARP, rb_intern("StringNode"))); + argv[4] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(5, argv, rb_const_get_at(rb_cYARP, rb_intern("StringNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_SUPER_NODE: { yp_super_node_t *cast = (yp_super_node_t *) node; - VALUE argv[7]; + VALUE argv[6]; // keyword_loc - argv[0] = location_new(parser, cast->keyword_loc.start, cast->keyword_loc.end); + argv[0] = location_new(parser, cast->keyword_loc.start, cast->keyword_loc.end, source); // lparen_loc - argv[1] = cast->lparen_loc.start == NULL ? Qnil : location_new(parser, cast->lparen_loc.start, cast->lparen_loc.end); + argv[1] = cast->lparen_loc.start == NULL ? Qnil : location_new(parser, cast->lparen_loc.start, cast->lparen_loc.end, source); // arguments - argv[2] = cast->arguments == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->arguments, encoding, constants); + argv[2] = cast->arguments == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->arguments, source, encoding, constants); // rparen_loc - argv[3] = cast->rparen_loc.start == NULL ? Qnil : location_new(parser, cast->rparen_loc.start, cast->rparen_loc.end); + argv[3] = cast->rparen_loc.start == NULL ? Qnil : location_new(parser, cast->rparen_loc.start, cast->rparen_loc.end, source); // block - argv[4] = cast->block == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->block, encoding, constants); + argv[4] = cast->block == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->block, source, encoding, constants); // location - argv[5] = LONG2FIX(node->location.start - parser->start); - argv[6] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(7, argv, rb_const_get_at(rb_cYARP, rb_intern("SuperNode"))); + argv[5] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(6, argv, rb_const_get_at(rb_cYARP, rb_intern("SuperNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_SYMBOL_NODE: { yp_symbol_node_t *cast = (yp_symbol_node_t *) node; - VALUE argv[6]; + VALUE argv[5]; // opening_loc - argv[0] = cast->opening_loc.start == NULL ? Qnil : location_new(parser, cast->opening_loc.start, cast->opening_loc.end); + argv[0] = cast->opening_loc.start == NULL ? Qnil : location_new(parser, cast->opening_loc.start, cast->opening_loc.end, source); // value_loc - argv[1] = location_new(parser, cast->value_loc.start, cast->value_loc.end); + argv[1] = location_new(parser, cast->value_loc.start, cast->value_loc.end, source); // closing_loc - argv[2] = cast->closing_loc.start == NULL ? Qnil : location_new(parser, cast->closing_loc.start, cast->closing_loc.end); + argv[2] = cast->closing_loc.start == NULL ? Qnil : location_new(parser, cast->closing_loc.start, cast->closing_loc.end, source); // unescaped argv[3] = yp_string_new(&cast->unescaped, encoding); // location - argv[4] = LONG2FIX(node->location.start - parser->start); - argv[5] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(6, argv, rb_const_get_at(rb_cYARP, rb_intern("SymbolNode"))); + argv[4] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(5, argv, rb_const_get_at(rb_cYARP, rb_intern("SymbolNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_TRUE_NODE: { - VALUE argv[2]; + VALUE argv[1]; // location - argv[0] = LONG2FIX(node->location.start - parser->start); - argv[1] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(2, argv, rb_const_get_at(rb_cYARP, rb_intern("TrueNode"))); + argv[0] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(1, argv, rb_const_get_at(rb_cYARP, rb_intern("TrueNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_UNDEF_NODE: { yp_undef_node_t *cast = (yp_undef_node_t *) node; - VALUE argv[4]; + VALUE argv[3]; // names argv[0] = rb_ary_new(); for (size_t index = 0; index < cast->names.size; index++) { - rb_ary_push(argv[0], yp_node_new(parser, cast->names.nodes[index], encoding, constants)); + rb_ary_push(argv[0], yp_node_new(parser, cast->names.nodes[index], source, encoding, constants)); } // keyword_loc - argv[1] = location_new(parser, cast->keyword_loc.start, cast->keyword_loc.end); + argv[1] = location_new(parser, cast->keyword_loc.start, cast->keyword_loc.end, source); // location - argv[2] = LONG2FIX(node->location.start - parser->start); - argv[3] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(4, argv, rb_const_get_at(rb_cYARP, rb_intern("UndefNode"))); + argv[2] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(3, argv, rb_const_get_at(rb_cYARP, rb_intern("UndefNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_UNLESS_NODE: { yp_unless_node_t *cast = (yp_unless_node_t *) node; - VALUE argv[7]; + VALUE argv[6]; // keyword_loc - argv[0] = location_new(parser, cast->keyword_loc.start, cast->keyword_loc.end); + argv[0] = location_new(parser, cast->keyword_loc.start, cast->keyword_loc.end, source); // predicate - argv[1] = yp_node_new(parser, (yp_node_t *) cast->predicate, encoding, constants); + argv[1] = yp_node_new(parser, (yp_node_t *) cast->predicate, source, encoding, constants); // statements - argv[2] = cast->statements == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->statements, encoding, constants); + argv[2] = cast->statements == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->statements, source, encoding, constants); // consequent - argv[3] = cast->consequent == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->consequent, encoding, constants); + argv[3] = cast->consequent == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->consequent, source, encoding, constants); // end_keyword_loc - argv[4] = cast->end_keyword_loc.start == NULL ? Qnil : location_new(parser, cast->end_keyword_loc.start, cast->end_keyword_loc.end); + argv[4] = cast->end_keyword_loc.start == NULL ? Qnil : location_new(parser, cast->end_keyword_loc.start, cast->end_keyword_loc.end, source); // location - argv[5] = LONG2FIX(node->location.start - parser->start); - argv[6] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(7, argv, rb_const_get_at(rb_cYARP, rb_intern("UnlessNode"))); + argv[5] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(6, argv, rb_const_get_at(rb_cYARP, rb_intern("UnlessNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_UNTIL_NODE: { yp_until_node_t *cast = (yp_until_node_t *) node; - VALUE argv[5]; + VALUE argv[4]; // keyword_loc - argv[0] = location_new(parser, cast->keyword_loc.start, cast->keyword_loc.end); + argv[0] = location_new(parser, cast->keyword_loc.start, cast->keyword_loc.end, source); // predicate - argv[1] = yp_node_new(parser, (yp_node_t *) cast->predicate, encoding, constants); + argv[1] = yp_node_new(parser, (yp_node_t *) cast->predicate, source, encoding, constants); // statements - argv[2] = cast->statements == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->statements, encoding, constants); + argv[2] = cast->statements == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->statements, source, encoding, constants); // location - argv[3] = LONG2FIX(node->location.start - parser->start); - argv[4] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(5, argv, rb_const_get_at(rb_cYARP, rb_intern("UntilNode"))); + argv[3] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(4, argv, rb_const_get_at(rb_cYARP, rb_intern("UntilNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_WHEN_NODE: { yp_when_node_t *cast = (yp_when_node_t *) node; - VALUE argv[5]; + VALUE argv[4]; // keyword_loc - argv[0] = location_new(parser, cast->keyword_loc.start, cast->keyword_loc.end); + argv[0] = location_new(parser, cast->keyword_loc.start, cast->keyword_loc.end, source); // conditions argv[1] = rb_ary_new(); for (size_t index = 0; index < cast->conditions.size; index++) { - rb_ary_push(argv[1], yp_node_new(parser, cast->conditions.nodes[index], encoding, constants)); + rb_ary_push(argv[1], yp_node_new(parser, cast->conditions.nodes[index], source, encoding, constants)); } // statements - argv[2] = cast->statements == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->statements, encoding, constants); + argv[2] = cast->statements == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->statements, source, encoding, constants); // location - argv[3] = LONG2FIX(node->location.start - parser->start); - argv[4] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(5, argv, rb_const_get_at(rb_cYARP, rb_intern("WhenNode"))); + argv[3] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(4, argv, rb_const_get_at(rb_cYARP, rb_intern("WhenNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_WHILE_NODE: { yp_while_node_t *cast = (yp_while_node_t *) node; - VALUE argv[5]; + VALUE argv[4]; // keyword_loc - argv[0] = location_new(parser, cast->keyword_loc.start, cast->keyword_loc.end); + argv[0] = location_new(parser, cast->keyword_loc.start, cast->keyword_loc.end, source); // predicate - argv[1] = yp_node_new(parser, (yp_node_t *) cast->predicate, encoding, constants); + argv[1] = yp_node_new(parser, (yp_node_t *) cast->predicate, source, encoding, constants); // statements - argv[2] = cast->statements == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->statements, encoding, constants); + argv[2] = cast->statements == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->statements, source, encoding, constants); // location - argv[3] = LONG2FIX(node->location.start - parser->start); - argv[4] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(5, argv, rb_const_get_at(rb_cYARP, rb_intern("WhileNode"))); + argv[3] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(4, argv, rb_const_get_at(rb_cYARP, rb_intern("WhileNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_X_STRING_NODE: { yp_x_string_node_t *cast = (yp_x_string_node_t *) node; - VALUE argv[6]; + VALUE argv[5]; // opening_loc - argv[0] = location_new(parser, cast->opening_loc.start, cast->opening_loc.end); + argv[0] = location_new(parser, cast->opening_loc.start, cast->opening_loc.end, source); // content_loc - argv[1] = location_new(parser, cast->content_loc.start, cast->content_loc.end); + argv[1] = location_new(parser, cast->content_loc.start, cast->content_loc.end, source); // closing_loc - argv[2] = location_new(parser, cast->closing_loc.start, cast->closing_loc.end); + argv[2] = location_new(parser, cast->closing_loc.start, cast->closing_loc.end, source); // unescaped argv[3] = yp_string_new(&cast->unescaped, encoding); // location - argv[4] = LONG2FIX(node->location.start - parser->start); - argv[5] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(6, argv, rb_const_get_at(rb_cYARP, rb_intern("XStringNode"))); + argv[4] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(5, argv, rb_const_get_at(rb_cYARP, rb_intern("XStringNode"))); } -#line 37 "api_node.c.erb" +#line 25 "api_node.c.erb" case YP_NODE_YIELD_NODE: { yp_yield_node_t *cast = (yp_yield_node_t *) node; - VALUE argv[6]; + VALUE argv[5]; // keyword_loc - argv[0] = location_new(parser, cast->keyword_loc.start, cast->keyword_loc.end); + argv[0] = location_new(parser, cast->keyword_loc.start, cast->keyword_loc.end, source); // lparen_loc - argv[1] = cast->lparen_loc.start == NULL ? Qnil : location_new(parser, cast->lparen_loc.start, cast->lparen_loc.end); + argv[1] = cast->lparen_loc.start == NULL ? Qnil : location_new(parser, cast->lparen_loc.start, cast->lparen_loc.end, source); // arguments - argv[2] = cast->arguments == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->arguments, encoding, constants); + argv[2] = cast->arguments == NULL ? Qnil : yp_node_new(parser, (yp_node_t *) cast->arguments, source, encoding, constants); // rparen_loc - argv[3] = cast->rparen_loc.start == NULL ? Qnil : location_new(parser, cast->rparen_loc.start, cast->rparen_loc.end); + argv[3] = cast->rparen_loc.start == NULL ? Qnil : location_new(parser, cast->rparen_loc.start, cast->rparen_loc.end, source); // location - argv[4] = LONG2FIX(node->location.start - parser->start); - argv[5] = LONG2FIX(node->location.end - node->location.start); - - return rb_class_new_instance(6, argv, rb_const_get_at(rb_cYARP, rb_intern("YieldNode"))); + argv[4] = location_new(parser, node->location.start, node->location.end, source); + return rb_class_new_instance(5, argv, rb_const_get_at(rb_cYARP, rb_intern("YieldNode"))); } default: rb_raise(rb_eRuntimeError, "unknown node type: %d", node->type); } } -#line 94 "api_node.c.erb" +#line 80 "api_node.c.erb" +VALUE +yp_token_new(yp_parser_t *parser, yp_token_t *token, rb_encoding *encoding, VALUE source) { + ID type = rb_intern(yp_token_type_to_str(token->type)); + VALUE location = location_new(parser, token->start, token->end, source); + + VALUE argv[] = { + ID2SYM(type), + rb_enc_str_new(token->start, token->end - token->start, encoding), + location + }; + + return rb_class_new_instance(3, argv, rb_cYARPToken); +} + +// Create a YARP::Source object from the given parser. +VALUE +yp_source_new(yp_parser_t *parser) { + VALUE source = rb_str_new(parser->start, parser->end - parser->start); + VALUE offsets = rb_ary_new_capa(parser->newline_list.size); + + for (size_t index = 0; index < parser->newline_list.size; index++) { + rb_ary_push(offsets, INT2FIX(parser->newline_list.offsets[index])); + } + + VALUE source_argv[] = { source, offsets }; + return rb_class_new_instance(2, source_argv, rb_cYARPSource); +} + VALUE yp_ast_new(yp_parser_t *parser, yp_node_t *node, rb_encoding *encoding) { + VALUE source = yp_source_new(parser); ID *constants = calloc(parser->constant_pool.size, sizeof(ID)); for (size_t index = 0; index < parser->constant_pool.capacity; index++) { @@ -2636,7 +2401,7 @@ VALUE yp_ast_new(yp_parser_t *parser, yp_node_t *node, rb_encoding *encoding) { } } - VALUE res_node = yp_node_new(parser, node, encoding, constants); + VALUE res_node = yp_node_new(parser, node, source, encoding, constants); free(constants); return res_node; } diff --git a/yarp/ast.h b/yarp/ast.h index a297a3dea4..15c8b2855f 100644 --- a/yarp/ast.h +++ b/yarp/ast.h @@ -9,14 +9,13 @@ #define YARP_AST_H #include "yarp/defines.h" +#include "yarp/util/yp_constant_pool.h" +#include "yarp/util/yp_string.h" #include <assert.h> #include <stddef.h> #include <stdint.h> -#include "yarp/util/yp_constant_pool.h" -#include "yarp/util/yp_string.h" - // This enum represents every type of token in the Ruby source. typedef enum yp_token_type { YP_TOKEN_EOF = 1, // final token in the file diff --git a/yarp/compile.c b/yarp/compile.c deleted file mode 100644 index eaa539b413..0000000000 --- a/yarp/compile.c +++ /dev/null @@ -1,826 +0,0 @@ -#include "yarp/extension.h" - -typedef enum { - YP_ISEQ_TYPE_TOP, - YP_ISEQ_TYPE_BLOCK -} yp_iseq_type_t; - -typedef enum { - YP_RUBY_EVENT_B_CALL, - YP_RUBY_EVENT_B_RETURN -} yp_ruby_event_t; - -typedef struct yp_iseq_compiler { - // This is the parent compiler. It is used to communicate between ISEQs that - // need to be able to jump back to the parent ISEQ. - struct yp_iseq_compiler *parent; - - // This is the list of local variables that are defined on this scope. - yp_constant_id_list_t *locals; - - // This is the instruction sequence that we are compiling. It's actually just - // a Ruby array that maps to the output of RubyVM::InstructionSequence#to_a. - VALUE insns; - - // This is a list of IDs coming from the instructions that are being compiled. - // In theory they should be deterministic, but we don't have that - // functionality yet. Fortunately you can pass -1 for all of them and - // everything for the most part continues to work. - VALUE node_ids; - - // This is the current size of the instruction sequence's stack. - int stack_size; - - // This is the maximum size of the instruction sequence's stack. - int stack_max; - - // This is the name of the instruction sequence. - const char *name; - - // This is the type of the instruction sequence. - yp_iseq_type_t type; - - // This is the optional argument information. - VALUE optionals; - - // This is the number of arguments. - int arg_size; - - // This is the current size of the instruction sequence's instructions and - // operands. - size_t size; - - // This is the index of the current inline storage. - size_t inline_storage_index; -} yp_iseq_compiler_t; - -static void -yp_iseq_compiler_init(yp_iseq_compiler_t *compiler, yp_iseq_compiler_t *parent, yp_constant_id_list_t *locals, const char *name, yp_iseq_type_t type) { - *compiler = (yp_iseq_compiler_t) { - .parent = parent, - .locals = locals, - .insns = rb_ary_new(), - .node_ids = rb_ary_new(), - .stack_size = 0, - .stack_max = 0, - .name = name, - .type = type, - .optionals = rb_hash_new(), - .arg_size = 0, - .size = 0, - .inline_storage_index = 0 - }; -} - -/******************************************************************************/ -/* Utilities */ -/******************************************************************************/ - -static inline int -sizet2int(size_t value) { - if (value > INT_MAX) rb_raise(rb_eRuntimeError, "value too large"); - return (int) value; -} - -static int -local_index(yp_iseq_compiler_t *compiler, yp_constant_id_t constant_id, int depth) { - int compiler_index; - yp_iseq_compiler_t *local_compiler = compiler; - - for (compiler_index = 0; compiler_index < depth; compiler_index++) { - local_compiler = local_compiler->parent; - assert(local_compiler != NULL); - } - - size_t index; - for (index = 0; index < local_compiler->locals->size; index++) { - if (local_compiler->locals->ids[index] == constant_id) { - return sizet2int(local_compiler->locals->size - index + 2); - } - } - - return -1; -} - -/******************************************************************************/ -/* Parse specific VALUEs from strings */ -/******************************************************************************/ - -static VALUE -parse_number(const char *start, const char *end) { - size_t length = end - start; - - char *buffer = alloca(length + 1); - memcpy(buffer, start, length); - - buffer[length] = '\0'; - return rb_cstr_to_inum(buffer, -10, Qfalse); -} - -static inline VALUE -parse_string(yp_string_t *string) { - return rb_str_new(yp_string_source(string), yp_string_length(string)); -} - -static inline ID -parse_symbol(const char *start, const char *end) { - return rb_intern2(start, end - start); -} - -static inline ID -parse_location_symbol(yp_location_t *location) { - return parse_symbol(location->start, location->end); -} - -static inline ID -parse_node_symbol(yp_node_t *node) { - return parse_symbol(node->location.start, node->location.end); -} - -static inline ID -parse_string_symbol(yp_string_t *string) { - const char *start = yp_string_source(string); - return parse_symbol(start, start + yp_string_length(string)); -} - -/******************************************************************************/ -/* Create Ruby objects for compilation */ -/******************************************************************************/ - -static VALUE -yp_iseq_new(yp_iseq_compiler_t *compiler) { - VALUE code_location = rb_ary_new_capa(4); - rb_ary_push(code_location, INT2FIX(1)); - rb_ary_push(code_location, INT2FIX(0)); - rb_ary_push(code_location, INT2FIX(1)); - rb_ary_push(code_location, INT2FIX(0)); - - VALUE data = rb_hash_new(); - rb_hash_aset(data, ID2SYM(rb_intern("arg_size")), INT2FIX(compiler->arg_size)); - rb_hash_aset(data, ID2SYM(rb_intern("local_size")), INT2FIX(0)); - rb_hash_aset(data, ID2SYM(rb_intern("stack_max")), INT2FIX(compiler->stack_max)); - rb_hash_aset(data, ID2SYM(rb_intern("node_id")), INT2FIX(-1)); - rb_hash_aset(data, ID2SYM(rb_intern("code_location")), code_location); - rb_hash_aset(data, ID2SYM(rb_intern("node_ids")), compiler->node_ids); - - VALUE type = Qnil; - switch (compiler->type) { - case YP_ISEQ_TYPE_TOP: - type = ID2SYM(rb_intern("top")); - break; - case YP_ISEQ_TYPE_BLOCK: - type = ID2SYM(rb_intern("block")); - break; - } - - VALUE iseq = rb_ary_new_capa(13); - rb_ary_push(iseq, rb_str_new_cstr("YARVInstructionSequence/SimpleDataFormat")); - rb_ary_push(iseq, INT2FIX(3)); - rb_ary_push(iseq, INT2FIX(3)); - rb_ary_push(iseq, INT2FIX(1)); - rb_ary_push(iseq, data); - rb_ary_push(iseq, rb_str_new_cstr(compiler->name)); - rb_ary_push(iseq, rb_str_new_cstr("<compiled>")); - rb_ary_push(iseq, rb_str_new_cstr("<compiled>")); - rb_ary_push(iseq, INT2FIX(1)); - rb_ary_push(iseq, type); - rb_ary_push(iseq, rb_ary_new()); - rb_ary_push(iseq, compiler->optionals); - rb_ary_push(iseq, rb_ary_new()); - rb_ary_push(iseq, compiler->insns); - - return iseq; -} - -// static const int YP_CALLDATA_ARGS_SPLAT = 1 << 0; -// static const int YP_CALLDATA_ARGS_BLOCKARG = 1 << 1; -static const int YP_CALLDATA_FCALL = 1 << 2; -static const int YP_CALLDATA_VCALL = 1 << 3; -static const int YP_CALLDATA_ARGS_SIMPLE = 1 << 4; -// static const int YP_CALLDATA_BLOCKISEQ = 1 << 5; -// static const int YP_CALLDATA_KWARG = 1 << 6; -// static const int YP_CALLDATA_KW_SPLAT = 1 << 7; -// static const int YP_CALLDATA_TAILCALL = 1 << 8; -// static const int YP_CALLDATA_SUPER = 1 << 9; -// static const int YP_CALLDATA_ZSUPER = 1 << 10; -// static const int YP_CALLDATA_OPT_SEND = 1 << 11; -// static const int YP_CALLDATA_KW_SPLAT_MUT = 1 << 12; - -static VALUE -yp_calldata_new(ID mid, int flag, size_t orig_argc) { - VALUE calldata = rb_hash_new(); - - rb_hash_aset(calldata, ID2SYM(rb_intern("mid")), ID2SYM(mid)); - rb_hash_aset(calldata, ID2SYM(rb_intern("flag")), INT2FIX(flag)); - rb_hash_aset(calldata, ID2SYM(rb_intern("orig_argc")), INT2FIX(orig_argc)); - - return calldata; -} - -static inline VALUE -yp_inline_storage_new(yp_iseq_compiler_t *compiler) { - return INT2FIX(compiler->inline_storage_index++); -} - -/******************************************************************************/ -/* Push instructions onto a compiler */ -/******************************************************************************/ - -static VALUE -push_insn(yp_iseq_compiler_t *compiler, int stack_change, size_t size, ...) { - va_list opnds; - va_start(opnds, size); - - VALUE insn = rb_ary_new_capa(size); - for (size_t index = 0; index < size; index++) { - rb_ary_push(insn, va_arg(opnds, VALUE)); - } - - va_end(opnds); - - compiler->stack_size += stack_change; - if (compiler->stack_size > compiler->stack_max) { - compiler->stack_max = compiler->stack_size; - } - - compiler->size += size; - rb_ary_push(compiler->insns, insn); - rb_ary_push(compiler->node_ids, INT2FIX(-1)); - - return insn; -} - -static VALUE -push_label(yp_iseq_compiler_t *compiler) { - VALUE label = ID2SYM(rb_intern_str(rb_sprintf("label_%zu", compiler->size))); - rb_ary_push(compiler->insns, label); - return label; -} - -static void -push_ruby_event(yp_iseq_compiler_t *compiler, yp_ruby_event_t event) { - switch (event) { - case YP_RUBY_EVENT_B_CALL: - rb_ary_push(compiler->insns, ID2SYM(rb_intern("RUBY_EVENT_B_CALL"))); - break; - case YP_RUBY_EVENT_B_RETURN: - rb_ary_push(compiler->insns, ID2SYM(rb_intern("RUBY_EVENT_B_RETURN"))); - break; - } -} - -static inline VALUE -push_anytostring(yp_iseq_compiler_t *compiler) { - return push_insn(compiler, -2 + 1, 1, ID2SYM(rb_intern("anytostring"))); -} - -static inline VALUE -push_branchif(yp_iseq_compiler_t *compiler, VALUE label) { - return push_insn(compiler, -1 + 0, 2, ID2SYM(rb_intern("branchif")), label); -} - -static inline VALUE -push_branchunless(yp_iseq_compiler_t *compiler, VALUE label) { - return push_insn(compiler, -1 + 0, 2, ID2SYM(rb_intern("branchunless")), label); -} - -static inline VALUE -push_concatstrings(yp_iseq_compiler_t *compiler, int count) { - return push_insn(compiler, -count + 1, 2, ID2SYM(rb_intern("concatstrings")), INT2FIX(count)); -} - -static inline VALUE -push_dup(yp_iseq_compiler_t *compiler) { - return push_insn(compiler, -1 + 2, 1, ID2SYM(rb_intern("dup"))); -} - -static inline VALUE -push_getclassvariable(yp_iseq_compiler_t *compiler, VALUE name, VALUE inline_storage) { - return push_insn(compiler, -0 + 1, 3, ID2SYM(rb_intern("getclassvariable")), name, inline_storage); -} - -static inline VALUE -push_getconstant(yp_iseq_compiler_t *compiler, VALUE name) { - return push_insn(compiler, -2 + 1, 2, ID2SYM(rb_intern("getconstant")), name); -} - -static inline VALUE -push_getglobal(yp_iseq_compiler_t *compiler, VALUE name) { - return push_insn(compiler, -0 + 1, 2, ID2SYM(rb_intern("getglobal")), name); -} - -static inline VALUE -push_getinstancevariable(yp_iseq_compiler_t *compiler, VALUE name, VALUE inline_storage) { - return push_insn(compiler, -0 + 1, 3, ID2SYM(rb_intern("getinstancevariable")), name, inline_storage); -} - -static inline VALUE -push_getlocal(yp_iseq_compiler_t *compiler, VALUE index, VALUE depth) { - return push_insn(compiler, -0 + 1, 3, ID2SYM(rb_intern("getlocal")), index, depth); -} - -static inline VALUE -push_leave(yp_iseq_compiler_t *compiler) { - return push_insn(compiler, -1 + 0, 1, ID2SYM(rb_intern("leave"))); -} - -static inline VALUE -push_newarray(yp_iseq_compiler_t *compiler, int count) { - return push_insn(compiler, -count + 1, 2, ID2SYM(rb_intern("newarray")), INT2FIX(count)); -} - -static inline VALUE -push_newhash(yp_iseq_compiler_t *compiler, int count) { - return push_insn(compiler, -count + 1, 2, ID2SYM(rb_intern("newhash")), INT2FIX(count)); -} - -static inline VALUE -push_newrange(yp_iseq_compiler_t *compiler, VALUE flag) { - return push_insn(compiler, -2 + 1, 2, ID2SYM(rb_intern("newrange")), flag); -} - -static inline VALUE -push_nop(yp_iseq_compiler_t *compiler) { - return push_insn(compiler, -2 + 1, 1, ID2SYM(rb_intern("nop"))); -} - -static inline VALUE -push_objtostring(yp_iseq_compiler_t *compiler, VALUE calldata) { - return push_insn(compiler, -1 + 1, 2, ID2SYM(rb_intern("objtostring")), calldata); -} - -static inline VALUE -push_pop(yp_iseq_compiler_t *compiler) { - return push_insn(compiler, -1 + 0, 1, ID2SYM(rb_intern("pop"))); -} - -static inline VALUE -push_putnil(yp_iseq_compiler_t *compiler) { - return push_insn(compiler, -0 + 1, 1, ID2SYM(rb_intern("putnil"))); -} - -static inline VALUE -push_putobject(yp_iseq_compiler_t *compiler, VALUE value) { - return push_insn(compiler, -0 + 1, 2, ID2SYM(rb_intern("putobject")), value); -} - -static inline VALUE -push_putself(yp_iseq_compiler_t *compiler) { - return push_insn(compiler, -0 + 1, 1, ID2SYM(rb_intern("putself"))); -} - -static inline VALUE -push_setlocal(yp_iseq_compiler_t *compiler, VALUE index, VALUE depth) { - return push_insn(compiler, -1 + 0, 3, ID2SYM(rb_intern("setlocal")), index, depth); -} - -static const VALUE YP_SPECIALOBJECT_VMCORE = INT2FIX(1); -static const VALUE YP_SPECIALOBJECT_CBASE = INT2FIX(2); -// static const VALUE YP_SPECIALOBJECT_CONST_BASE = INT2FIX(3); - -static inline VALUE -push_putspecialobject(yp_iseq_compiler_t *compiler, VALUE object) { - return push_insn(compiler, -0 + 1, 2, ID2SYM(rb_intern("putspecialobject")), object); -} - -static inline VALUE -push_putstring(yp_iseq_compiler_t *compiler, VALUE string) { - return push_insn(compiler, -0 + 1, 2, ID2SYM(rb_intern("putstring")), string); -} - -static inline VALUE -push_send(yp_iseq_compiler_t *compiler, int stack_change, VALUE calldata, VALUE block_iseq) { - return push_insn(compiler, stack_change, 3, ID2SYM(rb_intern("send")), calldata, block_iseq); -} - -static inline VALUE -push_setclassvariable(yp_iseq_compiler_t *compiler, VALUE name, VALUE inline_storage) { - return push_insn(compiler, -1 + 0, 3, ID2SYM(rb_intern("setclassvariable")), name, inline_storage); -} - -static inline VALUE -push_setglobal(yp_iseq_compiler_t *compiler, VALUE name) { - return push_insn(compiler, -1 + 0, 2, ID2SYM(rb_intern("setglobal")), name); -} - -static inline VALUE -push_setinstancevariable(yp_iseq_compiler_t *compiler, VALUE name, VALUE inline_storage) { - return push_insn(compiler, -1 + 0, 3, ID2SYM(rb_intern("setinstancevariable")), name, inline_storage); -} - -/******************************************************************************/ -/* Compile an AST node using the given compiler */ -/******************************************************************************/ - -static void -yp_compile_node(yp_iseq_compiler_t *compiler, yp_node_t *base_node) { - switch (base_node->type) { - case YP_NODE_ALIAS_NODE: { - yp_alias_node_t *node = (yp_alias_node_t *) base_node; - - push_putspecialobject(compiler, YP_SPECIALOBJECT_VMCORE); - push_putspecialobject(compiler, YP_SPECIALOBJECT_CBASE); - yp_compile_node(compiler, node->new_name); - yp_compile_node(compiler, node->old_name); - push_send(compiler, -3, yp_calldata_new(rb_intern("core#set_method_alias"), YP_CALLDATA_ARGS_SIMPLE, 3), Qnil); - - return; - } - case YP_NODE_AND_NODE: { - yp_and_node_t *node = (yp_and_node_t *) base_node; - - yp_compile_node(compiler, node->left); - push_dup(compiler); - VALUE branchunless = push_branchunless(compiler, Qnil); - - push_pop(compiler); - yp_compile_node(compiler, node->right); - - VALUE label = push_label(compiler); - rb_ary_store(branchunless, 1, label); - - return; - } - case YP_NODE_ARGUMENTS_NODE: { - yp_arguments_node_t *node = (yp_arguments_node_t *) base_node; - yp_node_list_t node_list = node->arguments; - for (size_t index = 0; index < node_list.size; index++) { - yp_compile_node(compiler, node_list.nodes[index]); - } - return; - } - case YP_NODE_ARRAY_NODE: { - yp_array_node_t *node = (yp_array_node_t *) base_node; - yp_node_list_t elements = node->elements; - for (size_t index = 0; index < elements.size; index++) { - yp_compile_node(compiler, elements.nodes[index]); - } - push_newarray(compiler, sizet2int(elements.size)); - return; - } - case YP_NODE_ASSOC_NODE: { - yp_assoc_node_t *node = (yp_assoc_node_t *) base_node; - yp_compile_node(compiler, node->key); - yp_compile_node(compiler, node->value); - return; - } - case YP_NODE_BLOCK_NODE: { - yp_block_node_t *node = (yp_block_node_t *) base_node; - - VALUE optional_labels = rb_ary_new(); - if (node->parameters && - node->parameters->parameters && - node->parameters->parameters->optionals.size > 0) { - compiler->arg_size += node->parameters->parameters->optionals.size; - - yp_node_list_t *optionals = &node->parameters->parameters->optionals; - for (size_t i = 0; i < optionals->size; i++) { - VALUE label = push_label(compiler); - rb_ary_push(optional_labels, label); - yp_compile_node(compiler, optionals->nodes[i]); - } - VALUE label = push_label(compiler); - rb_ary_push(optional_labels, label); - rb_hash_aset(compiler->optionals, ID2SYM(rb_intern("opt")), optional_labels); - - push_ruby_event(compiler, YP_RUBY_EVENT_B_CALL); - push_nop(compiler); - } else { - push_ruby_event(compiler, YP_RUBY_EVENT_B_CALL); - } - - - - if (node->statements) { - yp_compile_node(compiler, node->statements); - } else { - push_putnil(compiler); - } - push_ruby_event(compiler, YP_RUBY_EVENT_B_RETURN); - push_leave(compiler); - return; - } - case YP_NODE_CALL_NODE: { - yp_call_node_t *node = (yp_call_node_t *) base_node; - - ID mid = parse_location_symbol(&node->message_loc); - int flags = 0; - size_t orig_argc; - - if (node->receiver == NULL) { - push_putself(compiler); - } else { - yp_compile_node(compiler, node->receiver); - } - - if (node->arguments == NULL) { - if (flags & YP_CALLDATA_FCALL) flags |= YP_CALLDATA_VCALL; - orig_argc = 0; - } else { - yp_arguments_node_t *arguments = node->arguments; - yp_compile_node(compiler, (yp_node_t *) arguments); - orig_argc = arguments->arguments.size; - } - - VALUE block_iseq = Qnil; - if (node->block != NULL) { - yp_iseq_compiler_t block_compiler; - yp_iseq_compiler_init( - &block_compiler, - compiler, - &node->block->locals, - "block in <compiled>", - YP_ISEQ_TYPE_BLOCK - ); - - yp_compile_node(&block_compiler, (yp_node_t *) node->block); - block_iseq = yp_iseq_new(&block_compiler); - } - - if (block_iseq == Qnil && flags == 0) { - flags |= YP_CALLDATA_ARGS_SIMPLE; - } - - if (node->receiver == NULL) { - flags |= YP_CALLDATA_FCALL; - - if (block_iseq == Qnil && node->arguments == NULL) { - flags |= YP_CALLDATA_VCALL; - } - } - - push_send(compiler, -sizet2int(orig_argc), yp_calldata_new(mid, flags, orig_argc), block_iseq); - return; - } - case YP_NODE_CLASS_VARIABLE_READ_NODE: { - yp_class_variable_read_node_t *node = (yp_class_variable_read_node_t *) base_node; - push_getclassvariable(compiler, ID2SYM(parse_node_symbol((yp_node_t *) node)), yp_inline_storage_new(compiler)); - return; - } - case YP_NODE_CLASS_VARIABLE_WRITE_NODE: { - yp_class_variable_write_node_t *node = (yp_class_variable_write_node_t *) base_node; - if (node->value == NULL) { - rb_raise(rb_eNotImpError, "class variable write without value not implemented"); - } - - yp_compile_node(compiler, node->value); - push_dup(compiler); - push_setclassvariable(compiler, ID2SYM(parse_location_symbol(&node->name_loc)), yp_inline_storage_new(compiler)); - return; - } - case YP_NODE_CONSTANT_PATH_NODE: { - yp_constant_path_node_t *node = (yp_constant_path_node_t *) base_node; - yp_compile_node(compiler, node->parent); - push_putobject(compiler, Qfalse); - push_getconstant(compiler, ID2SYM(parse_node_symbol((yp_node_t *) node->child))); - return; - } - case YP_NODE_CONSTANT_READ_NODE: - push_putnil(compiler); - push_putobject(compiler, Qtrue); - push_getconstant(compiler, ID2SYM(parse_node_symbol((yp_node_t *) base_node))); - return; - case YP_NODE_EMBEDDED_STATEMENTS_NODE: { - yp_embedded_statements_node_t *node = (yp_embedded_statements_node_t *) base_node; - yp_compile_node(compiler, (yp_node_t *) node->statements); - return; - } - case YP_NODE_FALSE_NODE: - push_putobject(compiler, Qfalse); - return; - case YP_NODE_GLOBAL_VARIABLE_READ_NODE: - push_getglobal(compiler, ID2SYM(parse_location_symbol(&base_node->location))); - return; - case YP_NODE_GLOBAL_VARIABLE_WRITE_NODE: { - yp_global_variable_write_node_t *node = (yp_global_variable_write_node_t *) base_node; - - if (node->value == NULL) { - rb_raise(rb_eNotImpError, "global variable write without value not implemented"); - } - - yp_compile_node(compiler, node->value); - push_dup(compiler); - push_setglobal(compiler, ID2SYM(parse_location_symbol(&node->name_loc))); - return; - } - case YP_NODE_HASH_NODE: { - yp_hash_node_t *node = (yp_hash_node_t *) base_node; - yp_node_list_t elements = node->elements; - - for (size_t index = 0; index < elements.size; index++) { - yp_compile_node(compiler, elements.nodes[index]); - } - - push_newhash(compiler, sizet2int(elements.size * 2)); - return; - } - case YP_NODE_INSTANCE_VARIABLE_READ_NODE: - push_getinstancevariable(compiler, ID2SYM(parse_node_symbol((yp_node_t *) base_node)), yp_inline_storage_new(compiler)); - return; - case YP_NODE_INSTANCE_VARIABLE_WRITE_NODE: { - yp_instance_variable_write_node_t *node = (yp_instance_variable_write_node_t *) base_node; - - if (node->value == NULL) { - rb_raise(rb_eNotImpError, "instance variable write without value not implemented"); - } - - yp_compile_node(compiler, node->value); - push_dup(compiler); - push_setinstancevariable(compiler, ID2SYM(parse_location_symbol(&node->name_loc)), yp_inline_storage_new(compiler)); - return; - } - case YP_NODE_INTEGER_NODE: - push_putobject(compiler, parse_number(base_node->location.start, base_node->location.end)); - return; - case YP_NODE_INTERPOLATED_STRING_NODE: { - yp_interpolated_string_node_t *node = (yp_interpolated_string_node_t *) base_node; - - for (size_t index = 0; index < node->parts.size; index++) { - yp_node_t *part = node->parts.nodes[index]; - - switch (part->type) { - case YP_NODE_STRING_NODE: { - yp_string_node_t *string_node = (yp_string_node_t *) part; - push_putobject(compiler, parse_string(&string_node->unescaped)); - break; - } - default: - yp_compile_node(compiler, part); - push_dup(compiler); - push_objtostring(compiler, yp_calldata_new(rb_intern("to_s"), YP_CALLDATA_FCALL | YP_CALLDATA_ARGS_SIMPLE, 0)); - push_anytostring(compiler); - break; - } - } - - push_concatstrings(compiler, sizet2int(node->parts.size)); - return; - } - case YP_NODE_KEYWORD_HASH_NODE: { - yp_keyword_hash_node_t *node = (yp_keyword_hash_node_t *) base_node; - yp_node_list_t elements = node->elements; - - for (size_t index = 0; index < elements.size; index++) { - yp_compile_node(compiler, elements.nodes[index]); - } - - push_newhash(compiler, sizet2int(elements.size * 2)); - return; - } - case YP_NODE_LOCAL_VARIABLE_READ_NODE: { - yp_local_variable_read_node_t *node = (yp_local_variable_read_node_t *) base_node; - int index = local_index(compiler, node->constant_id, node->depth); - - push_getlocal(compiler, INT2FIX(index), INT2FIX(node->depth)); - return; - } - case YP_NODE_LOCAL_VARIABLE_WRITE_NODE: { - yp_local_variable_write_node_t *node = (yp_local_variable_write_node_t *) base_node; - - if (node->value == NULL) { - rb_raise(rb_eNotImpError, "local variable write without value not implemented"); - } - - int index = local_index(compiler, node->constant_id, node->depth); - - yp_compile_node(compiler, node->value); - push_dup(compiler); - push_setlocal(compiler, INT2FIX(index), INT2FIX(node->depth)); - return; - } - case YP_NODE_NIL_NODE: - push_putnil(compiler); - return; - case YP_NODE_OR_NODE: { - yp_or_node_t *node = (yp_or_node_t *) base_node; - - yp_compile_node(compiler, node->left); - push_dup(compiler); - VALUE branchif = push_branchif(compiler, Qnil); - - push_pop(compiler); - yp_compile_node(compiler, node->right); - - VALUE label = push_label(compiler); - rb_ary_store(branchif, 1, label); - - return; - } - case YP_NODE_PARENTHESES_NODE: { - yp_parentheses_node_t *node = (yp_parentheses_node_t *) base_node; - - if (node->statements == NULL) { - push_putnil(compiler); - } else { - yp_compile_node(compiler, node->statements); - } - - return; - } - case YP_NODE_PROGRAM_NODE: { - yp_program_node_t *node = (yp_program_node_t *) base_node; - - if (node->statements->body.size == 0) { - push_putnil(compiler); - } else { - yp_compile_node(compiler, (yp_node_t *) node->statements); - } - - push_leave(compiler); - return; - } - case YP_NODE_RANGE_NODE: { - yp_range_node_t *node = (yp_range_node_t *) base_node; - - if (node->left == NULL) { - push_putnil(compiler); - } else { - yp_compile_node(compiler, node->left); - } - - if (node->right == NULL) { - push_putnil(compiler); - } else { - yp_compile_node(compiler, node->right); - } - - push_newrange(compiler, INT2FIX((node->operator_loc.end - node->operator_loc.start) == 3)); - return; - } - case YP_NODE_SELF_NODE: - push_putself(compiler); - return; - case YP_NODE_STATEMENTS_NODE: { - yp_statements_node_t *node = (yp_statements_node_t *) base_node; - yp_node_list_t node_list = node->body; - for (size_t index = 0; index < node_list.size; index++) { - yp_compile_node(compiler, node_list.nodes[index]); - if (index < node_list.size - 1) push_pop(compiler); - } - return; - } - case YP_NODE_STRING_NODE: { - yp_string_node_t *node = (yp_string_node_t *) base_node; - push_putstring(compiler, parse_string(&node->unescaped)); - return; - } - case YP_NODE_SYMBOL_NODE: { - yp_symbol_node_t *node = (yp_symbol_node_t *) base_node; - push_putobject(compiler, ID2SYM(parse_string_symbol(&node->unescaped))); - return; - } - case YP_NODE_TRUE_NODE: - push_putobject(compiler, Qtrue); - return; - case YP_NODE_UNDEF_NODE: { - yp_undef_node_t *node = (yp_undef_node_t *) base_node; - - for (size_t index = 0; index < node->names.size; index++) { - push_putspecialobject(compiler, YP_SPECIALOBJECT_VMCORE); - push_putspecialobject(compiler, YP_SPECIALOBJECT_CBASE); - yp_compile_node(compiler, node->names.nodes[index]); - push_send(compiler, -2, yp_calldata_new(rb_intern("core#undef_method"), YP_CALLDATA_ARGS_SIMPLE, 2), Qnil); - - if (index < node->names.size - 1) push_pop(compiler); - } - - return; - } - case YP_NODE_X_STRING_NODE: { - yp_x_string_node_t *node = (yp_x_string_node_t *) base_node; - push_putself(compiler); - push_putobject(compiler, parse_string(&node->unescaped)); - push_send(compiler, -1, yp_calldata_new(rb_intern("`"), YP_CALLDATA_FCALL | YP_CALLDATA_ARGS_SIMPLE, 1), Qnil); - return; - } - case YP_NODE_OPTIONAL_PARAMETER_NODE: { - yp_optional_parameter_node_t *node = (yp_optional_parameter_node_t *) base_node; - int depth = 0; - int index = local_index(compiler, node->constant_id, depth); - yp_compile_node(compiler, node->value); - push_setlocal(compiler, INT2FIX(index), INT2FIX(depth)); - break; - } - default: - rb_raise(rb_eNotImpError, "node type %d not implemented", base_node->type); - return; - } -} - -// This function compiles the given node into a list of instructions. -VALUE -yp_compile(yp_node_t *node) { - assert(node->type == YP_NODE_PROGRAM_NODE); - - yp_iseq_compiler_t compiler; - yp_iseq_compiler_init( - &compiler, - NULL, - &((yp_program_node_t *) node)->locals, - "<compiled>", - YP_ISEQ_TYPE_TOP - ); - - yp_compile_node(&compiler, node); - return yp_iseq_new(&compiler); -} diff --git a/yarp/config.h b/yarp/config.h new file mode 100644 index 0000000000..5a5987fa44 --- /dev/null +++ b/yarp/config.h @@ -0,0 +1 @@ +#include "ruby/config.h" diff --git a/yarp/defines.h b/yarp/defines.h index f447333542..e6a90bb518 100644 --- a/yarp/defines.h +++ b/yarp/defines.h @@ -1,8 +1,20 @@ #ifndef YARP_DEFINES_H #define YARP_DEFINES_H +// This file should be included first by any *.h or *.c in YARP + +#include "yarp/config.h" + +#include <ctype.h> +#include <stdarg.h> +#include <stddef.h> +#include <stdio.h> +#include <string.h> + // YP_EXPORTED_FUNCTION -#if defined(_WIN32) +#if defined(YP_STATIC) +# define YP_EXPORTED_FUNCTION +#elif defined(_WIN32) # define YP_EXPORTED_FUNCTION __declspec(dllexport) extern #else # ifndef YP_EXPORTED_FUNCTION @@ -16,9 +28,9 @@ // YP_ATTRIBUTE_UNUSED #if defined(__GNUC__) -# define YP_ATTRIBUTE_UNUSED __attribute__((unused)) +# define YP_ATTRIBUTE_UNUSED __attribute__((unused)) #else -# define YP_ATTRIBUTE_UNUSED +# define YP_ATTRIBUTE_UNUSED #endif // inline @@ -26,4 +38,13 @@ # define inline __inline #endif +int yp_strncasecmp(const char *string1, const char *string2, size_t length); + +int yp_snprintf(char *dest, YP_ATTRIBUTE_UNUSED size_t size, const char *format, ...); + +#if defined(HAVE_SNPRINTF) + // We use snprintf if it's available +# define yp_snprintf snprintf +#endif + #endif diff --git a/yarp/diagnostic.h b/yarp/diagnostic.h index b604abb0e9..bcbee5380c 100644 --- a/yarp/diagnostic.h +++ b/yarp/diagnostic.h @@ -2,12 +2,11 @@ #define YARP_DIAGNOSTIC_H #include "yarp/defines.h" +#include "yarp/util/yp_list.h" #include <stdbool.h> #include <stdlib.h> -#include "yarp/util/yp_list.h" - // This struct represents a diagnostic found during parsing. typedef struct { yp_list_node_t node; diff --git a/yarp/enc/yp_ascii.c b/yarp/enc/yp_ascii.c index d891108c6b..655dd49fa6 100644 --- a/yarp/enc/yp_ascii.c +++ b/yarp/enc/yp_ascii.c @@ -51,7 +51,8 @@ yp_encoding_t yp_encoding_ascii = { .char_width = yp_encoding_ascii_char_width, .alnum_char = yp_encoding_ascii_alnum_char, .alpha_char = yp_encoding_ascii_alpha_char, - .isupper_char = yp_encoding_ascii_isupper_char + .isupper_char = yp_encoding_ascii_isupper_char, + .multibyte = false }; yp_encoding_t yp_encoding_ascii_8bit = { @@ -60,4 +61,5 @@ yp_encoding_t yp_encoding_ascii_8bit = { .alnum_char = yp_encoding_ascii_alnum_char, .alpha_char = yp_encoding_ascii_alpha_char, .isupper_char = yp_encoding_ascii_isupper_char, + .multibyte = false }; diff --git a/yarp/enc/yp_big5.c b/yarp/enc/yp_big5.c index 1b8024e082..23f90c0297 100644 --- a/yarp/enc/yp_big5.c +++ b/yarp/enc/yp_big5.c @@ -74,5 +74,6 @@ yp_encoding_t yp_encoding_big5 = { .char_width = yp_encoding_big5_char_width, .alnum_char = yp_encoding_big5_alnum_char, .alpha_char = yp_encoding_big5_alpha_char, - .isupper_char = yp_encoding_big5_isupper_char + .isupper_char = yp_encoding_big5_isupper_char, + .multibyte = true }; diff --git a/yarp/enc/yp_encoding.h b/yarp/enc/yp_encoding.h index 8601fa8f33..24714bd41f 100644 --- a/yarp/enc/yp_encoding.h +++ b/yarp/enc/yp_encoding.h @@ -12,11 +12,28 @@ // Each callback should return the number of bytes, or 0 if the next bytes are // invalid for the encoding and type. typedef struct { - const char *name; + // Return the number of bytes that the next character takes if it is valid + // in the encoding. size_t (*char_width)(const char *c); + + // Return the number of bytes that the next character takes if it is valid + // in the encoding and is alphabetical. size_t (*alpha_char)(const char *c); + + // Return the number of bytes that the next character takes if it is valid + // in the encoding and is alphanumeric. size_t (*alnum_char)(const char *c); + + // Return true if the next character is valid in the encoding and is an + // uppercase character. bool (*isupper_char)(const char *c); + + // The name of the encoding. This should correspond to a value that can be + // passed to Encoding.find in Ruby. + const char *name; + + // Return true if the encoding is a multibyte encoding. + bool multibyte; } yp_encoding_t; // These bits define the location of each bit of metadata within the various diff --git a/yarp/enc/yp_euc_jp.c b/yarp/enc/yp_euc_jp.c index 1127e4de1b..3a616e230a 100644 --- a/yarp/enc/yp_euc_jp.c +++ b/yarp/enc/yp_euc_jp.c @@ -77,5 +77,6 @@ yp_encoding_t yp_encoding_euc_jp = { .char_width = yp_encoding_euc_jp_char_width, .alnum_char = yp_encoding_euc_jp_alnum_char, .alpha_char = yp_encoding_euc_jp_alpha_char, - .isupper_char = yp_encoding_euc_jp_isupper_char + .isupper_char = yp_encoding_euc_jp_isupper_char, + .multibyte = true }; diff --git a/yarp/enc/yp_gbk.c b/yarp/enc/yp_gbk.c index b2e3809515..3daa1ee3f3 100644 --- a/yarp/enc/yp_gbk.c +++ b/yarp/enc/yp_gbk.c @@ -80,5 +80,6 @@ yp_encoding_t yp_encoding_gbk = { .char_width = yp_encoding_gbk_char_width, .alnum_char = yp_encoding_gbk_alnum_char, .alpha_char = yp_encoding_gbk_alpha_char, - .isupper_char = yp_encoding_gbk_isupper_char + .isupper_char = yp_encoding_gbk_isupper_char, + .multibyte = true }; diff --git a/yarp/enc/yp_iso_8859_1.c b/yarp/enc/yp_iso_8859_1.c index 0987a37f91..e56a47d223 100644 --- a/yarp/enc/yp_iso_8859_1.c +++ b/yarp/enc/yp_iso_8859_1.c @@ -45,5 +45,6 @@ yp_encoding_t yp_encoding_iso_8859_1 = { .char_width = yp_encoding_single_char_width, .alnum_char = yp_encoding_iso_8859_1_alnum_char, .alpha_char = yp_encoding_iso_8859_1_alpha_char, - .isupper_char = yp_encoding_iso_8859_1_isupper_char + .isupper_char = yp_encoding_iso_8859_1_isupper_char, + .multibyte = false }; diff --git a/yarp/enc/yp_iso_8859_10.c b/yarp/enc/yp_iso_8859_10.c index 73d2392f89..d3abf7d09f 100644 --- a/yarp/enc/yp_iso_8859_10.c +++ b/yarp/enc/yp_iso_8859_10.c @@ -45,5 +45,6 @@ yp_encoding_t yp_encoding_iso_8859_10 = { .char_width = yp_encoding_single_char_width, .alnum_char = yp_encoding_iso_8859_10_alnum_char, .alpha_char = yp_encoding_iso_8859_10_alpha_char, - .isupper_char = yp_encoding_iso_8859_10_isupper_char + .isupper_char = yp_encoding_iso_8859_10_isupper_char, + .multibyte = false }; diff --git a/yarp/enc/yp_iso_8859_11.c b/yarp/enc/yp_iso_8859_11.c index ea01d60a95..45b55fb1ef 100644 --- a/yarp/enc/yp_iso_8859_11.c +++ b/yarp/enc/yp_iso_8859_11.c @@ -45,5 +45,6 @@ yp_encoding_t yp_encoding_iso_8859_11 = { .char_width = yp_encoding_single_char_width, .alnum_char = yp_encoding_iso_8859_11_alnum_char, .alpha_char = yp_encoding_iso_8859_11_alpha_char, - .isupper_char = yp_encoding_iso_8859_11_isupper_char + .isupper_char = yp_encoding_iso_8859_11_isupper_char, + .multibyte = false }; diff --git a/yarp/enc/yp_iso_8859_13.c b/yarp/enc/yp_iso_8859_13.c index 8ca4883acd..4504779f36 100644 --- a/yarp/enc/yp_iso_8859_13.c +++ b/yarp/enc/yp_iso_8859_13.c @@ -45,5 +45,6 @@ yp_encoding_t yp_encoding_iso_8859_13 = { .char_width = yp_encoding_single_char_width, .alnum_char = yp_encoding_iso_8859_13_alnum_char, .alpha_char = yp_encoding_iso_8859_13_alpha_char, - .isupper_char = yp_encoding_iso_8859_13_isupper_char + .isupper_char = yp_encoding_iso_8859_13_isupper_char, + .multibyte = false }; diff --git a/yarp/enc/yp_iso_8859_14.c b/yarp/enc/yp_iso_8859_14.c index 0ef6868916..7c25610bd0 100644 --- a/yarp/enc/yp_iso_8859_14.c +++ b/yarp/enc/yp_iso_8859_14.c @@ -45,5 +45,6 @@ yp_encoding_t yp_encoding_iso_8859_14 = { .char_width = yp_encoding_single_char_width, .alnum_char = yp_encoding_iso_8859_14_alnum_char, .alpha_char = yp_encoding_iso_8859_14_alpha_char, - .isupper_char = yp_encoding_iso_8859_14_isupper_char + .isupper_char = yp_encoding_iso_8859_14_isupper_char, + .multibyte = false }; diff --git a/yarp/enc/yp_iso_8859_15.c b/yarp/enc/yp_iso_8859_15.c index 7ac4c45986..e41cc6fbb0 100644 --- a/yarp/enc/yp_iso_8859_15.c +++ b/yarp/enc/yp_iso_8859_15.c @@ -45,5 +45,6 @@ yp_encoding_t yp_encoding_iso_8859_15 = { .char_width = yp_encoding_single_char_width, .alnum_char = yp_encoding_iso_8859_15_alnum_char, .alpha_char = yp_encoding_iso_8859_15_alpha_char, - .isupper_char = yp_encoding_iso_8859_15_isupper_char + .isupper_char = yp_encoding_iso_8859_15_isupper_char, + .multibyte = false }; diff --git a/yarp/enc/yp_iso_8859_16.c b/yarp/enc/yp_iso_8859_16.c index cd932d554c..f30067f82a 100644 --- a/yarp/enc/yp_iso_8859_16.c +++ b/yarp/enc/yp_iso_8859_16.c @@ -45,5 +45,6 @@ yp_encoding_t yp_encoding_iso_8859_16 = { .char_width = yp_encoding_single_char_width, .alnum_char = yp_encoding_iso_8859_16_alnum_char, .alpha_char = yp_encoding_iso_8859_16_alpha_char, - .isupper_char = yp_encoding_iso_8859_16_isupper_char + .isupper_char = yp_encoding_iso_8859_16_isupper_char, + .multibyte = false }; diff --git a/yarp/enc/yp_iso_8859_2.c b/yarp/enc/yp_iso_8859_2.c index 067db0e95a..af95362761 100644 --- a/yarp/enc/yp_iso_8859_2.c +++ b/yarp/enc/yp_iso_8859_2.c @@ -45,5 +45,6 @@ yp_encoding_t yp_encoding_iso_8859_2 = { .char_width = yp_encoding_single_char_width, .alnum_char = yp_encoding_iso_8859_2_alnum_char, .alpha_char = yp_encoding_iso_8859_2_alpha_char, - .isupper_char = yp_encoding_iso_8859_2_isupper_char + .isupper_char = yp_encoding_iso_8859_2_isupper_char, + .multibyte = false }; diff --git a/yarp/enc/yp_iso_8859_3.c b/yarp/enc/yp_iso_8859_3.c index 5373b89cc1..382a9f239a 100644 --- a/yarp/enc/yp_iso_8859_3.c +++ b/yarp/enc/yp_iso_8859_3.c @@ -45,5 +45,6 @@ yp_encoding_t yp_encoding_iso_8859_3 = { .char_width = yp_encoding_single_char_width, .alnum_char = yp_encoding_iso_8859_3_alnum_char, .alpha_char = yp_encoding_iso_8859_3_alpha_char, - .isupper_char = yp_encoding_iso_8859_3_isupper_char + .isupper_char = yp_encoding_iso_8859_3_isupper_char, + .multibyte = false }; diff --git a/yarp/enc/yp_iso_8859_4.c b/yarp/enc/yp_iso_8859_4.c index ad13aca6b9..5f7d87ecca 100644 --- a/yarp/enc/yp_iso_8859_4.c +++ b/yarp/enc/yp_iso_8859_4.c @@ -45,5 +45,6 @@ yp_encoding_t yp_encoding_iso_8859_4 = { .char_width = yp_encoding_single_char_width, .alnum_char = yp_encoding_iso_8859_4_alnum_char, .alpha_char = yp_encoding_iso_8859_4_alpha_char, - .isupper_char = yp_encoding_iso_8859_4_isupper_char + .isupper_char = yp_encoding_iso_8859_4_isupper_char, + .multibyte = false }; diff --git a/yarp/enc/yp_iso_8859_5.c b/yarp/enc/yp_iso_8859_5.c index 4fc201fe28..ff6d4105d1 100644 --- a/yarp/enc/yp_iso_8859_5.c +++ b/yarp/enc/yp_iso_8859_5.c @@ -45,5 +45,6 @@ yp_encoding_t yp_encoding_iso_8859_5 = { .char_width = yp_encoding_single_char_width, .alnum_char = yp_encoding_iso_8859_5_alnum_char, .alpha_char = yp_encoding_iso_8859_5_alpha_char, - .isupper_char = yp_encoding_iso_8859_5_isupper_char + .isupper_char = yp_encoding_iso_8859_5_isupper_char, + .multibyte = false }; diff --git a/yarp/enc/yp_iso_8859_6.c b/yarp/enc/yp_iso_8859_6.c index dad9bb42cb..b32d3081cd 100644 --- a/yarp/enc/yp_iso_8859_6.c +++ b/yarp/enc/yp_iso_8859_6.c @@ -45,5 +45,6 @@ yp_encoding_t yp_encoding_iso_8859_6 = { .char_width = yp_encoding_single_char_width, .alnum_char = yp_encoding_iso_8859_6_alnum_char, .alpha_char = yp_encoding_iso_8859_6_alpha_char, - .isupper_char = yp_encoding_iso_8859_6_isupper_char + .isupper_char = yp_encoding_iso_8859_6_isupper_char, + .multibyte = false }; diff --git a/yarp/enc/yp_iso_8859_7.c b/yarp/enc/yp_iso_8859_7.c index e080102ef0..0ccea26f50 100644 --- a/yarp/enc/yp_iso_8859_7.c +++ b/yarp/enc/yp_iso_8859_7.c @@ -45,5 +45,6 @@ yp_encoding_t yp_encoding_iso_8859_7 = { .char_width = yp_encoding_single_char_width, .alnum_char = yp_encoding_iso_8859_7_alnum_char, .alpha_char = yp_encoding_iso_8859_7_alpha_char, - .isupper_char = yp_encoding_iso_8859_7_isupper_char + .isupper_char = yp_encoding_iso_8859_7_isupper_char, + .multibyte = false }; diff --git a/yarp/enc/yp_iso_8859_8.c b/yarp/enc/yp_iso_8859_8.c index 9216155fde..718ba8f5b4 100644 --- a/yarp/enc/yp_iso_8859_8.c +++ b/yarp/enc/yp_iso_8859_8.c @@ -45,5 +45,6 @@ yp_encoding_t yp_encoding_iso_8859_8 = { .char_width = yp_encoding_single_char_width, .alnum_char = yp_encoding_iso_8859_8_alnum_char, .alpha_char = yp_encoding_iso_8859_8_alpha_char, - .isupper_char = yp_encoding_iso_8859_8_isupper_char + .isupper_char = yp_encoding_iso_8859_8_isupper_char, + .multibyte = false }; diff --git a/yarp/enc/yp_iso_8859_9.c b/yarp/enc/yp_iso_8859_9.c index 67bad2c0e8..3dab740382 100644 --- a/yarp/enc/yp_iso_8859_9.c +++ b/yarp/enc/yp_iso_8859_9.c @@ -45,5 +45,6 @@ yp_encoding_t yp_encoding_iso_8859_9 = { .char_width = yp_encoding_single_char_width, .alnum_char = yp_encoding_iso_8859_9_alnum_char, .alpha_char = yp_encoding_iso_8859_9_alpha_char, - .isupper_char = yp_encoding_iso_8859_9_isupper_char + .isupper_char = yp_encoding_iso_8859_9_isupper_char, + .multibyte = false }; diff --git a/yarp/enc/yp_koi8_r.c b/yarp/enc/yp_koi8_r.c index db23aecc2c..cc77889610 100644 --- a/yarp/enc/yp_koi8_r.c +++ b/yarp/enc/yp_koi8_r.c @@ -51,5 +51,6 @@ yp_encoding_t yp_encoding_koi8_r = { .char_width = yp_encoding_koi8_r_char_width, .alnum_char = yp_encoding_koi8_r_alnum_char, .alpha_char = yp_encoding_koi8_r_alpha_char, - .isupper_char = yp_encoding_koi8_r_isupper_char + .isupper_char = yp_encoding_koi8_r_isupper_char, + .multibyte = false }; diff --git a/yarp/enc/yp_shift_jis.c b/yarp/enc/yp_shift_jis.c index d882b23045..6977d3ce98 100644 --- a/yarp/enc/yp_shift_jis.c +++ b/yarp/enc/yp_shift_jis.c @@ -77,5 +77,6 @@ yp_encoding_t yp_encoding_shift_jis = { .char_width = yp_encoding_shift_jis_char_width, .alnum_char = yp_encoding_shift_jis_alnum_char, .alpha_char = yp_encoding_shift_jis_alpha_char, - .isupper_char = yp_encoding_shift_jis_isupper_char + .isupper_char = yp_encoding_shift_jis_isupper_char, + .multibyte = true }; diff --git a/yarp/enc/yp_unicode.c b/yarp/enc/yp_unicode.c index cb63dd55d9..63cbf418dd 100644 --- a/yarp/enc/yp_unicode.c +++ b/yarp/enc/yp_unicode.c @@ -2230,7 +2230,7 @@ utf_8_codepoint(const unsigned char *c, size_t *width) { codepoint = (state != 0) ? (byte & 0x3fu) | (codepoint << 6) : - (0xff >> type) & (byte); + (0xffu >> type) & (byte); state = utf_8_dfa[256 + (state * 16) + type]; if (!state) { @@ -2312,5 +2312,6 @@ yp_encoding_t yp_encoding_utf_8 = { .char_width = yp_encoding_utf_8_char_width, .alnum_char = yp_encoding_utf_8_alnum_char, .alpha_char = yp_encoding_utf_8_alpha_char, - .isupper_char = yp_encoding_utf_8_isupper_char + .isupper_char = yp_encoding_utf_8_isupper_char, + .multibyte = true }; diff --git a/yarp/enc/yp_windows_1251.c b/yarp/enc/yp_windows_1251.c index 8573ef0a5d..37344e1ebf 100644 --- a/yarp/enc/yp_windows_1251.c +++ b/yarp/enc/yp_windows_1251.c @@ -45,5 +45,6 @@ yp_encoding_t yp_encoding_windows_1251 = { .char_width = yp_encoding_single_char_width, .alnum_char = yp_encoding_windows_1251_alnum_char, .alpha_char = yp_encoding_windows_1251_alpha_char, - .isupper_char = yp_encoding_windows_1251_isupper_char + .isupper_char = yp_encoding_windows_1251_isupper_char, + .multibyte = false }; diff --git a/yarp/enc/yp_windows_1252.c b/yarp/enc/yp_windows_1252.c index 3bcf24819b..a62d4f4a21 100644 --- a/yarp/enc/yp_windows_1252.c +++ b/yarp/enc/yp_windows_1252.c @@ -45,5 +45,6 @@ yp_encoding_t yp_encoding_windows_1252 = { .char_width = yp_encoding_single_char_width, .alnum_char = yp_encoding_windows_1252_alnum_char, .alpha_char = yp_encoding_windows_1252_alpha_char, - .isupper_char = yp_encoding_windows_1252_isupper_char + .isupper_char = yp_encoding_windows_1252_isupper_char, + .multibyte = false }; diff --git a/yarp/enc/yp_windows_31j.c b/yarp/enc/yp_windows_31j.c index 18afebdef7..9aa62c9b10 100644 --- a/yarp/enc/yp_windows_31j.c +++ b/yarp/enc/yp_windows_31j.c @@ -77,5 +77,6 @@ yp_encoding_t yp_encoding_windows_31j = { .char_width = yp_encoding_windows_31j_char_width, .alnum_char = yp_encoding_windows_31j_alnum_char, .alpha_char = yp_encoding_windows_31j_alpha_char, - .isupper_char = yp_encoding_windows_31j_isupper_char + .isupper_char = yp_encoding_windows_31j_isupper_char, + .multibyte = true }; diff --git a/yarp/extension.c b/yarp/extension.c index 222dcb945a..41031ac82f 100644 --- a/yarp/extension.c +++ b/yarp/extension.c @@ -1,6 +1,7 @@ #include "yarp/extension.h" VALUE rb_cYARP; +VALUE rb_cYARPSource; VALUE rb_cYARPToken; VALUE rb_cYARPLocation; @@ -9,51 +10,97 @@ VALUE rb_cYARPParseError; VALUE rb_cYARPParseWarning; VALUE rb_cYARPParseResult; -// Represents a source of Ruby code. It can either be coming from a file or a -// string. If it's a file, it's going to mmap the contents of the file. If it's -// a string it's going to just point to the contents of the string. +/******************************************************************************/ +/* IO of Ruby code */ +/******************************************************************************/ + +// Represents an input of Ruby code. It can either be coming from a file or a +// string. If it's a file, we'll use demand paging to read the contents of the +// file into a string. If it's already a string, we'll reference it directly. typedef struct { - enum { SOURCE_FILE, SOURCE_STRING } type; const char *source; size_t size; -} source_t; +} input_t; + +// Check if the given filepath is a string. If it's nil, then return NULL. If +// it's not a string, then raise a type error. Otherwise return the filepath as +// a C string. +static const char * +check_filepath(VALUE filepath) { + // If the filepath is nil, then we don't need to do anything. + if (NIL_P(filepath)) { + return NULL; + } + + // Check if the filepath is a string. If it's not, then raise a type error. + if (!RB_TYPE_P(filepath, T_STRING)) { + rb_raise(rb_eTypeError, "wrong argument type %"PRIsVALUE" (expected String)", rb_obj_class(filepath)); + } + + // Otherwise, return the filepath as a C string. + return StringValueCStr(filepath); +} // Read the file indicated by the filepath parameter into source and load its -// contents and size into the given source_t. +// contents and size into the given input_t. +// +// We want to use demand paging as much as possible in order to avoid having to +// read the entire file into memory (which could be detrimental to performance +// for large files). This means that if we're on windows we'll use +// `MapViewOfFile`, on POSIX systems that have access to `mmap` we'll use +// `mmap`, and on other POSIX systems we'll use `read`. static int -source_file_load(source_t *source, VALUE filepath) { +input_load_filepath(input_t *input, const char *filepath) { #ifdef _WIN32 - HANDLE file = CreateFile( - StringValueCStr(filepath), - GENERIC_READ, - 0, - NULL, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, - NULL - ); + // Open the file for reading. + HANDLE file = CreateFile(filepath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (file == INVALID_HANDLE_VALUE) { - perror("Invalid handle for file"); + perror("CreateFile failed"); return 1; } + // Get the file size. DWORD file_size = GetFileSize(file, NULL); - source->source = malloc(file_size); + if (file_size == INVALID_FILE_SIZE) { + CloseHandle(file); + perror("GetFileSize failed"); + return 1; + } + + // If the file is empty, then we don't need to do anything else, we'll set + // the source to a constant empty string and return. + if (!file_size) { + CloseHandle(file); + input->size = 0; + input->source = ""; + return 0; + } + + // Create a mapping of the file. + HANDLE mapping = CreateFileMapping(file, NULL, PAGE_READONLY, 0, 0, NULL); + if (mapping == NULL) { + CloseHandle(file); + perror("CreateFileMapping failed"); + return 1; + } - DWORD bytes_read; - BOOL success = ReadFile(file, DISCARD_CONST_QUAL(void *, source->source), file_size, &bytes_read, NULL); + // Map the file into memory. + input->source = (const char *) MapViewOfFile(mapping, FILE_MAP_READ, 0, 0, 0); + CloseHandle(mapping); CloseHandle(file); - if (!success) { - perror("ReadFile failed"); + if (input->source == NULL) { + perror("MapViewOfFile failed"); return 1; } - source->size = (size_t) file_size; + // Set the size of the source. + input->size = (size_t) file_size; return 0; #else // Open the file for reading - int fd = open(StringValueCStr(filepath), O_RDONLY); + int fd = open(filepath, O_RDONLY); if (fd == -1) { perror("open"); return 1; @@ -68,30 +115,30 @@ source_file_load(source_t *source, VALUE filepath) { } // mmap the file descriptor to virtually get the contents - source->size = sb.st_size; + input->size = sb.st_size; #ifdef HAVE_MMAP - if (!source->size) { + if (!input->size) { close(fd); - source->source = ""; + input->source = ""; return 0; } - char * res = mmap(NULL, source->size, PROT_READ, MAP_PRIVATE, fd, 0); - if (res == MAP_FAILED) { + const char *result = mmap(NULL, input->size, PROT_READ, MAP_PRIVATE, fd, 0); + if (result == MAP_FAILED) { perror("Map failed"); return 1; } else { - source->source = res; + input->source = result; } #else - source->source = malloc(source->size); - if (source->source == NULL) return 1; + input->source = malloc(input->size); + if (input->source == NULL) return 1; - ssize_t read_size = read(fd, (void *)source->source, source->size); - if (read_size < 0 || (size_t)read_size != source->size) { + ssize_t read_size = read(fd, (void *) input->source, input->size); + if (read_size < 0 || (size_t)read_size != input->size) { perror("Read size is incorrect"); - free((void *)source->source); + free((void *) input->source); return 1; } #endif @@ -101,86 +148,106 @@ source_file_load(source_t *source, VALUE filepath) { #endif } -// Load the contents and size of the given string into the given source_t. +// Load the contents and size of the given string into the given input_t. static void -source_string_load(source_t *source, VALUE string) { - *source = (source_t) { - .type = SOURCE_STRING, - .source = RSTRING_PTR(string), - .size = RSTRING_LEN(string), - }; +input_load_string(input_t *input, VALUE string) { + // Check if the string is a string. If it's not, then raise a type error. + if (!RB_TYPE_P(string, T_STRING)) { + rb_raise(rb_eTypeError, "wrong argument type %"PRIsVALUE" (expected String)", rb_obj_class(string)); + } + + input->source = RSTRING_PTR(string); + input->size = RSTRING_LEN(string); } -// Free any resources associated with the given source_t. +// Free any resources associated with the given input_t. This is the corollary +// function to source_file_load. It will unmap the file if it was mapped, or +// free the memory if it was allocated. static void -source_file_unload(source_t *source) { -#ifdef _WIN32 - free((void *)source->source); -#else -#ifdef HAVE_MMAP - munmap((void *)source->source, source->size); +input_unload_filepath(input_t *input) { + // We don't need to free anything with 0 sized files because we handle that + // with a constant string instead. + if (!input->size) return; + void *memory = (void *) input->source; + +#if defined(_WIN32) + UnmapViewOfFile(memory); +#elif defined(HAVE_MMAP) + munmap(memory, input->size); #else - free((void *)source->source); -#endif + free(memory); #endif } -// Dump the AST corresponding to the given source to a string. +/******************************************************************************/ +/* Serializing the AST */ +/******************************************************************************/ + +// Dump the AST corresponding to the given input to a string. static VALUE -dump_source(source_t *source, const char *filepath) { +dump_input(input_t *input, const char *filepath) { + yp_buffer_t buffer; + if (!yp_buffer_init(&buffer)) { + rb_raise(rb_eNoMemError, "failed to allocate memory"); + } + yp_parser_t parser; - yp_parser_init(&parser, source->source, source->size, filepath); + yp_parser_init(&parser, input->source, input->size, filepath); yp_node_t *node = yp_parse(&parser); - - yp_buffer_t buffer; - if (!yp_buffer_init(&buffer)) rb_raise(rb_eNoMemError, "failed to allocate memory"); - yp_serialize(&parser, node, &buffer); - VALUE dumped = rb_str_new(buffer.value, buffer.length); + VALUE result = rb_str_new(buffer.value, buffer.length); yp_node_destroy(&parser, node); yp_buffer_free(&buffer); yp_parser_free(&parser); - return dumped; + return result; } // Dump the AST corresponding to the given string to a string. static VALUE -dump(VALUE self, VALUE string, VALUE filepath) { - source_t source; - source_string_load(&source, string); - char *str = NULL; - - if (filepath != Qnil) { - str = StringValueCStr(filepath); - } - - return dump_source(&source, str); +dump(int argc, VALUE *argv, VALUE self) { + VALUE string; + VALUE filepath; + rb_scan_args(argc, argv, "11", &string, &filepath); + + input_t input; + input_load_string(&input, string); + return dump_input(&input, check_filepath(filepath)); } // Dump the AST corresponding to the given file to a string. static VALUE dump_file(VALUE self, VALUE filepath) { - source_t source; - if (source_file_load(&source, filepath) != 0) return Qnil; + input_t input; + + const char *checked = check_filepath(filepath); + if (input_load_filepath(&input, checked) != 0) return Qnil; + + VALUE value = dump_input(&input, checked); + input_unload_filepath(&input); - VALUE value = dump_source(&source, StringValueCStr(filepath)); - source_file_unload(&source); return value; } +/******************************************************************************/ +/* Extracting values for the parse result */ +/******************************************************************************/ + // Extract the comments out of the parser into an array. static VALUE -parser_comments(yp_parser_t *parser) { +parser_comments(yp_parser_t *parser, VALUE source) { VALUE comments = rb_ary_new(); - yp_comment_t *comment; - for (comment = (yp_comment_t *) parser->comment_list.head; comment != NULL; comment = (yp_comment_t *) comment->node.next) { - VALUE location_argv[] = { LONG2FIX(comment->start - parser->start), LONG2FIX(comment->end - parser->start) }; - VALUE type; + for (yp_comment_t *comment = (yp_comment_t *) parser->comment_list.head; comment != NULL; comment = (yp_comment_t *) comment->node.next) { + VALUE location_argv[] = { + source, + LONG2FIX(comment->start - parser->start), + LONG2FIX(comment->end - parser->start) + }; + VALUE type; switch (comment->type) { case YP_COMMENT_INLINE: type = ID2SYM(rb_intern("inline")); @@ -196,7 +263,7 @@ parser_comments(yp_parser_t *parser) { break; } - VALUE comment_argv[] = { type, rb_class_new_instance(2, location_argv, rb_cYARPLocation) }; + VALUE comment_argv[] = { type, rb_class_new_instance(3, location_argv, rb_cYARPLocation) }; rb_ary_push(comments, rb_class_new_instance(2, comment_argv, rb_cYARPComment)); } @@ -205,19 +272,20 @@ parser_comments(yp_parser_t *parser) { // Extract the errors out of the parser into an array. static VALUE -parser_errors(yp_parser_t *parser, rb_encoding *encoding) { +parser_errors(yp_parser_t *parser, rb_encoding *encoding, VALUE source) { VALUE errors = rb_ary_new(); yp_diagnostic_t *error; for (error = (yp_diagnostic_t *) parser->error_list.head; error != NULL; error = (yp_diagnostic_t *) error->node.next) { VALUE location_argv[] = { + source, LONG2FIX(error->start - parser->start), LONG2FIX(error->end - parser->start) }; VALUE error_argv[] = { rb_enc_str_new_cstr(error->message, encoding), - rb_class_new_instance(2, location_argv, rb_cYARPLocation) + rb_class_new_instance(3, location_argv, rb_cYARPLocation) }; rb_ary_push(errors, rb_class_new_instance(2, error_argv, rb_cYARPParseError)); @@ -228,19 +296,20 @@ parser_errors(yp_parser_t *parser, rb_encoding *encoding) { // Extract the warnings out of the parser into an array. static VALUE -parser_warnings(yp_parser_t *parser, rb_encoding *encoding) { +parser_warnings(yp_parser_t *parser, rb_encoding *encoding, VALUE source) { VALUE warnings = rb_ary_new(); yp_diagnostic_t *warning; for (warning = (yp_diagnostic_t *) parser->warning_list.head; warning != NULL; warning = (yp_diagnostic_t *) warning->node.next) { VALUE location_argv[] = { + source, LONG2FIX(warning->start - parser->start), LONG2FIX(warning->end - parser->start) }; VALUE warning_argv[] = { rb_enc_str_new_cstr(warning->message, encoding), - rb_class_new_instance(2, location_argv, rb_cYARPLocation) + rb_class_new_instance(3, location_argv, rb_cYARPLocation) }; rb_ary_push(warnings, rb_class_new_instance(2, warning_argv, rb_cYARPParseWarning)); @@ -249,22 +318,36 @@ parser_warnings(yp_parser_t *parser, rb_encoding *encoding) { return warnings; } +/******************************************************************************/ +/* Lexing Ruby code */ +/******************************************************************************/ + +// This struct gets stored in the parser and passed in to the lex callback any +// time a new token is found. We use it to store the necessary information to +// initialize a Token instance. typedef struct { + VALUE source; VALUE tokens; rb_encoding *encoding; } lex_data_t; +// This is passed as a callback to the parser. It gets called every time a new +// token is found. Once found, we initialize a new instance of Token and push it +// onto the tokens array. static void lex_token(void *data, yp_parser_t *parser, yp_token_t *token) { lex_data_t *lex_data = (lex_data_t *) parser->lex_callback->data; VALUE yields = rb_ary_new_capa(2); - rb_ary_push(yields, yp_token_new(parser, token, lex_data->encoding)); + rb_ary_push(yields, yp_token_new(parser, token, lex_data->encoding, lex_data->source)); rb_ary_push(yields, INT2FIX(parser->lex_state)); rb_ary_push(lex_data->tokens, yields); } +// This is called whenever the encoding changes based on the magic comment at +// the top of the file. We use it to update the encoding that we are using to +// create tokens. static void lex_encoding_changed_callback(yp_parser_t *parser) { lex_data_t *lex_data = (lex_data_t *) parser->lex_callback->data; @@ -273,30 +356,42 @@ lex_encoding_changed_callback(yp_parser_t *parser) { // Return an array of tokens corresponding to the given source. static VALUE -lex_source(source_t *source, char *filepath) { +lex_input(input_t *input, const char *filepath) { yp_parser_t parser; - yp_parser_init(&parser, source->source, source->size, filepath); + yp_parser_init(&parser, input->source, input->size, filepath); yp_parser_register_encoding_changed_callback(&parser, lex_encoding_changed_callback); + VALUE offsets = rb_ary_new(); + VALUE source_argv[] = { rb_str_new(input->source, input->size), offsets }; + VALUE source = rb_class_new_instance(2, source_argv, rb_cYARPSource); + lex_data_t lex_data = { + .source = source, .tokens = rb_ary_new(), .encoding = rb_utf8_encoding() }; - void *data = (void *) &lex_data; + lex_data_t *data = &lex_data; yp_lex_callback_t lex_callback = (yp_lex_callback_t) { - .data = data, + .data = (void *) data, .callback = lex_token, }; parser.lex_callback = &lex_callback; yp_node_t *node = yp_parse(&parser); + // Here we need to update the source range to have the correct newline + // offsets. We do it here because we've already created the object and given + // it over to all of the tokens. + for (size_t index = 0; index < parser.newline_list.size; index++) { + rb_ary_push(offsets, INT2FIX(parser.newline_list.offsets[index])); + } + VALUE result_argv[] = { lex_data.tokens, - parser_comments(&parser), - parser_errors(&parser, lex_data.encoding), - parser_warnings(&parser, lex_data.encoding) + parser_comments(&parser, source), + parser_errors(&parser, lex_data.encoding, source), + parser_warnings(&parser, lex_data.encoding, source) }; VALUE result = rb_class_new_instance(4, result_argv, rb_cYARPParseResult); @@ -309,40 +404,49 @@ lex_source(source_t *source, char *filepath) { // Return an array of tokens corresponding to the given string. static VALUE -lex(VALUE self, VALUE string, VALUE filepath) { - source_t source; - source_string_load(&source, string); - char *filepath_char = NULL; - if (filepath) { - filepath_char = StringValueCStr(filepath); - } - return lex_source(&source, filepath_char); +lex(int argc, VALUE *argv, VALUE self) { + VALUE string; + VALUE filepath; + rb_scan_args(argc, argv, "11", &string, &filepath); + + input_t input; + input_load_string(&input, string); + return lex_input(&input, check_filepath(filepath)); } // Return an array of tokens corresponding to the given file. static VALUE lex_file(VALUE self, VALUE filepath) { - source_t source; - if (source_file_load(&source, filepath) != 0) return Qnil; + input_t input; + + const char *checked = check_filepath(filepath); + if (input_load_filepath(&input, checked) != 0) return Qnil; + + VALUE value = lex_input(&input, checked); + input_unload_filepath(&input); - VALUE value = lex_source(&source, StringValueCStr(filepath)); - source_file_unload(&source); return value; } +/******************************************************************************/ +/* Parsing Ruby code */ +/******************************************************************************/ + +// Parse the given input and return a ParseResult instance. static VALUE -parse_source(source_t *source, char *filepath) { +parse_input(input_t *input, const char *filepath) { yp_parser_t parser; - yp_parser_init(&parser, source->source, source->size, filepath); + yp_parser_init(&parser, input->source, input->size, filepath); yp_node_t *node = yp_parse(&parser); rb_encoding *encoding = rb_enc_find(parser.encoding.name); + VALUE source = yp_source_new(&parser); VALUE result_argv[] = { yp_ast_new(&parser, node, encoding), - parser_comments(&parser), - parser_errors(&parser, encoding), - parser_warnings(&parser, encoding) + parser_comments(&parser, source), + parser_errors(&parser, encoding, source), + parser_warnings(&parser, encoding, source) }; VALUE result = rb_class_new_instance(4, result_argv, rb_cYARPParseResult); @@ -353,40 +457,58 @@ parse_source(source_t *source, char *filepath) { return result; } +// Parse the given string and return a ParseResult instance. static VALUE -parse(VALUE self, VALUE string, VALUE filepath) { - source_t source; - source_string_load(&source, string); +parse(int argc, VALUE *argv, VALUE self) { + VALUE string; + VALUE filepath; + rb_scan_args(argc, argv, "11", &string, &filepath); + + input_t input; + input_load_string(&input, string); + #ifdef YARP_DEBUG_MODE_BUILD - char* dup = malloc(source.size); - memcpy(dup, source.source, source.size); - source.source = dup; + char* dup = malloc(input.size); + memcpy(dup, input.source, input.size); + input.source = dup; #endif - VALUE value = parse_source(&source, NIL_P(filepath) ? NULL : StringValueCStr(filepath)); + + VALUE value = parse_input(&input, check_filepath(filepath)); + #ifdef YARP_DEBUG_MODE_BUILD free(dup); #endif + return value; } +// Parse the given file and return a ParseResult instance. static VALUE -parse_file(VALUE self, VALUE rb_filepath) { - source_t source; - if (source_file_load(&source, rb_filepath) != 0) { - return Qnil; - } +parse_file(VALUE self, VALUE filepath) { + input_t input; + + const char *checked = check_filepath(filepath); + if (input_load_filepath(&input, checked) != 0) return Qnil; + + VALUE value = parse_input(&input, checked); + input_unload_filepath(&input); - VALUE value = parse_source(&source, StringValueCStr(rb_filepath)); - source_file_unload(&source); return value; } +/******************************************************************************/ +/* Utility functions exposed to make testing easier */ +/******************************************************************************/ + +// Returns an array of strings corresponding to the named capture groups in the +// given source string. If YARP was unable to parse the regular expression, this +// function returns nil. static VALUE -named_captures(VALUE self, VALUE rb_source) { +named_captures(VALUE self, VALUE source) { yp_string_list_t string_list; yp_string_list_init(&string_list); - if (!yp_regexp_named_capture_group_names(RSTRING_PTR(rb_source), RSTRING_LEN(rb_source), &string_list)) { + if (!yp_regexp_named_capture_group_names(RSTRING_PTR(source), RSTRING_LEN(source), &string_list)) { yp_string_list_free(&string_list); return Qnil; } @@ -401,6 +523,8 @@ named_captures(VALUE self, VALUE rb_source) { return names; } +// Accepts a source string and a type of unescaping and returns the unescaped +// version. static VALUE unescape(VALUE source, yp_unescape_type_t unescape_type) { yp_string_t string; @@ -409,7 +533,13 @@ unescape(VALUE source, yp_unescape_type_t unescape_type) { yp_list_t error_list; yp_list_init(&error_list); - yp_unescape_manipulate_string(RSTRING_PTR(source), RSTRING_LEN(source), &string, unescape_type, &error_list); + const char *start = RSTRING_PTR(source); + size_t length = RSTRING_LEN(source); + + yp_parser_t parser; + yp_parser_init(&parser, start, length, ""); + + yp_unescape_manipulate_string(&parser, start, length, &string, unescape_type, &error_list); if (yp_list_empty_p(&error_list)) { result = rb_str_new(yp_string_source(&string), yp_string_length(&string)); } else { @@ -418,27 +548,32 @@ unescape(VALUE source, yp_unescape_type_t unescape_type) { yp_string_free(&string); yp_list_free(&error_list); + yp_parser_free(&parser); return result; } +// Do not unescape anything in the given string. This is here to provide a +// consistent API. static VALUE unescape_none(VALUE self, VALUE source) { return unescape(source, YP_UNESCAPE_NONE); } +// Minimally unescape the given string. This means effectively unescaping just +// the quotes of a string. Returns the unescaped string. static VALUE unescape_minimal(VALUE self, VALUE source) { return unescape(source, YP_UNESCAPE_MINIMAL); } +// Unescape everything in the given string. Return the unescaped string. static VALUE unescape_all(VALUE self, VALUE source) { return unescape(source, YP_UNESCAPE_ALL); } -// This function returns a hash of information about the given source string's -// memory usage. +// Return a hash of information about the given source string's memory usage. static VALUE memsize(VALUE self, VALUE string) { yp_parser_t parser; @@ -459,28 +594,17 @@ memsize(VALUE self, VALUE string) { return result; } -static VALUE -compile(VALUE self, VALUE string) { - yp_parser_t parser; - size_t length = RSTRING_LEN(string); - yp_parser_init(&parser, RSTRING_PTR(string), length, NULL); - - yp_node_t *node = yp_parse(&parser); - VALUE result = yp_compile(node); - - yp_node_destroy(&parser, node); - yp_parser_free(&parser); - - return result; -} - +// Parse the file, but do nothing with the result. This is used to profile the +// parser for memory and speed. static VALUE profile_file(VALUE self, VALUE filepath) { - source_t source; - if (source_file_load(&source, filepath) != 0) return Qnil; + input_t input; + + const char *checked = check_filepath(filepath); + if (input_load_filepath(&input, checked) != 0) return Qnil; yp_parser_t parser; - yp_parser_init(&parser, source.source, source.size, StringValueCStr(filepath)); + yp_parser_init(&parser, input.source, input.size, checked); yp_node_t *node = yp_parse(&parser); yp_node_destroy(&parser, node); @@ -491,9 +615,8 @@ profile_file(VALUE self, VALUE filepath) { // The function takes a source string and returns a Ruby array containing the // offsets of every newline in the string. (It also includes a 0 at the -// beginning to indicate the position of the first line.) -// -// It accepts a string as its only argument and returns an array of integers. +// beginning to indicate the position of the first line.) It accepts a string as +// its only argument and returns an array of integers. static VALUE newlines(VALUE self, VALUE string) { yp_parser_t parser; @@ -512,46 +635,56 @@ newlines(VALUE self, VALUE string) { return result; } +/******************************************************************************/ +/* Initialization of the extension */ +/******************************************************************************/ + RUBY_FUNC_EXPORTED void Init_yarp(void) { + // Make sure that the YARP library version matches the expected version. + // Otherwise something was compiled incorrectly. if (strcmp(yp_version(), EXPECTED_YARP_VERSION) != 0) { - rb_raise(rb_eRuntimeError, "The YARP library version (%s) does not match the expected version (%s)", yp_version(), - EXPECTED_YARP_VERSION); + rb_raise( + rb_eRuntimeError, + "The YARP library version (%s) does not match the expected version (%s)", + yp_version(), + EXPECTED_YARP_VERSION + ); } + // Grab up references to all of the constants that we're going to need to + // reference throughout this extension. rb_cYARP = rb_define_module("YARP"); + rb_cYARPSource = rb_define_class_under(rb_cYARP, "Source", rb_cObject); rb_cYARPToken = rb_define_class_under(rb_cYARP, "Token", rb_cObject); rb_cYARPLocation = rb_define_class_under(rb_cYARP, "Location", rb_cObject); - rb_cYARPComment = rb_define_class_under(rb_cYARP, "Comment", rb_cObject); rb_cYARPParseError = rb_define_class_under(rb_cYARP, "ParseError", rb_cObject); rb_cYARPParseWarning = rb_define_class_under(rb_cYARP, "ParseWarning", rb_cObject); rb_cYARPParseResult = rb_define_class_under(rb_cYARP, "ParseResult", rb_cObject); - rb_define_const(rb_cYARP, "VERSION", rb_sprintf("%d.%d.%d", YP_VERSION_MAJOR, YP_VERSION_MINOR, YP_VERSION_PATCH)); + // Define the version string here so that we can use the constants defined + // in yarp.h. + rb_define_const(rb_cYARP, "VERSION", rb_str_new2(EXPECTED_YARP_VERSION)); - rb_define_singleton_method(rb_cYARP, "dump", dump, 2); + // First, the functions that have to do with lexing and parsing. + rb_define_singleton_method(rb_cYARP, "dump", dump, -1); rb_define_singleton_method(rb_cYARP, "dump_file", dump_file, 1); - - rb_define_singleton_method(rb_cYARP, "lex", lex, 2); + rb_define_singleton_method(rb_cYARP, "lex", lex, -1); rb_define_singleton_method(rb_cYARP, "lex_file", lex_file, 1); - - rb_define_singleton_method(rb_cYARP, "_parse", parse, 2); + rb_define_singleton_method(rb_cYARP, "parse", parse, -1); rb_define_singleton_method(rb_cYARP, "parse_file", parse_file, 1); + // Next, the functions that will be called by the parser to perform various + // internal tasks. We expose these to make them easier to test. rb_define_singleton_method(rb_cYARP, "named_captures", named_captures, 1); - rb_define_singleton_method(rb_cYARP, "unescape_none", unescape_none, 1); rb_define_singleton_method(rb_cYARP, "unescape_minimal", unescape_minimal, 1); rb_define_singleton_method(rb_cYARP, "unescape_all", unescape_all, 1); - rb_define_singleton_method(rb_cYARP, "memsize", memsize, 1); - - rb_define_singleton_method(rb_cYARP, "compile", compile, 1); - rb_define_singleton_method(rb_cYARP, "profile_file", profile_file, 1); - rb_define_singleton_method(rb_cYARP, "newlines", newlines, 1); + // Next, initialize the pack API. Init_yarp_pack(); } diff --git a/yarp/extension.h b/yarp/extension.h index e573be6171..d19c390f2b 100644 --- a/yarp/extension.h +++ b/yarp/extension.h @@ -5,11 +5,11 @@ #include <ruby/encoding.h> #include "yarp.h" -#include <fcntl.h> - +// The following headers are necessary to read files using demand paging. #ifdef _WIN32 #include <windows.h> #else +#include <fcntl.h> #include <sys/mman.h> #include <sys/stat.h> #include <unistd.h> @@ -17,16 +17,11 @@ #define EXPECTED_YARP_VERSION "0.4.0" -VALUE yp_token_new(yp_parser_t *parser, yp_token_t *token, rb_encoding *encoding); - +VALUE yp_source_new(yp_parser_t *parser); +VALUE yp_token_new(yp_parser_t *parser, yp_token_t *token, rb_encoding *encoding, VALUE source); VALUE yp_ast_new(yp_parser_t *parser, yp_node_t *node, rb_encoding *encoding); -VALUE yp_compile(yp_node_t *node); - void Init_yarp_pack(void); - YP_EXPORTED_FUNCTION void Init_yarp(void); -#define DISCARD_CONST_QUAL(t, v) ((t)(uintptr_t)(v)) - -#endif // YARP_EXT_NODE_H +#endif diff --git a/yarp/missing.h b/yarp/missing.h deleted file mode 100644 index 9f0ef33938..0000000000 --- a/yarp/missing.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef YARP_MISSING_H -#define YARP_MISSING_H - -#include "yarp/defines.h" - -#include <ctype.h> -#include <stddef.h> -#include <string.h> - -const char * yp_strnstr(const char *haystack, const char *needle, size_t length); - -int yp_strncasecmp(const char *string1, const char *string2, size_t length); - -#ifndef HAVE_STRNCASECMP -#ifndef strncasecmp -#define strncasecmp yp_strncasecmp -#endif -#endif - -#endif diff --git a/yarp/node.h b/yarp/node.h index 3da45fe427..f75e03ba10 100644 --- a/yarp/node.h +++ b/yarp/node.h @@ -2,8 +2,6 @@ #define YARP_NODE_H #include "yarp/defines.h" - -#include "yarp.h" #include "yarp/parser.h" // Append a token to the given list. @@ -15,6 +13,20 @@ void yp_node_list_append(yp_node_list_t *list, yp_node_t *node); // Clear the node but preserves the location. void yp_node_clear(yp_node_t *node); +// Deallocate a node and all of its children. +YP_EXPORTED_FUNCTION void yp_node_destroy(yp_parser_t *parser, struct yp_node *node); + +// This struct stores the information gathered by the yp_node_memsize function. +// It contains both the memory footprint and additionally metadata about the +// shape of the tree. +typedef struct { + size_t memsize; + size_t node_count; +} yp_memsize_t; + +// Calculates the memory footprint of a given node. +YP_EXPORTED_FUNCTION void yp_node_memsize(yp_node_t *node, yp_memsize_t *memsize); + #define YP_EMPTY_NODE_LIST ((yp_node_list_t) { .nodes = NULL, .size = 0, .capacity = 0 }) #define YP_EMPTY_LOCATION_LIST ((yp_location_list_t) { .locations = NULL, .size = 0, .capacity = 0 }) diff --git a/yarp/pack.h b/yarp/pack.h index 4a4446bb0e..9d6204bf7b 100644 --- a/yarp/pack.h +++ b/yarp/pack.h @@ -3,8 +3,8 @@ #include "yarp/defines.h" -#include <stdlib.h> #include <stdint.h> +#include <stdlib.h> typedef enum yp_pack_version { YP_PACK_VERSION_3_2_0 diff --git a/yarp/parser.h b/yarp/parser.h index 2c6d08a3c9..a23f886084 100644 --- a/yarp/parser.h +++ b/yarp/parser.h @@ -1,17 +1,16 @@ #ifndef YARP_PARSER_H #define YARP_PARSER_H -#include "yarp/defines.h" - -#include <stdbool.h> - #include "yarp/ast.h" +#include "yarp/defines.h" #include "yarp/enc/yp_encoding.h" #include "yarp/util/yp_constant_pool.h" #include "yarp/util/yp_list.h" #include "yarp/util/yp_newline_list.h" #include "yarp/util/yp_state_stack.h" +#include <stdbool.h> + // This enum provides various bits that represent different kinds of states that // the lexer can track. This is used to determine which kind of token to return // based on the context of the parser. diff --git a/yarp/prettyprint.c b/yarp/prettyprint.c index cb5d746165..727ac6c430 100644 --- a/yarp/prettyprint.c +++ b/yarp/prettyprint.c @@ -5,6 +5,8 @@ /* if you are looking to modify the */ /* template */ /******************************************************************************/ +#include "yarp/defines.h" + #include <stdio.h> #include "yarp/ast.h" @@ -14,7 +16,7 @@ static void prettyprint_location(yp_buffer_t *buffer, yp_parser_t *parser, yp_location_t *location) { char printed[] = "[0000-0000]"; - sprintf(printed, "[%04ld-%04ld]", (long int)(location->start - parser->start), (long int)(location->end - parser->start)); + yp_snprintf(printed, sizeof(printed), "[%04ld-%04ld]", (long int)(location->start - parser->start), (long int)(location->end - parser->start)); yp_buffer_append_str(buffer, printed, strlen(printed)); } @@ -189,7 +191,7 @@ prettyprint_node(yp_buffer_t *buffer, yp_parser_t *parser, yp_node_t *node) { for (uint32_t index = 0; index < ((yp_block_node_t *)node)->locals.size; index++) { if (index != 0) yp_buffer_append_str(buffer, ", ", 2); char locals_buffer[12]; - sprintf(locals_buffer, "%u", ((yp_block_node_t *)node)->locals.ids[index]); + yp_snprintf(locals_buffer, sizeof(locals_buffer), "%u", ((yp_block_node_t *)node)->locals.ids[index]); yp_buffer_append_str(buffer, locals_buffer, strlen(locals_buffer)); } yp_buffer_append_str(buffer, ", ", 2); if (((yp_block_node_t *)node)->parameters == NULL) { @@ -291,7 +293,7 @@ prettyprint_node(yp_buffer_t *buffer, yp_parser_t *parser, yp_node_t *node) { prettyprint_node(buffer, parser, (yp_node_t *)((yp_call_node_t *)node)->block); } yp_buffer_append_str(buffer, ", ", 2); char flags_buffer[12]; - sprintf(flags_buffer, "+%d", ((yp_call_node_t *)node)->flags); + yp_snprintf(flags_buffer, sizeof(flags_buffer), "+%d", ((yp_call_node_t *)node)->flags); yp_buffer_append_str(buffer, flags_buffer, strlen(flags_buffer)); yp_buffer_append_str(buffer, ", ", 2); yp_buffer_append_str(buffer, "\"", 1); yp_buffer_append_str(buffer, yp_string_source(&((yp_call_node_t *)node)->name), yp_string_length(&((yp_call_node_t *)node)->name)); @@ -321,7 +323,7 @@ prettyprint_node(yp_buffer_t *buffer, yp_parser_t *parser, yp_node_t *node) { yp_buffer_append_str(buffer, ", ", 2); prettyprint_location(buffer, parser, &((yp_call_operator_write_node_t *)node)->operator_loc); yp_buffer_append_str(buffer, ", ", 2); prettyprint_node(buffer, parser, (yp_node_t *)((yp_call_operator_write_node_t *)node)->value); yp_buffer_append_str(buffer, ", ", 2); char operator_id_buffer[12]; - sprintf(operator_id_buffer, "%u", ((yp_call_operator_write_node_t *)node)->operator_id); + yp_snprintf(operator_id_buffer, sizeof(operator_id_buffer), "%u", ((yp_call_operator_write_node_t *)node)->operator_id); yp_buffer_append_str(buffer, operator_id_buffer, strlen(operator_id_buffer)); yp_buffer_append_str(buffer, ")", 1); break; @@ -360,7 +362,7 @@ prettyprint_node(yp_buffer_t *buffer, yp_parser_t *parser, yp_node_t *node) { for (uint32_t index = 0; index < ((yp_class_node_t *)node)->locals.size; index++) { if (index != 0) yp_buffer_append_str(buffer, ", ", 2); char locals_buffer[12]; - sprintf(locals_buffer, "%u", ((yp_class_node_t *)node)->locals.ids[index]); + yp_snprintf(locals_buffer, sizeof(locals_buffer), "%u", ((yp_class_node_t *)node)->locals.ids[index]); yp_buffer_append_str(buffer, locals_buffer, strlen(locals_buffer)); } yp_buffer_append_str(buffer, ", ", 2); prettyprint_location(buffer, parser, &((yp_class_node_t *)node)->class_keyword_loc); @@ -406,7 +408,7 @@ prettyprint_node(yp_buffer_t *buffer, yp_parser_t *parser, yp_node_t *node) { yp_buffer_append_str(buffer, ", ", 2); prettyprint_location(buffer, parser, &((yp_class_variable_operator_write_node_t *)node)->operator_loc); yp_buffer_append_str(buffer, ", ", 2); prettyprint_node(buffer, parser, (yp_node_t *)((yp_class_variable_operator_write_node_t *)node)->value); yp_buffer_append_str(buffer, ", ", 2); char operator_buffer[12]; - sprintf(operator_buffer, "%u", ((yp_class_variable_operator_write_node_t *)node)->operator); + yp_snprintf(operator_buffer, sizeof(operator_buffer), "%u", ((yp_class_variable_operator_write_node_t *)node)->operator); yp_buffer_append_str(buffer, operator_buffer, strlen(operator_buffer)); yp_buffer_append_str(buffer, ")", 1); break; @@ -454,7 +456,7 @@ prettyprint_node(yp_buffer_t *buffer, yp_parser_t *parser, yp_node_t *node) { yp_buffer_append_str(buffer, ", ", 2); prettyprint_location(buffer, parser, &((yp_constant_operator_write_node_t *)node)->operator_loc); yp_buffer_append_str(buffer, ", ", 2); prettyprint_node(buffer, parser, (yp_node_t *)((yp_constant_operator_write_node_t *)node)->value); yp_buffer_append_str(buffer, ", ", 2); char operator_buffer[12]; - sprintf(operator_buffer, "%u", ((yp_constant_operator_write_node_t *)node)->operator); + yp_snprintf(operator_buffer, sizeof(operator_buffer), "%u", ((yp_constant_operator_write_node_t *)node)->operator); yp_buffer_append_str(buffer, operator_buffer, strlen(operator_buffer)); yp_buffer_append_str(buffer, ")", 1); break; @@ -493,7 +495,7 @@ prettyprint_node(yp_buffer_t *buffer, yp_parser_t *parser, yp_node_t *node) { yp_buffer_append_str(buffer, ", ", 2); prettyprint_location(buffer, parser, &((yp_constant_path_operator_write_node_t *)node)->operator_loc); yp_buffer_append_str(buffer, ", ", 2); prettyprint_node(buffer, parser, (yp_node_t *)((yp_constant_path_operator_write_node_t *)node)->value); yp_buffer_append_str(buffer, ", ", 2); char operator_buffer[12]; - sprintf(operator_buffer, "%u", ((yp_constant_path_operator_write_node_t *)node)->operator); + yp_snprintf(operator_buffer, sizeof(operator_buffer), "%u", ((yp_constant_path_operator_write_node_t *)node)->operator); yp_buffer_append_str(buffer, operator_buffer, strlen(operator_buffer)); yp_buffer_append_str(buffer, ")", 1); break; @@ -540,7 +542,7 @@ prettyprint_node(yp_buffer_t *buffer, yp_parser_t *parser, yp_node_t *node) { yp_buffer_append_str(buffer, ", ", 2); for (uint32_t index = 0; index < ((yp_def_node_t *)node)->locals.size; index++) { if (index != 0) yp_buffer_append_str(buffer, ", ", 2); char locals_buffer[12]; - sprintf(locals_buffer, "%u", ((yp_def_node_t *)node)->locals.ids[index]); + yp_snprintf(locals_buffer, sizeof(locals_buffer), "%u", ((yp_def_node_t *)node)->locals.ids[index]); yp_buffer_append_str(buffer, locals_buffer, strlen(locals_buffer)); } yp_buffer_append_str(buffer, ", ", 2); prettyprint_location(buffer, parser, &((yp_def_node_t *)node)->def_keyword_loc); @@ -734,7 +736,7 @@ prettyprint_node(yp_buffer_t *buffer, yp_parser_t *parser, yp_node_t *node) { yp_buffer_append_str(buffer, ", ", 2); prettyprint_location(buffer, parser, &((yp_global_variable_operator_write_node_t *)node)->operator_loc); yp_buffer_append_str(buffer, ", ", 2); prettyprint_node(buffer, parser, (yp_node_t *)((yp_global_variable_operator_write_node_t *)node)->value); yp_buffer_append_str(buffer, ", ", 2); char operator_buffer[12]; - sprintf(operator_buffer, "%u", ((yp_global_variable_operator_write_node_t *)node)->operator); + yp_snprintf(operator_buffer, sizeof(operator_buffer), "%u", ((yp_global_variable_operator_write_node_t *)node)->operator); yp_buffer_append_str(buffer, operator_buffer, strlen(operator_buffer)); yp_buffer_append_str(buffer, ")", 1); break; @@ -871,7 +873,7 @@ prettyprint_node(yp_buffer_t *buffer, yp_parser_t *parser, yp_node_t *node) { yp_buffer_append_str(buffer, ", ", 2); prettyprint_location(buffer, parser, &((yp_instance_variable_operator_write_node_t *)node)->operator_loc); yp_buffer_append_str(buffer, ", ", 2); prettyprint_node(buffer, parser, (yp_node_t *)((yp_instance_variable_operator_write_node_t *)node)->value); yp_buffer_append_str(buffer, ", ", 2); char operator_buffer[12]; - sprintf(operator_buffer, "%u", ((yp_instance_variable_operator_write_node_t *)node)->operator); + yp_snprintf(operator_buffer, sizeof(operator_buffer), "%u", ((yp_instance_variable_operator_write_node_t *)node)->operator); yp_buffer_append_str(buffer, operator_buffer, strlen(operator_buffer)); yp_buffer_append_str(buffer, ")", 1); break; @@ -911,7 +913,7 @@ prettyprint_node(yp_buffer_t *buffer, yp_parser_t *parser, yp_node_t *node) { } yp_buffer_append_str(buffer, ", ", 2); prettyprint_location(buffer, parser, &((yp_interpolated_regular_expression_node_t *)node)->closing_loc); yp_buffer_append_str(buffer, ", ", 2); char flags_buffer[12]; - sprintf(flags_buffer, "+%d", ((yp_interpolated_regular_expression_node_t *)node)->flags); + yp_snprintf(flags_buffer, sizeof(flags_buffer), "+%d", ((yp_interpolated_regular_expression_node_t *)node)->flags); yp_buffer_append_str(buffer, flags_buffer, strlen(flags_buffer)); yp_buffer_append_str(buffer, ")", 1); break; @@ -1001,7 +1003,7 @@ prettyprint_node(yp_buffer_t *buffer, yp_parser_t *parser, yp_node_t *node) { for (uint32_t index = 0; index < ((yp_lambda_node_t *)node)->locals.size; index++) { if (index != 0) yp_buffer_append_str(buffer, ", ", 2); char locals_buffer[12]; - sprintf(locals_buffer, "%u", ((yp_lambda_node_t *)node)->locals.ids[index]); + yp_snprintf(locals_buffer, sizeof(locals_buffer), "%u", ((yp_lambda_node_t *)node)->locals.ids[index]); yp_buffer_append_str(buffer, locals_buffer, strlen(locals_buffer)); } yp_buffer_append_str(buffer, ", ", 2); prettyprint_location(buffer, parser, &((yp_lambda_node_t *)node)->opening_loc); @@ -1024,7 +1026,7 @@ prettyprint_node(yp_buffer_t *buffer, yp_parser_t *parser, yp_node_t *node) { yp_buffer_append_str(buffer, ", ", 2); prettyprint_location(buffer, parser, &((yp_local_variable_operator_and_write_node_t *)node)->operator_loc); yp_buffer_append_str(buffer, ", ", 2); prettyprint_node(buffer, parser, (yp_node_t *)((yp_local_variable_operator_and_write_node_t *)node)->value); yp_buffer_append_str(buffer, ", ", 2); char constant_id_buffer[12]; - sprintf(constant_id_buffer, "%u", ((yp_local_variable_operator_and_write_node_t *)node)->constant_id); + yp_snprintf(constant_id_buffer, sizeof(constant_id_buffer), "%u", ((yp_local_variable_operator_and_write_node_t *)node)->constant_id); yp_buffer_append_str(buffer, constant_id_buffer, strlen(constant_id_buffer)); yp_buffer_append_str(buffer, ")", 1); break; @@ -1035,7 +1037,7 @@ prettyprint_node(yp_buffer_t *buffer, yp_parser_t *parser, yp_node_t *node) { yp_buffer_append_str(buffer, ", ", 2); prettyprint_location(buffer, parser, &((yp_local_variable_operator_or_write_node_t *)node)->operator_loc); yp_buffer_append_str(buffer, ", ", 2); prettyprint_node(buffer, parser, (yp_node_t *)((yp_local_variable_operator_or_write_node_t *)node)->value); yp_buffer_append_str(buffer, ", ", 2); char constant_id_buffer[12]; - sprintf(constant_id_buffer, "%u", ((yp_local_variable_operator_or_write_node_t *)node)->constant_id); + yp_snprintf(constant_id_buffer, sizeof(constant_id_buffer), "%u", ((yp_local_variable_operator_or_write_node_t *)node)->constant_id); yp_buffer_append_str(buffer, constant_id_buffer, strlen(constant_id_buffer)); yp_buffer_append_str(buffer, ")", 1); break; @@ -1046,10 +1048,10 @@ prettyprint_node(yp_buffer_t *buffer, yp_parser_t *parser, yp_node_t *node) { yp_buffer_append_str(buffer, ", ", 2); prettyprint_location(buffer, parser, &((yp_local_variable_operator_write_node_t *)node)->operator_loc); yp_buffer_append_str(buffer, ", ", 2); prettyprint_node(buffer, parser, (yp_node_t *)((yp_local_variable_operator_write_node_t *)node)->value); yp_buffer_append_str(buffer, ", ", 2); char constant_id_buffer[12]; - sprintf(constant_id_buffer, "%u", ((yp_local_variable_operator_write_node_t *)node)->constant_id); + yp_snprintf(constant_id_buffer, sizeof(constant_id_buffer), "%u", ((yp_local_variable_operator_write_node_t *)node)->constant_id); yp_buffer_append_str(buffer, constant_id_buffer, strlen(constant_id_buffer)); yp_buffer_append_str(buffer, ", ", 2); char operator_id_buffer[12]; - sprintf(operator_id_buffer, "%u", ((yp_local_variable_operator_write_node_t *)node)->operator_id); + yp_snprintf(operator_id_buffer, sizeof(operator_id_buffer), "%u", ((yp_local_variable_operator_write_node_t *)node)->operator_id); yp_buffer_append_str(buffer, operator_id_buffer, strlen(operator_id_buffer)); yp_buffer_append_str(buffer, ")", 1); break; @@ -1057,10 +1059,10 @@ prettyprint_node(yp_buffer_t *buffer, yp_parser_t *parser, yp_node_t *node) { case YP_NODE_LOCAL_VARIABLE_READ_NODE: { yp_buffer_append_str(buffer, "LocalVariableReadNode(", 22); char constant_id_buffer[12]; - sprintf(constant_id_buffer, "%u", ((yp_local_variable_read_node_t *)node)->constant_id); + yp_snprintf(constant_id_buffer, sizeof(constant_id_buffer), "%u", ((yp_local_variable_read_node_t *)node)->constant_id); yp_buffer_append_str(buffer, constant_id_buffer, strlen(constant_id_buffer)); yp_buffer_append_str(buffer, ", ", 2); char depth_buffer[12]; - sprintf(depth_buffer, "+%d", ((yp_local_variable_read_node_t *)node)->depth); + yp_snprintf(depth_buffer, sizeof(depth_buffer), "+%d", ((yp_local_variable_read_node_t *)node)->depth); yp_buffer_append_str(buffer, depth_buffer, strlen(depth_buffer)); yp_buffer_append_str(buffer, ")", 1); break; @@ -1068,10 +1070,10 @@ prettyprint_node(yp_buffer_t *buffer, yp_parser_t *parser, yp_node_t *node) { case YP_NODE_LOCAL_VARIABLE_WRITE_NODE: { yp_buffer_append_str(buffer, "LocalVariableWriteNode(", 23); char constant_id_buffer[12]; - sprintf(constant_id_buffer, "%u", ((yp_local_variable_write_node_t *)node)->constant_id); + yp_snprintf(constant_id_buffer, sizeof(constant_id_buffer), "%u", ((yp_local_variable_write_node_t *)node)->constant_id); yp_buffer_append_str(buffer, constant_id_buffer, strlen(constant_id_buffer)); yp_buffer_append_str(buffer, ", ", 2); char depth_buffer[12]; - sprintf(depth_buffer, "+%d", ((yp_local_variable_write_node_t *)node)->depth); + yp_snprintf(depth_buffer, sizeof(depth_buffer), "+%d", ((yp_local_variable_write_node_t *)node)->depth); yp_buffer_append_str(buffer, depth_buffer, strlen(depth_buffer)); yp_buffer_append_str(buffer, ", ", 2); if (((yp_local_variable_write_node_t *)node)->value == NULL) { yp_buffer_append_str(buffer, "nil", 3); @@ -1113,7 +1115,7 @@ prettyprint_node(yp_buffer_t *buffer, yp_parser_t *parser, yp_node_t *node) { for (uint32_t index = 0; index < ((yp_module_node_t *)node)->locals.size; index++) { if (index != 0) yp_buffer_append_str(buffer, ", ", 2); char locals_buffer[12]; - sprintf(locals_buffer, "%u", ((yp_module_node_t *)node)->locals.ids[index]); + yp_snprintf(locals_buffer, sizeof(locals_buffer), "%u", ((yp_module_node_t *)node)->locals.ids[index]); yp_buffer_append_str(buffer, locals_buffer, strlen(locals_buffer)); } yp_buffer_append_str(buffer, ", ", 2); prettyprint_location(buffer, parser, &((yp_module_node_t *)node)->module_keyword_loc); @@ -1187,7 +1189,7 @@ prettyprint_node(yp_buffer_t *buffer, yp_parser_t *parser, yp_node_t *node) { case YP_NODE_OPTIONAL_PARAMETER_NODE: { yp_buffer_append_str(buffer, "OptionalParameterNode(", 22); char constant_id_buffer[12]; - sprintf(constant_id_buffer, "%u", ((yp_optional_parameter_node_t *)node)->constant_id); + yp_snprintf(constant_id_buffer, sizeof(constant_id_buffer), "%u", ((yp_optional_parameter_node_t *)node)->constant_id); yp_buffer_append_str(buffer, constant_id_buffer, strlen(constant_id_buffer)); yp_buffer_append_str(buffer, ", ", 2); prettyprint_location(buffer, parser, &((yp_optional_parameter_node_t *)node)->name_loc); yp_buffer_append_str(buffer, ", ", 2); prettyprint_location(buffer, parser, &((yp_optional_parameter_node_t *)node)->operator_loc); @@ -1298,7 +1300,7 @@ prettyprint_node(yp_buffer_t *buffer, yp_parser_t *parser, yp_node_t *node) { for (uint32_t index = 0; index < ((yp_program_node_t *)node)->locals.size; index++) { if (index != 0) yp_buffer_append_str(buffer, ", ", 2); char locals_buffer[12]; - sprintf(locals_buffer, "%u", ((yp_program_node_t *)node)->locals.ids[index]); + yp_snprintf(locals_buffer, sizeof(locals_buffer), "%u", ((yp_program_node_t *)node)->locals.ids[index]); yp_buffer_append_str(buffer, locals_buffer, strlen(locals_buffer)); } yp_buffer_append_str(buffer, ", ", 2); prettyprint_node(buffer, parser, (yp_node_t *)((yp_program_node_t *)node)->statements); @@ -1319,7 +1321,7 @@ prettyprint_node(yp_buffer_t *buffer, yp_parser_t *parser, yp_node_t *node) { } yp_buffer_append_str(buffer, ", ", 2); prettyprint_location(buffer, parser, &((yp_range_node_t *)node)->operator_loc); yp_buffer_append_str(buffer, ", ", 2); char flags_buffer[12]; - sprintf(flags_buffer, "+%d", ((yp_range_node_t *)node)->flags); + yp_snprintf(flags_buffer, sizeof(flags_buffer), "+%d", ((yp_range_node_t *)node)->flags); yp_buffer_append_str(buffer, flags_buffer, strlen(flags_buffer)); yp_buffer_append_str(buffer, ")", 1); break; @@ -1344,7 +1346,7 @@ prettyprint_node(yp_buffer_t *buffer, yp_parser_t *parser, yp_node_t *node) { yp_buffer_append_str(buffer, yp_string_source(&((yp_regular_expression_node_t *)node)->unescaped), yp_string_length(&((yp_regular_expression_node_t *)node)->unescaped)); yp_buffer_append_str(buffer, "\"", 1); yp_buffer_append_str(buffer, ", ", 2); char flags_buffer[12]; - sprintf(flags_buffer, "+%d", ((yp_regular_expression_node_t *)node)->flags); + yp_snprintf(flags_buffer, sizeof(flags_buffer), "+%d", ((yp_regular_expression_node_t *)node)->flags); yp_buffer_append_str(buffer, flags_buffer, strlen(flags_buffer)); yp_buffer_append_str(buffer, ")", 1); break; @@ -1363,7 +1365,7 @@ prettyprint_node(yp_buffer_t *buffer, yp_parser_t *parser, yp_node_t *node) { case YP_NODE_REQUIRED_PARAMETER_NODE: { yp_buffer_append_str(buffer, "RequiredParameterNode(", 22); char constant_id_buffer[12]; - sprintf(constant_id_buffer, "%u", ((yp_required_parameter_node_t *)node)->constant_id); + yp_snprintf(constant_id_buffer, sizeof(constant_id_buffer), "%u", ((yp_required_parameter_node_t *)node)->constant_id); yp_buffer_append_str(buffer, constant_id_buffer, strlen(constant_id_buffer)); yp_buffer_append_str(buffer, ")", 1); break; @@ -1443,7 +1445,7 @@ prettyprint_node(yp_buffer_t *buffer, yp_parser_t *parser, yp_node_t *node) { for (uint32_t index = 0; index < ((yp_singleton_class_node_t *)node)->locals.size; index++) { if (index != 0) yp_buffer_append_str(buffer, ", ", 2); char locals_buffer[12]; - sprintf(locals_buffer, "%u", ((yp_singleton_class_node_t *)node)->locals.ids[index]); + yp_snprintf(locals_buffer, sizeof(locals_buffer), "%u", ((yp_singleton_class_node_t *)node)->locals.ids[index]); yp_buffer_append_str(buffer, locals_buffer, strlen(locals_buffer)); } yp_buffer_append_str(buffer, ", ", 2); prettyprint_location(buffer, parser, &((yp_singleton_class_node_t *)node)->class_keyword_loc); diff --git a/yarp/regexp.c b/yarp/regexp.c index 1d4d1ac1af..c8aeaa0adb 100644 --- a/yarp/regexp.c +++ b/yarp/regexp.c @@ -374,7 +374,7 @@ yp_regexp_parse_group(yp_regexp_parser_t *parser) { case '#': { // inline comments bool found = yp_regexp_char_find(parser, ')'); // the close paren we found is escaped, we need to find another - while (parser->start <= parser->cursor - 2 && *(parser->cursor - 2) == '\\') { + while (found && (parser->start <= parser->cursor - 2) && (*(parser->cursor - 2) == '\\')) { found = yp_regexp_char_find(parser, ')'); } return found; diff --git a/yarp/regexp.h b/yarp/regexp.h index b66db8cb10..cf624db6b8 100644 --- a/yarp/regexp.h +++ b/yarp/regexp.h @@ -2,15 +2,14 @@ #define YARP_REGEXP_H #include "yarp/defines.h" - #include "yarp/parser.h" +#include "yarp/util/yp_string_list.h" +#include "yarp/util/yp_string.h" + #include <stdbool.h> #include <stddef.h> #include <string.h> -#include "yarp/util/yp_string_list.h" -#include "yarp/util/yp_string.h" - // Parse a regular expression and extract the names of all of the named capture // groups. YP_EXPORTED_FUNCTION bool yp_regexp_named_capture_group_names(const char *source, size_t size, yp_string_list_t *named_captures); diff --git a/yarp/unescape.c b/yarp/unescape.c index a47e49ac10..5370b27355 100644 --- a/yarp/unescape.c +++ b/yarp/unescape.c @@ -438,14 +438,14 @@ unescape(char *dest, size_t *dest_length, const char *backslash, const char *end // \c? or \C-? delete, ASCII 7Fh (DEL) // YP_EXPORTED_FUNCTION void -yp_unescape_manipulate_string(const char *value, size_t length, yp_string_t *string, yp_unescape_type_t unescape_type, yp_list_t *error_list) { +yp_unescape_manipulate_string(yp_parser_t *parser, const char *value, size_t length, yp_string_t *string, yp_unescape_type_t unescape_type, yp_list_t *error_list) { if (unescape_type == YP_UNESCAPE_NONE) { // If we're not unescaping then we can reference the source directly. yp_string_shared_init(string, value, value + length); return; } - const char *backslash = memchr(value, '\\', length); + const char *backslash = yp_memchr(parser, value, '\\', length); if (backslash == NULL) { // Here there are no escapes, so we can reference the source directly. @@ -509,7 +509,7 @@ yp_unescape_manipulate_string(const char *value, size_t length, yp_string_t *str } if (end > cursor) { - backslash = memchr(cursor, '\\', (size_t) (end - cursor)); + backslash = yp_memchr(parser, cursor, '\\', (size_t) (end - cursor)); } else { backslash = NULL; } diff --git a/yarp/unescape.h b/yarp/unescape.h index 8a481a9550..15e7cf2e17 100644 --- a/yarp/unescape.h +++ b/yarp/unescape.h @@ -2,17 +2,18 @@ #define YARP_UNESCAPE_H #include "yarp/defines.h" +#include "yarp/diagnostic.h" +#include "yarp/parser.h" +#include "yarp/util/yp_char.h" +#include "yarp/util/yp_list.h" +#include "yarp/util/yp_memchr.h" +#include "yarp/util/yp_string.h" #include <assert.h> #include <stdbool.h> #include <stdint.h> #include <string.h> -#include "yarp/diagnostic.h" -#include "yarp/util/yp_char.h" -#include "yarp/util/yp_list.h" -#include "yarp/util/yp_string.h" - // The type of unescape we are performing. typedef enum { // When we're creating a string inside of a list literal like %w, we @@ -30,7 +31,7 @@ typedef enum { // Unescape the contents of the given token into the given string using the // given unescape mode. -YP_EXPORTED_FUNCTION void yp_unescape_manipulate_string(const char *value, size_t length, yp_string_t *string, yp_unescape_type_t unescape_type, yp_list_t *error_list); +YP_EXPORTED_FUNCTION void yp_unescape_manipulate_string(yp_parser_t *parser, const char *value, size_t length, yp_string_t *string, yp_unescape_type_t unescape_type, yp_list_t *error_list); YP_EXPORTED_FUNCTION size_t yp_unescape_calculate_difference(const char *value, const char *end, yp_unescape_type_t unescape_type, bool expect_single_codepoint, yp_list_t *error_list); diff --git a/yarp/util/yp_char.h b/yarp/util/yp_char.h index 24a8c7a852..85e5ce4c65 100644 --- a/yarp/util/yp_char.h +++ b/yarp/util/yp_char.h @@ -2,12 +2,11 @@ #define YP_CHAR_H #include "yarp/defines.h" +#include "yarp/util/yp_newline_list.h" #include <stdbool.h> #include <stddef.h> -#include "yarp/util/yp_newline_list.h" - // Returns the number of characters at the start of the string that are // whitespace. Disallows searching past the given maximum number of characters. size_t yp_strspn_whitespace(const char *string, ptrdiff_t length); diff --git a/yarp/util/yp_constant_pool.h b/yarp/util/yp_constant_pool.h index 5bae29f966..992f6a57a5 100644 --- a/yarp/util/yp_constant_pool.h +++ b/yarp/util/yp_constant_pool.h @@ -6,13 +6,13 @@ #ifndef YP_CONSTANT_POOL_H #define YP_CONSTANT_POOL_H +#include "yarp/defines.h" + #include <stdbool.h> #include <stdint.h> #include <stdlib.h> #include <string.h> -#include "yarp/defines.h" - typedef uint32_t yp_constant_id_t; typedef struct { diff --git a/yarp/util/yp_memchr.c b/yarp/util/yp_memchr.c new file mode 100644 index 0000000000..3f63a2cfab --- /dev/null +++ b/yarp/util/yp_memchr.c @@ -0,0 +1,31 @@ +#include "yarp/util/yp_memchr.h" + +#define YP_MEMCHR_TRAILING_BYTE_MINIMUM 0x40 + +// We need to roll our own memchr to handle cases where the encoding changes and +// we need to search for a character in a buffer that could be the trailing byte +// of a multibyte character. +void * +yp_memchr(yp_parser_t *parser, const void *memory, int character, size_t number) { + if (parser->encoding_changed && parser->encoding.multibyte && character >= YP_MEMCHR_TRAILING_BYTE_MINIMUM) { + const char *source = (const char *) memory; + size_t index = 0; + + while (index < number) { + if (source[index] == character) { + return (void *) (source + index); + } + + size_t width = parser->encoding.char_width(source + index); + if (width == 0) { + return NULL; + } + + index += width; + } + + return NULL; + } else { + return memchr(memory, character, number); + } +} diff --git a/yarp/util/yp_memchr.h b/yarp/util/yp_memchr.h new file mode 100644 index 0000000000..3dae01eebd --- /dev/null +++ b/yarp/util/yp_memchr.h @@ -0,0 +1,14 @@ +#ifndef YP_MEMCHR_H +#define YP_MEMCHR_H + +#include "yarp/defines.h" +#include "yarp/parser.h" + +#include <stddef.h> + +// We need to roll our own memchr to handle cases where the encoding changes and +// we need to search for a character in a buffer that could be the trailing byte +// of a multibyte character. +void * yp_memchr(yp_parser_t *parser, const void *source, int character, size_t number); + +#endif diff --git a/yarp/util/yp_newline_list.c b/yarp/util/yp_newline_list.c index 82877f8cb3..c619e83c92 100644 --- a/yarp/util/yp_newline_list.c +++ b/yarp/util/yp_newline_list.c @@ -31,7 +31,7 @@ yp_newline_list_append(yp_newline_list_t *list, const char *cursor) { } assert(cursor >= list->start); - list->offsets[list->size++] = (size_t) (cursor - list->start); + list->offsets[list->size++] = (size_t) (cursor - list->start + 1); return true; } diff --git a/yarp/util/yp_newline_list.h b/yarp/util/yp_newline_list.h index a2c25412d3..91dbd64a82 100644 --- a/yarp/util/yp_newline_list.h +++ b/yarp/util/yp_newline_list.h @@ -9,13 +9,13 @@ #ifndef YP_NEWLINE_LIST_H #define YP_NEWLINE_LIST_H +#include "yarp/defines.h" + #include <assert.h> -#include <stddef.h> #include <stdbool.h> +#include <stddef.h> #include <stdlib.h> -#include "yarp/defines.h" - // A list of offsets of newlines in a string. The offsets are assumed to be // sorted/inserted in ascending order. typedef struct { diff --git a/yarp/util/yp_snprintf.c b/yarp/util/yp_snprintf.c new file mode 100644 index 0000000000..f3b69c2f58 --- /dev/null +++ b/yarp/util/yp_snprintf.c @@ -0,0 +1,14 @@ +#include "yarp/defines.h" + +#ifndef HAVE_SNPRINTF +// In case snprintf isn't present on the system, we provide our own that simply +// forwards to the less-safe sprintf. +int +yp_snprintf(char *dest, YP_ATTRIBUTE_UNUSED size_t size, const char *format, ...) { + va_list args; + va_start(args, format); + int result = vsprintf(dest, format, args); + va_end(args); + return result; +} +#endif diff --git a/yarp/util/yp_string.c b/yarp/util/yp_string.c index 5f588bc261..248c082a86 100644 --- a/yarp/util/yp_string.c +++ b/yarp/util/yp_string.c @@ -1,11 +1,5 @@ #include "yarp/util/yp_string.h" -// Allocate a new yp_string_t. -yp_string_t * -yp_string_alloc(void) { - return (yp_string_t *) malloc(sizeof(yp_string_t)); -} - // Initialize a shared string that is based on initial input. void yp_string_shared_init(yp_string_t *string, const char *start, const char *end) { diff --git a/yarp/util/yp_string.h b/yarp/util/yp_string.h index b866d14c8d..eecd71ea5b 100644 --- a/yarp/util/yp_string.h +++ b/yarp/util/yp_string.h @@ -29,9 +29,6 @@ typedef struct { } as; } yp_string_t; -// Allocate a new yp_string_t. -yp_string_t * yp_string_alloc(void); - // Initialize a shared string that is based on initial input. void yp_string_shared_init(yp_string_t *string, const char *start, const char *end); diff --git a/yarp/util/yp_string_list.h b/yarp/util/yp_string_list.h index cd954faf04..ae252eb5d5 100644 --- a/yarp/util/yp_string_list.h +++ b/yarp/util/yp_string_list.h @@ -2,12 +2,11 @@ #define YARP_STRING_LIST_H #include "yarp/defines.h" +#include "yarp/util/yp_string.h" #include <stddef.h> #include <stdlib.h> -#include "yarp/util/yp_string.h" - typedef struct { yp_string_t *strings; size_t length; diff --git a/yarp/missing.c b/yarp/util/yp_strncasecmp.c index 57d8ec0335..899bba4eaa 100644 --- a/yarp/missing.c +++ b/yarp/util/yp_strncasecmp.c @@ -1,19 +1,5 @@ -#include "yarp/missing.h" - -const char * -yp_strnstr(const char *haystack, const char *needle, size_t length) { - size_t needle_length = strlen(needle); - if (needle_length > length) return NULL; - - const char *haystack_limit = haystack + length - needle_length + 1; - - while ((haystack = memchr(haystack, needle[0], (size_t) (haystack_limit - haystack))) != NULL) { - if (!strncmp(haystack, needle, needle_length)) return haystack; - haystack++; - } - - return NULL; -} +#include <ctype.h> +#include <stddef.h> int yp_strncasecmp(const char *string1, const char *string2, size_t length) { diff --git a/yarp/util/yp_strpbrk.c b/yarp/util/yp_strpbrk.c index 7bb619c102..1c32398b55 100644 --- a/yarp/util/yp_strpbrk.c +++ b/yarp/util/yp_strpbrk.c @@ -1,5 +1,42 @@ #include "yarp/util/yp_strpbrk.h" +// This is the slow path that does care about the encoding. +static inline const char * +yp_strpbrk_multi_byte(yp_parser_t *parser, const char *source, const char *charset, size_t maximum) { + size_t index = 0; + + while (index < maximum) { + if (strchr(charset, source[index]) != NULL) { + return source + index; + } + + size_t width = parser->encoding.char_width(source + index); + if (width == 0) { + return NULL; + } + + index += width; + } + + return NULL; +} + +// This is the fast path that does not care about the encoding. +static inline const char * +yp_strpbrk_single_byte(const char *source, const char *charset, size_t maximum) { + size_t index = 0; + + while (index < maximum) { + if (strchr(charset, source[index]) != NULL) { + return source + index; + } + + index++; + } + + return NULL; +} + // Here we have rolled our own version of strpbrk. The standard library strpbrk // has undefined behavior when the source string is not null-terminated. We want // to support strings that are not null-terminated because yp_parse does not @@ -12,19 +49,18 @@ // also don't want it to stop on null bytes. Ruby actually allows null bytes // within strings, comments, regular expressions, etc. So we need to be able to // skip past them. +// +// Finally, we want to support encodings wherein the charset could contain +// characters that are trailing bytes of multi-byte characters. For example, in +// Shift-JIS, the backslash character can be a trailing byte. In that case we +// need to take a slower path and iterate one multi-byte character at a time. const char * -yp_strpbrk(const char *source, const char *charset, ptrdiff_t length) { - if (length < 0) return NULL; - - size_t index = 0; - size_t maximum = (size_t) length; - - while (index < maximum) { - if (strchr(charset, source[index]) != NULL) { - return &source[index]; - } - index++; +yp_strpbrk(yp_parser_t *parser, const char *source, const char *charset, ptrdiff_t length) { + if (length <= 0) { + return NULL; + } else if (parser->encoding_changed && parser->encoding.multibyte) { + return yp_strpbrk_multi_byte(parser, source, charset, (size_t) length); + } else { + return yp_strpbrk_single_byte(source, charset, (size_t) length); } - - return NULL; } diff --git a/yarp/util/yp_strpbrk.h b/yarp/util/yp_strpbrk.h index c9c924514a..7a664d5452 100644 --- a/yarp/util/yp_strpbrk.h +++ b/yarp/util/yp_strpbrk.h @@ -2,6 +2,7 @@ #define YP_STRPBRK_H #include "yarp/defines.h" +#include "yarp/parser.h" #include <stddef.h> #include <string.h> @@ -18,6 +19,11 @@ // also don't want it to stop on null bytes. Ruby actually allows null bytes // within strings, comments, regular expressions, etc. So we need to be able to // skip past them. -const char * yp_strpbrk(const char *source, const char *charset, ptrdiff_t length); +// +// Finally, we want to support encodings wherein the charset could contain +// characters that are trailing bytes of multi-byte characters. For example, in +// Shift-JIS, the backslash character can be a trailing byte. In that case we +// need to take a slower path and iterate one multi-byte character at a time. +const char * yp_strpbrk(yp_parser_t *parser, const char *source, const char *charset, ptrdiff_t length); #endif diff --git a/yarp/version.h b/yarp/version.h new file mode 100644 index 0000000000..d8d9b024de --- /dev/null +++ b/yarp/version.h @@ -0,0 +1,5 @@ +#define YP_VERSION_MAJOR 0 +#define YP_VERSION_MINOR 4 +#define YP_VERSION_PATCH 0 + +#define YP_VERSION "0.4.0" diff --git a/yarp/yarp.c b/yarp/yarp.c index 00582039e3..7b91b04e19 100644 --- a/yarp/yarp.c +++ b/yarp/yarp.c @@ -1,16 +1,19 @@ #include "yarp.h" +#include "yarp/version.h" -#define YP_STRINGIZE0(expr) #expr -#define YP_STRINGIZE(expr) YP_STRINGIZE0(expr) -#define YP_VERSION_MACRO YP_STRINGIZE(YP_VERSION_MAJOR) "." YP_STRINGIZE(YP_VERSION_MINOR) "." YP_STRINGIZE(YP_VERSION_PATCH) - -#define YP_TAB_WHITESPACE_SIZE 8 - +// The YARP version and the serialization format. const char * yp_version(void) { - return YP_VERSION_MACRO; + return YP_VERSION; } +// In heredocs, tabs automatically complete up to the next 8 spaces. This is +// defined in CRuby as TAB_WIDTH. +#define YP_TAB_WHITESPACE_SIZE 8 + +// Debugging logging will provide you will additional debugging functions as +// well as automatically replace some functions with their debugging +// counterparts. #ifndef YP_DEBUG_LOGGING #define YP_DEBUG_LOGGING 0 #endif @@ -442,6 +445,7 @@ not_provided(yp_parser_t *parser) { return (yp_token_t) { .type = YP_TOKEN_NOT_PROVIDED, .start = parser->start, .end = parser->start }; } +#define YP_EMPTY_STRING ((yp_string_t) { .type = YP_STRING_SHARED, .as.shared.start = NULL, .as.shared.end = NULL }) #define YP_LOCATION_NULL_VALUE(parser) ((yp_location_t) { .start = parser->start, .end = parser->start }) #define YP_LOCATION_TOKEN_VALUE(token) ((yp_location_t) { .start = (token)->start, .end = (token)->end }) #define YP_LOCATION_NODE_VALUE(node) ((yp_location_t) { .start = (node)->location.start, .end = (node)->location.end }) @@ -675,7 +679,9 @@ yp_array_pattern_node_node_list_create(yp_parser_t *parser, yp_node_list_t *node .constant = NULL, .rest = NULL, .requireds = YP_EMPTY_NODE_LIST, - .posts = YP_EMPTY_NODE_LIST + .posts = YP_EMPTY_NODE_LIST, + .opening_loc = YP_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE, + .closing_loc = YP_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE }; // For now we're going to just copy over each pointer manually. This could be @@ -684,7 +690,7 @@ yp_array_pattern_node_node_list_create(yp_parser_t *parser, yp_node_list_t *node for (size_t index = 0; index < nodes->size; index++) { yp_node_t *child = nodes->nodes[index]; - if (child->type == YP_NODE_SPLAT_NODE) { + if (!found_rest && child->type == YP_NODE_SPLAT_NODE) { node->rest = child; found_rest = true; } else if (found_rest) { @@ -710,7 +716,9 @@ yp_array_pattern_node_rest_create(yp_parser_t *parser, yp_node_t *rest) { .constant = NULL, .rest = rest, .requireds = YP_EMPTY_NODE_LIST, - .posts = YP_EMPTY_NODE_LIST + .posts = YP_EMPTY_NODE_LIST, + .opening_loc = YP_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE, + .closing_loc = YP_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE }; return node; @@ -1885,7 +1893,9 @@ yp_find_pattern_node_create(yp_parser_t *parser, yp_node_list_t *nodes) { .constant = NULL, .left = left, .right = right, - .requireds = YP_EMPTY_NODE_LIST + .requireds = YP_EMPTY_NODE_LIST, + .opening_loc = YP_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE, + .closing_loc = YP_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE }; // For now we're going to just copy over each pointer manually. This could be @@ -2018,7 +2028,9 @@ yp_hash_pattern_node_node_list_create(yp_parser_t *parser, yp_node_list_t *assoc }, .constant = NULL, .kwrest = NULL, - .assocs = YP_EMPTY_NODE_LIST + .assocs = YP_EMPTY_NODE_LIST, + .opening_loc = YP_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE, + .closing_loc = YP_OPTIONAL_LOCATION_NOT_PROVIDED_VALUE }; for (size_t index = 0; index < assocs->size; index++) { @@ -3709,7 +3721,8 @@ yp_string_node_create(yp_parser_t *parser, const yp_token_t *opening, const yp_t }, .opening_loc = YP_OPTIONAL_LOCATION_TOKEN_VALUE(opening), .content_loc = YP_LOCATION_TOKEN_VALUE(content), - .closing_loc = YP_OPTIONAL_LOCATION_TOKEN_VALUE(closing) + .closing_loc = YP_OPTIONAL_LOCATION_TOKEN_VALUE(closing), + .unescaped = YP_EMPTY_STRING }; return node; @@ -3766,7 +3779,8 @@ yp_symbol_node_create(yp_parser_t *parser, const yp_token_t *opening, const yp_t }, .opening_loc = YP_OPTIONAL_LOCATION_TOKEN_VALUE(opening), .value_loc = YP_LOCATION_TOKEN_VALUE(value), - .closing_loc = YP_OPTIONAL_LOCATION_TOKEN_VALUE(closing) + .closing_loc = YP_OPTIONAL_LOCATION_TOKEN_VALUE(closing), + .unescaped = YP_EMPTY_STRING }; return node; @@ -3788,7 +3802,7 @@ yp_symbol_node_label_create(yp_parser_t *parser, const yp_token_t *token) { ptrdiff_t length = label.end - label.start; assert(length >= 0); - yp_unescape_manipulate_string(label.start, (size_t) length, &node->unescaped, YP_UNESCAPE_ALL, &parser->error_list); + yp_unescape_manipulate_string(parser, label.start, (size_t) length, &node->unescaped, YP_UNESCAPE_ALL, &parser->error_list); break; } case YP_TOKEN_MISSING: { @@ -4073,7 +4087,8 @@ yp_xstring_node_create(yp_parser_t *parser, const yp_token_t *opening, const yp_ }, .opening_loc = YP_LOCATION_TOKEN_VALUE(opening), .content_loc = YP_LOCATION_TOKEN_VALUE(content), - .closing_loc = YP_LOCATION_TOKEN_VALUE(closing) + .closing_loc = YP_LOCATION_TOKEN_VALUE(closing), + .unescaped = YP_EMPTY_STRING }; return node; @@ -4113,6 +4128,7 @@ yp_yield_node_create(yp_parser_t *parser, const yp_token_t *keyword, const yp_lo } +#undef YP_EMPTY_STRING #undef YP_LOCATION_NULL_VALUE #undef YP_LOCATION_TOKEN_VALUE #undef YP_LOCATION_NODE_VALUE @@ -4331,6 +4347,17 @@ peek(yp_parser_t *parser) { } } +// Get the next string of length len in the source starting from parser->current.end. +// If the string extends beyond the end of the source, return the empty string "" +static inline const char* +peek_string(yp_parser_t *parser, size_t len) { + if (parser->current.end + len <= parser->end) { + return parser->current.end; + } else { + return ""; + } +} + // If the character to be read matches the given value, then returns true and // advanced the current pointer. static inline bool @@ -4342,22 +4369,53 @@ match(yp_parser_t *parser, char value) { return false; } +// Skip to the next newline character or NUL byte. +static inline const char * +next_newline(const char *cursor, ptrdiff_t length) { + assert(length >= 0); + + // Note that it's okay for us to use memchr here to look for \n because none + // of the encodings that we support have \n as a component of a multi-byte + // character. + return memchr(cursor, '\n', (size_t) length); +} + +// Find the start of the encoding comment. This is effectively an inlined +// version of strnstr with some modifications. +static inline const char * +parser_lex_encoding_comment_start(yp_parser_t *parser, const char *cursor, ptrdiff_t remaining) { + assert(remaining >= 0); + size_t length = (size_t) remaining; + + size_t key_length = strlen("coding:"); + if (key_length > length) return NULL; + + const char *cursor_limit = cursor + length - key_length + 1; + while ((cursor = yp_memchr(parser, cursor, 'c', (size_t) (cursor_limit - cursor))) != NULL) { + if ( + (strncmp(cursor, "coding", key_length - 1) == 0) && + (cursor[key_length - 1] == ':' || cursor[key_length - 1] == '=') + ) { + return cursor + key_length; + } + + cursor++; + } + + return NULL; +} + // Here we're going to check if this is a "magic" comment, and perform whatever // actions are necessary for it here. static void parser_lex_encoding_comment(yp_parser_t *parser) { const char *start = parser->current.start + 1; - const char *end = memchr(start, '\n', (size_t) (parser->end - start)); + const char *end = next_newline(start, parser->end - start); if (end == NULL) end = parser->end; // These are the patterns we're going to match to find the encoding comment. // This is definitely not complete or even really correct. - const char *encoding_start = NULL; - if ((encoding_start = yp_strnstr(start, "coding:", (size_t) (end - start))) != NULL) { - encoding_start += 7; - } else if ((encoding_start = yp_strnstr(start, "coding=", (size_t) (end - start))) != NULL) { - encoding_start += 7; - } + const char *encoding_start = parser_lex_encoding_comment_start(parser, start, end - start); // If we didn't find anything that matched our patterns, then return. Note // that this does a _very_ poor job of actually finding the encoding, and @@ -4370,7 +4428,7 @@ parser_lex_encoding_comment(yp_parser_t *parser) { // Now determine the end of the encoding string. This is either the end of // the line, the first whitespace character, or a punctuation mark. - const char *encoding_end = yp_strpbrk(encoding_start, " \t\f\r\v\n;,", end - encoding_start); + const char *encoding_end = yp_strpbrk(parser, encoding_start, " \t\f\r\v\n;,", end - encoding_start); encoding_end = encoding_end == NULL ? end : encoding_end; // Finally, we can determine the width of the encoding string. @@ -4392,7 +4450,7 @@ parser_lex_encoding_comment(yp_parser_t *parser) { // Extensions like utf-8 can contain extra encoding details like, // utf-8-dos, utf-8-linux, utf-8-mac. We treat these all as utf-8 should // treat any encoding starting utf-8 as utf-8. - if (strncasecmp(encoding_start, "utf-8", 5) == 0) { + if ((encoding_start + 5 <= parser->end) && (yp_strncasecmp(encoding_start, "utf-8", 5) == 0)) { // We don't need to do anything here because the default encoding is // already UTF-8. We'll just return. return; @@ -4401,7 +4459,7 @@ parser_lex_encoding_comment(yp_parser_t *parser) { // Next, we're going to loop through each of the encodings that we handle // explicitly. If we found one that we understand, we'll use that value. #define ENCODING(value, prebuilt) \ - if (width == sizeof(value) - 1 && strncasecmp(encoding_start, value, sizeof(value) - 1) == 0) { \ + if (width == sizeof(value) - 1 && encoding_start + width <= parser->end && yp_strncasecmp(encoding_start, value, width) == 0) { \ parser->encoding = prebuilt; \ parser->encoding_changed |= true; \ if (parser->encoding_changed_callback != NULL) parser->encoding_changed_callback(parser); \ @@ -4866,7 +4924,8 @@ static yp_token_type_t lex_keyword(yp_parser_t *parser, const char *value, yp_lex_state_t state, yp_token_type_t type, yp_token_type_t modifier_type) { yp_lex_state_t last_state = parser->lex_state; - if (strncmp(parser->current.start, value, strlen(value)) == 0) { + const size_t vlen = strlen(value); + if (parser->current.start + vlen <= parser->end && strncmp(parser->current.start, value, vlen) == 0) { if (parser->lex_state & YP_LEX_STATE_FNAME) { lex_state_set(parser, YP_LEX_STATE_ENDFN); } else { @@ -5275,7 +5334,7 @@ parser_comment(yp_parser_t *parser, yp_comment_type_t type) { static yp_token_type_t lex_embdoc(yp_parser_t *parser) { // First, lex out the EMBDOC_BEGIN token. - const char *newline = memchr(parser->current.end, '\n', (size_t) (parser->end - parser->current.end)); + const char *newline = next_newline(parser->current.end, parser->end - parser->current.end); if (newline == NULL) { parser->current.end = parser->end; @@ -5300,7 +5359,7 @@ lex_embdoc(yp_parser_t *parser) { // token here. if (strncmp(parser->current.end, "=end", 4) == 0 && (parser->current.end + 4 == parser->end || yp_char_is_whitespace(parser->current.end[4]))) { - const char *newline = memchr(parser->current.end, '\n', (size_t) (parser->end - parser->current.end)); + const char *newline = next_newline(parser->current.end, parser->end - parser->current.end); if (newline == NULL) { parser->current.end = parser->end; @@ -5320,7 +5379,7 @@ lex_embdoc(yp_parser_t *parser) { // Otherwise, we'll parse until the end of the line and return a line of // embedded documentation. - const char *newline = memchr(parser->current.end, '\n', (size_t) (parser->end - parser->current.end)); + const char *newline = next_newline(parser->current.end, parser->end - parser->current.end); if (newline == NULL) { parser->current.end = parser->end; @@ -5466,9 +5525,9 @@ parser_lex(yp_parser_t *parser) { LEX(YP_TOKEN_EOF); case '#': { // comments - const char *ending = memchr(parser->current.end, '\n', (size_t) (parser->end - parser->current.end)); + const char *ending = next_newline(parser->current.end, parser->end - parser->current.end); while (ending && ending < parser->end && *ending != '\n') { - ending = memchr(ending + 1, '\n', (size_t) (parser->end - ending)); + ending = next_newline(ending + 1, parser->end - ending); } parser->current.end = ending == NULL ? parser->end : ending + 1; @@ -5540,7 +5599,7 @@ parser_lex(yp_parser_t *parser) { // Otherwise we'll return a regular newline. if (next_content[0] == '#') { // Here we look for a "." or "&." following a "\n". - const char *following = memchr(next_content, '\n', (size_t) (parser->end - next_content)); + const char *following = next_newline(next_content, parser->end - next_content); while (following && (following < parser->end)) { following++; @@ -5552,7 +5611,7 @@ parser_lex(yp_parser_t *parser) { // If there is a comment, then we need to find the end of the // comment and continue searching from there. - following = memchr(following, '\n', (size_t) (parser->end - following)); + following = next_newline(following, parser->end - following); } // If the lex state was ignored, or we hit a '.' or a '&.', @@ -5785,7 +5844,7 @@ parser_lex(yp_parser_t *parser) { // = => =~ == === =begin case '=': - if (current_token_starts_line(parser) && strncmp(parser->current.end, "begin", 5) == 0 && yp_char_is_whitespace(parser->current.end[5])) { + if (current_token_starts_line(parser) && strncmp(peek_string(parser, 5), "begin", 5) == 0 && yp_char_is_whitespace(peek_at(parser, 5))) { yp_token_type_t type = lex_embdoc(parser); if (type == YP_TOKEN_EOF) { @@ -5848,19 +5907,21 @@ parser_lex(yp_parser_t *parser) { const char *ident_start = parser->current.end; size_t width = 0; - if (quote == YP_HEREDOC_QUOTE_NONE && (width = char_is_identifier(parser, parser->current.end)) == 0) { + if (parser->current.end >= parser->end) { + parser->current.end = end; + } else if (quote == YP_HEREDOC_QUOTE_NONE && (width = char_is_identifier(parser, parser->current.end)) == 0) { parser->current.end = end; } else { if (quote == YP_HEREDOC_QUOTE_NONE) { parser->current.end += width; - while ((width = char_is_identifier(parser, parser->current.end))) { + while ((parser->current.end < parser->end) && (width = char_is_identifier(parser, parser->current.end))) { parser->current.end += width; } } else { // If we have quotes, then we're going to go until we find the // end quote. - while (parser->current.end < parser->end && quote != (yp_heredoc_quote_t) (*parser->current.end)) { + while ((parser->current.end < parser->end) && quote != (yp_heredoc_quote_t) (*parser->current.end)) { parser->current.end++; } } @@ -5882,7 +5943,7 @@ parser_lex(yp_parser_t *parser) { }); if (parser->heredoc_end == NULL) { - const char *body_start = (const char *) memchr(parser->current.end, '\n', (size_t) (parser->end - parser->current.end)); + const char *body_start = next_newline(parser->current.end, parser->end - parser->current.end); if (body_start == NULL) { // If there is no newline after the heredoc identifier, then @@ -6465,13 +6526,13 @@ parser_lex(yp_parser_t *parser) { // Here we'll get a list of the places where strpbrk should break, // and then find the first one. const char *breakpoints = parser->lex_modes.current->as.list.breakpoints; - const char *breakpoint = yp_strpbrk(parser->current.end, breakpoints, parser->end - parser->current.end); + const char *breakpoint = yp_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end); while (breakpoint != NULL) { switch (*breakpoint) { case '\0': // If we hit a null byte, skip directly past it. - breakpoint = yp_strpbrk(breakpoint + 1, breakpoints, parser->end - (breakpoint + 1)); + breakpoint = yp_strpbrk(parser, breakpoint + 1, breakpoints, parser->end - (breakpoint + 1)); break; case '\\': { // If we hit escapes, then we need to treat the next token @@ -6492,7 +6553,7 @@ parser_lex(yp_parser_t *parser) { yp_newline_list_append(&parser->newline_list, breakpoint + difference - 1); } - breakpoint = yp_strpbrk(breakpoint + difference, breakpoints, parser->end - (breakpoint + difference)); + breakpoint = yp_strpbrk(parser, breakpoint + difference, breakpoints, parser->end - (breakpoint + difference)); break; } case ' ': @@ -6517,7 +6578,7 @@ parser_lex(yp_parser_t *parser) { // that looked like an interpolated class or instance variable // like "#@" but wasn't actually. In this case we'll just skip // to the next breakpoint. - breakpoint = yp_strpbrk(parser->current.end, breakpoints, parser->end - parser->current.end); + breakpoint = yp_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end); break; } } @@ -6526,7 +6587,7 @@ parser_lex(yp_parser_t *parser) { if (*breakpoint == parser->lex_modes.current->as.list.incrementor) { // If we've hit the incrementor, then we need to skip past it and // find the next breakpoint. - breakpoint = yp_strpbrk(breakpoint + 1, breakpoints, parser->end - (breakpoint + 1)); + breakpoint = yp_strpbrk(parser, breakpoint + 1, breakpoints, parser->end - (breakpoint + 1)); parser->lex_modes.current->as.list.nesting++; break; } @@ -6537,7 +6598,7 @@ parser_lex(yp_parser_t *parser) { // If this terminator doesn't actually close the list, then we need // to continue on past it. if (parser->lex_modes.current->as.list.nesting > 0) { - breakpoint = yp_strpbrk(breakpoint + 1, breakpoints, parser->end - (breakpoint + 1)); + breakpoint = yp_strpbrk(parser, breakpoint + 1, breakpoints, parser->end - (breakpoint + 1)); parser->lex_modes.current->as.list.nesting--; break; } @@ -6577,13 +6638,13 @@ parser_lex(yp_parser_t *parser) { // regular expression. We'll use strpbrk to find the first of these // characters. const char *breakpoints = parser->lex_modes.current->as.regexp.breakpoints; - const char *breakpoint = yp_strpbrk(parser->current.end, breakpoints, parser->end - parser->current.end); + const char *breakpoint = yp_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end); while (breakpoint != NULL) { switch (*breakpoint) { case '\0': // If we hit a null byte, skip directly past it. - breakpoint = yp_strpbrk(breakpoint + 1, breakpoints, parser->end - (breakpoint + 1)); + breakpoint = yp_strpbrk(parser, breakpoint + 1, breakpoints, parser->end - (breakpoint + 1)); break; case '\\': { // If we hit escapes, then we need to treat the next token @@ -6597,7 +6658,7 @@ parser_lex(yp_parser_t *parser) { yp_newline_list_append(&parser->newline_list, breakpoint + difference - 1); } - breakpoint = yp_strpbrk(breakpoint + difference, breakpoints, parser->end - (breakpoint + difference)); + breakpoint = yp_strpbrk(parser, breakpoint + difference, breakpoints, parser->end - (breakpoint + difference)); break; } case '#': { @@ -6613,7 +6674,7 @@ parser_lex(yp_parser_t *parser) { // that looked like an interpolated class or instance variable // like "#@" but wasn't actually. In this case we'll just skip // to the next breakpoint. - breakpoint = yp_strpbrk(parser->current.end, breakpoints, parser->end - parser->current.end); + breakpoint = yp_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end); break; } } @@ -6622,7 +6683,7 @@ parser_lex(yp_parser_t *parser) { if (*breakpoint == parser->lex_modes.current->as.regexp.incrementor) { // If we've hit the incrementor, then we need to skip past it and // find the next breakpoint. - breakpoint = yp_strpbrk(breakpoint + 1, breakpoints, parser->end - (breakpoint + 1)); + breakpoint = yp_strpbrk(parser, breakpoint + 1, breakpoints, parser->end - (breakpoint + 1)); parser->lex_modes.current->as.regexp.nesting++; break; } @@ -6635,7 +6696,7 @@ parser_lex(yp_parser_t *parser) { if (parser->lex_modes.current->as.regexp.terminator != '\n') { // If the terminator is not a newline, then we // can set the next breakpoint and continue. - breakpoint = yp_strpbrk(breakpoint + 1, breakpoints, parser->end - (breakpoint + 1)); + breakpoint = yp_strpbrk(parser, breakpoint + 1, breakpoints, parser->end - (breakpoint + 1)); break; } @@ -6646,7 +6707,7 @@ parser_lex(yp_parser_t *parser) { assert(*breakpoint == parser->lex_modes.current->as.regexp.terminator); if (parser->lex_modes.current->as.regexp.nesting > 0) { - breakpoint = yp_strpbrk(breakpoint + 1, breakpoints, parser->end - (breakpoint + 1)); + breakpoint = yp_strpbrk(parser, breakpoint + 1, breakpoints, parser->end - (breakpoint + 1)); parser->lex_modes.current->as.regexp.nesting--; break; } @@ -6694,7 +6755,7 @@ parser_lex(yp_parser_t *parser) { // These are the places where we need to split up the content of the // string. We'll use strpbrk to find the first of these characters. const char *breakpoints = parser->lex_modes.current->as.string.breakpoints; - const char *breakpoint = yp_strpbrk(parser->current.end, breakpoints, parser->end - parser->current.end); + const char *breakpoint = yp_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end); while (breakpoint != NULL) { // If we hit the incrementor, then we'll increment then nesting and @@ -6704,7 +6765,7 @@ parser_lex(yp_parser_t *parser) { *breakpoint == parser->lex_modes.current->as.string.incrementor ) { parser->lex_modes.current->as.string.nesting++; - breakpoint = yp_strpbrk(breakpoint + 1, breakpoints, parser->end - (breakpoint + 1)); + breakpoint = yp_strpbrk(parser, breakpoint + 1, breakpoints, parser->end - (breakpoint + 1)); continue; } @@ -6715,7 +6776,7 @@ parser_lex(yp_parser_t *parser) { // If this terminator doesn't actually close the string, then we need // to continue on past it. if (parser->lex_modes.current->as.string.nesting > 0) { - breakpoint = yp_strpbrk(breakpoint + 1, breakpoints, parser->end - (breakpoint + 1)); + breakpoint = yp_strpbrk(parser, breakpoint + 1, breakpoints, parser->end - (breakpoint + 1)); parser->lex_modes.current->as.string.nesting--; continue; } @@ -6762,7 +6823,7 @@ parser_lex(yp_parser_t *parser) { if (*breakpoint == '\n') { if (parser->heredoc_end == NULL) { yp_newline_list_append(&parser->newline_list, breakpoint); - breakpoint = yp_strpbrk(breakpoint + 1, breakpoints, parser->end - (breakpoint + 1)); + breakpoint = yp_strpbrk(parser, breakpoint + 1, breakpoints, parser->end - (breakpoint + 1)); continue; } else { parser->current.end = breakpoint + 1; @@ -6774,7 +6835,7 @@ parser_lex(yp_parser_t *parser) { switch (*breakpoint) { case '\0': // Skip directly past the null character. - breakpoint = yp_strpbrk(breakpoint + 1, breakpoints, parser->end - (breakpoint + 1)); + breakpoint = yp_strpbrk(parser, breakpoint + 1, breakpoints, parser->end - (breakpoint + 1)); break; case '\\': { // If we hit escapes, then we need to treat the next token @@ -6789,7 +6850,7 @@ parser_lex(yp_parser_t *parser) { yp_newline_list_append(&parser->newline_list, breakpoint + difference - 1); } - breakpoint = yp_strpbrk(breakpoint + difference, breakpoints, parser->end - (breakpoint + difference)); + breakpoint = yp_strpbrk(parser, breakpoint + difference, breakpoints, parser->end - (breakpoint + difference)); break; } case '#': { @@ -6802,7 +6863,7 @@ parser_lex(yp_parser_t *parser) { // looked like an interpolated class or instance variable like "#@" // but wasn't actually. In this case we'll just skip to the next // breakpoint. - breakpoint = yp_strpbrk(parser->current.end, breakpoints, parser->end - parser->current.end); + breakpoint = yp_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end); break; } default: @@ -6844,7 +6905,7 @@ parser_lex(yp_parser_t *parser) { start += yp_strspn_inline_whitespace(start, parser->end - start); } - if (strncmp(start, ident_start, ident_length) == 0) { + if ((start + ident_length <= parser->end) && (strncmp(start, ident_start, ident_length) == 0)) { bool matched = true; bool at_end = false; @@ -6888,13 +6949,13 @@ parser_lex(yp_parser_t *parser) { breakpoints[2] = '\0'; } - const char *breakpoint = yp_strpbrk(parser->current.end, breakpoints, parser->end - parser->current.end); + const char *breakpoint = yp_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end); while (breakpoint != NULL) { switch (*breakpoint) { case '\0': // Skip directly past the null character. - breakpoint = yp_strpbrk(breakpoint + 1, breakpoints, parser->end - (breakpoint + 1)); + breakpoint = yp_strpbrk(parser, breakpoint + 1, breakpoints, parser->end - (breakpoint + 1)); break; case '\n': { yp_newline_list_append(&parser->newline_list, breakpoint); @@ -6939,7 +7000,7 @@ parser_lex(yp_parser_t *parser) { // Otherwise we hit a newline and it wasn't followed by a // terminator, so we can continue parsing. - breakpoint = yp_strpbrk(breakpoint + 1, breakpoints, parser->end - (breakpoint + 1)); + breakpoint = yp_strpbrk(parser, breakpoint + 1, breakpoints, parser->end - (breakpoint + 1)); break; } case '\\': { @@ -6956,7 +7017,7 @@ parser_lex(yp_parser_t *parser) { yp_newline_list_append(&parser->newline_list, breakpoint + difference - 1); } - breakpoint = yp_strpbrk(breakpoint + difference, breakpoints, parser->end - (breakpoint + difference)); + breakpoint = yp_strpbrk(parser, breakpoint + difference, breakpoints, parser->end - (breakpoint + difference)); } break; } @@ -6970,7 +7031,7 @@ parser_lex(yp_parser_t *parser) { // that looked like an interpolated class or instance variable // like "#@" but wasn't actually. In this case we'll just skip // to the next breakpoint. - breakpoint = yp_strpbrk(parser->current.end, breakpoints, parser->end - parser->current.end); + breakpoint = yp_strpbrk(parser, parser->current.end, breakpoints, parser->end - parser->current.end); break; } default: @@ -7007,7 +7068,7 @@ yp_regular_expression_node_create_and_unescape(yp_parser_t *parser, const yp_tok ptrdiff_t length = content->end - content->start; assert(length >= 0); - yp_unescape_manipulate_string(content->start, (size_t) length, &node->unescaped, unescape_type, &parser->error_list); + yp_unescape_manipulate_string(parser, content->start, (size_t) length, &node->unescaped, unescape_type, &parser->error_list); return node; } @@ -7018,7 +7079,7 @@ yp_symbol_node_create_and_unescape(yp_parser_t *parser, const yp_token_t *openin ptrdiff_t length = content->end - content->start; assert(length >= 0); - yp_unescape_manipulate_string(content->start, (size_t) length, &node->unescaped, unescape_type, &parser->error_list); + yp_unescape_manipulate_string(parser, content->start, (size_t) length, &node->unescaped, unescape_type, &parser->error_list); return node; } @@ -7029,7 +7090,7 @@ yp_string_node_create_and_unescape(yp_parser_t *parser, const yp_token_t *openin ptrdiff_t length = content->end - content->start; assert(length >= 0); - yp_unescape_manipulate_string(content->start, (size_t) length, &node->unescaped, unescape_type, &parser->error_list); + yp_unescape_manipulate_string(parser, content->start, (size_t) length, &node->unescaped, unescape_type, &parser->error_list); return node; } @@ -7040,7 +7101,7 @@ yp_xstring_node_create_and_unescape(yp_parser_t *parser, const yp_token_t *openi ptrdiff_t length = content->end - content->start; assert(length >= 0); - yp_unescape_manipulate_string(content->start, (size_t) length, &node->unescaped, YP_UNESCAPE_ALL, &parser->error_list); + yp_unescape_manipulate_string(parser, content->start, (size_t) length, &node->unescaped, YP_UNESCAPE_ALL, &parser->error_list); return node; } @@ -7505,10 +7566,10 @@ parse_target(yp_parser_t *parser, yp_node_t *target, yp_token_t *operator, yp_no // the previous method name in, and append an =. size_t length = yp_string_length(&call->name); - char *name = malloc(length + 2); + char *name = calloc(length + 2, sizeof(char)); if (name == NULL) return NULL; - sprintf(name, "%.*s=", (int) length, yp_string_source(&call->name)); + yp_snprintf(name, length + 2, "%.*s=", (int) length, yp_string_source(&call->name)); // Now switch the name to the new string. yp_string_free(&call->name); @@ -8954,9 +9015,11 @@ parse_string_part(yp_parser_t *parser) { static yp_node_t * parse_symbol(yp_parser_t *parser, yp_lex_mode_t *lex_mode, yp_lex_state_t next_state) { + bool lex_string = lex_mode->mode == YP_LEX_STRING; + bool lex_interpolation = lex_string && lex_mode->as.string.interpolation; yp_token_t opening = parser->previous; - if (lex_mode->mode != YP_LEX_STRING) { + if (!lex_string) { if (next_state != YP_LEX_STATE_NONE) { lex_state_set(parser, next_state); } @@ -8990,9 +9053,9 @@ parse_symbol(yp_parser_t *parser, yp_lex_mode_t *lex_mode, yp_lex_state_t next_s } // If we weren't in a string in the previous check then we have to be now. - assert(lex_mode->mode == YP_LEX_STRING); + assert(lex_string); - if (lex_mode->as.string.interpolation) { + if (lex_interpolation) { yp_interpolated_symbol_node_t *interpolated = yp_interpolated_symbol_node_create(parser, &opening, NULL, &opening); while (!match_any_type_p(parser, 2, YP_TOKEN_STRING_END, YP_TOKEN_EOF)) { @@ -9043,9 +9106,10 @@ parse_undef_argument(yp_parser_t *parser) { return (yp_node_t *) yp_symbol_node_create_and_unescape(parser, &opening, &parser->previous, &closing, YP_UNESCAPE_ALL); } case YP_TOKEN_SYMBOL_BEGIN: { - yp_lex_mode_t *lex_mode = parser->lex_modes.current; + yp_lex_mode_t lex_mode = *parser->lex_modes.current; parser_lex(parser); - return parse_symbol(parser, lex_mode, YP_LEX_STATE_NONE); + + return parse_symbol(parser, &lex_mode, YP_LEX_STATE_NONE); } default: yp_diagnostic_list_append(&parser->error_list, parser->current.start, parser->current.end, "Expected a bare word or symbol argument."); @@ -9075,10 +9139,10 @@ parse_alias_argument(yp_parser_t *parser, bool first) { return (yp_node_t *) yp_symbol_node_create_and_unescape(parser, &opening, &parser->previous, &closing, YP_UNESCAPE_ALL); } case YP_TOKEN_SYMBOL_BEGIN: { - yp_lex_mode_t *lex_mode = parser->lex_modes.current; + yp_lex_mode_t lex_mode = *parser->lex_modes.current; parser_lex(parser); - return parse_symbol(parser, lex_mode, first ? YP_LEX_STATE_FNAME | YP_LEX_STATE_FITEM : YP_LEX_STATE_NONE); + return parse_symbol(parser, &lex_mode, first ? YP_LEX_STATE_FNAME | YP_LEX_STATE_FITEM : YP_LEX_STATE_NONE); } case YP_TOKEN_BACK_REFERENCE: parser_lex(parser); @@ -9177,7 +9241,7 @@ parse_heredoc_common_whitespace(yp_parser_t *parser, yp_node_list_t *nodes) { common_whitespace = cur_whitespace; } - cur_char = memchr(cur_char + 1, '\n', (size_t) (parser->end - (cur_char + 1))); + cur_char = next_newline(cur_char + 1, parser->end - (cur_char + 1)); if (cur_char) cur_char++; } } @@ -9252,7 +9316,7 @@ parse_heredoc_dedent(yp_parser_t *parser, yp_node_t *node, yp_heredoc_quote_t qu // At this point we have dedented all that we need to, so we need to find // the next newline. - const char *breakpoint = memchr(source_cursor, '\n', (size_t) (source_end - source_cursor)); + const char *breakpoint = next_newline(source_cursor, source_end - source_cursor); if (breakpoint == NULL) { // If there isn't another newline, then we can just move the rest of the @@ -9293,92 +9357,106 @@ parse_pattern_constant_path(yp_parser_t *parser, yp_node_t *node) { // If there is a [ or ( that follows, then this is part of a larger pattern // expression. We'll parse the inner pattern here, then modify the returned // inner pattern with our constant path attached. - if (match_any_type_p(parser, 2, YP_TOKEN_BRACKET_LEFT, YP_TOKEN_PARENTHESIS_LEFT)) { - yp_token_t opening; - yp_token_t closing; - yp_node_t *inner = NULL; + if (!match_any_type_p(parser, 2, YP_TOKEN_BRACKET_LEFT, YP_TOKEN_PARENTHESIS_LEFT)) { + return node; + } - if (accept(parser, YP_TOKEN_BRACKET_LEFT)) { - opening = parser->previous; + yp_token_t opening; + yp_token_t closing; + yp_node_t *inner = NULL; + if (accept(parser, YP_TOKEN_BRACKET_LEFT)) { + opening = parser->previous; + accept(parser, YP_TOKEN_NEWLINE); + + if (!accept(parser, YP_TOKEN_BRACKET_RIGHT)) { + inner = parse_pattern(parser, true, "Expected a pattern expression after the [ operator."); accept(parser, YP_TOKEN_NEWLINE); + expect(parser, YP_TOKEN_BRACKET_RIGHT, "Expected a ] to close the pattern expression."); + } - if (!accept(parser, YP_TOKEN_BRACKET_RIGHT)) { - inner = parse_pattern(parser, true, "Expected a pattern expression after the [ operator."); - accept(parser, YP_TOKEN_NEWLINE); + closing = parser->previous; + } else { + parser_lex(parser); + opening = parser->previous; - expect(parser, YP_TOKEN_BRACKET_RIGHT, "Expected a ] to close the pattern expression."); - } + if (!accept(parser, YP_TOKEN_PARENTHESIS_RIGHT)) { + inner = parse_pattern(parser, true, "Expected a pattern expression after the ( operator."); + expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, "Expected a ) to close the pattern expression."); + } - closing = parser->previous; - } else { - parser_lex(parser); - opening = parser->previous; + closing = parser->previous; + } + + if (!inner) { + // If there was no inner pattern, then we have something like Foo() or + // Foo[]. In that case we'll create an array pattern with no requireds. + return (yp_node_t *) yp_array_pattern_node_constant_create(parser, node, &opening, &closing); + } + + // Now that we have the inner pattern, check to see if it's an array, find, + // or hash pattern. If it is, then we'll attach our constant path to it if + // it doesn't already have a constant. If it's not one of those node types + // or it does have a constant, then we'll create an array pattern. + switch (inner->type) { + case YP_NODE_ARRAY_PATTERN_NODE: { + yp_array_pattern_node_t *pattern_node = (yp_array_pattern_node_t *) inner; + + if (pattern_node->constant == NULL) { + pattern_node->base.location.start = node->location.start; + pattern_node->base.location.end = closing.end; - if (!accept(parser, YP_TOKEN_PARENTHESIS_RIGHT)) { - inner = parse_pattern(parser, true, "Expected a pattern expression after the ( operator."); - expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, "Expected a ) to close the pattern expression."); + pattern_node->constant = node; + pattern_node->opening_loc = (yp_location_t) { .start = opening.start, .end = opening.end }; + pattern_node->closing_loc = (yp_location_t) { .start = closing.start, .end = closing.end }; + + return (yp_node_t *) pattern_node; } - closing = parser->previous; + break; } + case YP_NODE_FIND_PATTERN_NODE: { + yp_find_pattern_node_t *pattern_node = (yp_find_pattern_node_t *) inner; - if (inner) { - // Now that we have the inner pattern, check to see if it's an array, find, - // or hash pattern. If it is, then we'll attach our constant path to it. If - // it's not, then we'll create an array pattern. - switch (inner->type) { - case YP_NODE_ARRAY_PATTERN_NODE: { - yp_array_pattern_node_t *pattern_node = (yp_array_pattern_node_t *)inner; - pattern_node->base.location.start = node->location.start; - pattern_node->base.location.end = closing.end; + if (pattern_node->constant == NULL) { + pattern_node->base.location.start = node->location.start; + pattern_node->base.location.end = closing.end; - pattern_node->constant = node; - pattern_node->opening_loc = (yp_location_t) { .start = opening.start, .end = opening.end }; - pattern_node->closing_loc = (yp_location_t) { .start = closing.start, .end = closing.end }; + pattern_node->constant = node; + pattern_node->opening_loc = (yp_location_t) { .start = opening.start, .end = opening.end }; + pattern_node->closing_loc = (yp_location_t) { .start = closing.start, .end = closing.end }; - node = (yp_node_t *)pattern_node; - break; - } - case YP_NODE_FIND_PATTERN_NODE: { - yp_find_pattern_node_t *pattern_node = (yp_find_pattern_node_t *) inner; - pattern_node->base.location.start = node->location.start; - pattern_node->base.location.end = closing.end; + return (yp_node_t *) pattern_node; + } - pattern_node->constant = node; - pattern_node->opening_loc = (yp_location_t) { .start = opening.start, .end = opening.end }; - pattern_node->closing_loc = (yp_location_t) { .start = closing.start, .end = closing.end }; + break; + } + case YP_NODE_HASH_PATTERN_NODE: { + yp_hash_pattern_node_t *pattern_node = (yp_hash_pattern_node_t *) inner; - node = (yp_node_t *) pattern_node; - break; - } - case YP_NODE_HASH_PATTERN_NODE: { - yp_hash_pattern_node_t *pattern_node = (yp_hash_pattern_node_t *)inner; - pattern_node->base.location.start = node->location.start; - pattern_node->base.location.end = closing.end; + if (pattern_node->constant == NULL) { + pattern_node->base.location.start = node->location.start; + pattern_node->base.location.end = closing.end; - pattern_node->constant = node; - pattern_node->opening_loc = (yp_location_t) { .start = opening.start, .end = opening.end }; - pattern_node->closing_loc = (yp_location_t) { .start = closing.start, .end = closing.end }; + pattern_node->constant = node; + pattern_node->opening_loc = (yp_location_t) { .start = opening.start, .end = opening.end }; + pattern_node->closing_loc = (yp_location_t) { .start = closing.start, .end = closing.end }; - node = (yp_node_t *) pattern_node; - break; - } - default: { - yp_array_pattern_node_t *pattern_node = yp_array_pattern_node_constant_create(parser, node, &opening, &closing); - yp_array_pattern_node_requireds_append(pattern_node, inner); - node = (yp_node_t *)pattern_node; - break; - } + return (yp_node_t *) pattern_node; } - } else { - // If there was no inner pattern, then we have something like Foo() or - // Foo[]. In that case we'll create an array pattern with no requireds. - node = (yp_node_t *)yp_array_pattern_node_constant_create(parser, node, &opening, &closing); + + break; } + default: + break; } - return node; + // If we got here, then we didn't return one of the inner patterns by + // attaching its constant. In this case we'll create an array pattern and + // attach our constant to it. + yp_array_pattern_node_t *pattern_node = yp_array_pattern_node_constant_create(parser, node, &opening, &closing); + yp_array_pattern_node_requireds_append(pattern_node, inner); + return (yp_node_t *) pattern_node; } // Parse a rest pattern. @@ -9897,8 +9975,6 @@ parse_pattern(yp_parser_t *parser, bool top_pattern, const char *message) { // Parse an expression that begins with the previous node that we just lexed. static inline yp_node_t * parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { - yp_lex_mode_t *lex_mode = parser->lex_modes.current; - switch (parser->current.type) { case YP_TOKEN_BRACKET_LEFT_ARRAY: { parser_lex(parser); @@ -11015,7 +11091,10 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { lex_state_set(parser, YP_LEX_STATE_FNAME | YP_LEX_STATE_FITEM); parser_lex(parser); name = parse_undef_argument(parser); - if (name->type == YP_NODE_MISSING_NODE) break; + if (name->type == YP_NODE_MISSING_NODE) { + yp_node_destroy(parser, name); + break; + } yp_undef_node_append(undef, name); } @@ -11043,6 +11122,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { receiver = parse_expression(parser, YP_BINDING_POWER_COMPOSITION, "Expected expression after `not`."); if (!parser->recovering) { + accept(parser, YP_TOKEN_NEWLINE); expect(parser, YP_TOKEN_PARENTHESIS_RIGHT, "Expected ')' after 'not' expression."); arguments.closing_loc = ((yp_location_t) { .start = parser->previous.start, .end = parser->previous.end }); } @@ -11727,9 +11807,12 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { return (yp_node_t *) node; } case YP_TOKEN_STRING_BEGIN: { + assert(parser->lex_modes.current->mode == YP_LEX_STRING); + bool lex_interpolation = parser->lex_modes.current->as.string.interpolation; + + yp_token_t opening = parser->current; parser_lex(parser); - yp_token_t opening = parser->previous; yp_node_t *node; if (accept(parser, YP_TOKEN_STRING_END)) { @@ -11754,7 +11837,7 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { }; return (yp_node_t *) yp_symbol_node_create(parser, &opening, &content, &parser->previous); - } else if (!lex_mode->as.string.interpolation) { + } else if (!lex_interpolation) { // If we don't accept interpolation then we expect the string to start // with a single string content node. expect(parser, YP_TOKEN_STRING_CONTENT, "Expected string content after opening delimiter."); @@ -11858,9 +11941,12 @@ parse_expression_prefix(yp_parser_t *parser, yp_binding_power_t binding_power) { return node; } } - case YP_TOKEN_SYMBOL_BEGIN: + case YP_TOKEN_SYMBOL_BEGIN: { + yp_lex_mode_t lex_mode = *parser->lex_modes.current; parser_lex(parser); - return parse_symbol(parser, lex_mode, YP_LEX_STATE_END); + + return parse_symbol(parser, &lex_mode, YP_LEX_STATE_END); + } default: if (context_recoverable(parser, &parser->current)) { parser->recovering = true; @@ -12482,82 +12568,8 @@ parse_expression_infix(yp_parser_t *parser, yp_node_t *node, yp_binding_power_t return path; } - case YP_TOKEN_AMPERSAND: - case YP_TOKEN_BACKTICK: - case YP_TOKEN_BANG: - case YP_TOKEN_BANG_EQUAL: - case YP_TOKEN_BANG_TILDE: - case YP_TOKEN_CARET: - case YP_TOKEN_EQUAL_EQUAL: - case YP_TOKEN_EQUAL_EQUAL_EQUAL: - case YP_TOKEN_EQUAL_TILDE: - case YP_TOKEN_GREATER: - case YP_TOKEN_GREATER_EQUAL: - case YP_TOKEN_GREATER_GREATER: - case YP_TOKEN_HEREDOC_START: - case YP_TOKEN_IGNORED_NEWLINE: - case YP_TOKEN_KEYWORD_ALIAS: - case YP_TOKEN_KEYWORD_AND: - case YP_TOKEN_KEYWORD_BEGIN: - case YP_TOKEN_KEYWORD_BEGIN_UPCASE: - case YP_TOKEN_KEYWORD_BREAK: - case YP_TOKEN_KEYWORD_CASE: - case YP_TOKEN_KEYWORD_CLASS: - case YP_TOKEN_KEYWORD_DEF: - case YP_TOKEN_KEYWORD_DEFINED: - case YP_TOKEN_KEYWORD_DO: - case YP_TOKEN_KEYWORD_ELSE: - case YP_TOKEN_KEYWORD_ELSIF: - case YP_TOKEN_KEYWORD_END: - case YP_TOKEN_KEYWORD_END_UPCASE: - case YP_TOKEN_KEYWORD_ENSURE: - case YP_TOKEN_KEYWORD_FALSE: - case YP_TOKEN_KEYWORD_FOR: - case YP_TOKEN_KEYWORD_IF: - case YP_TOKEN_KEYWORD_IN: - case YP_TOKEN_KEYWORD_NEXT: - case YP_TOKEN_KEYWORD_NIL: - case YP_TOKEN_KEYWORD_NOT: - case YP_TOKEN_KEYWORD_OR: - case YP_TOKEN_KEYWORD_REDO: - case YP_TOKEN_KEYWORD_RESCUE: - case YP_TOKEN_KEYWORD_RETRY: - case YP_TOKEN_KEYWORD_RETURN: - case YP_TOKEN_KEYWORD_SELF: - case YP_TOKEN_KEYWORD_SUPER: - case YP_TOKEN_KEYWORD_THEN: - case YP_TOKEN_KEYWORD_TRUE: - case YP_TOKEN_KEYWORD_UNDEF: - case YP_TOKEN_KEYWORD_UNLESS: - case YP_TOKEN_KEYWORD_UNTIL: - case YP_TOKEN_KEYWORD_WHEN: - case YP_TOKEN_KEYWORD_WHILE: - case YP_TOKEN_KEYWORD_YIELD: - case YP_TOKEN_KEYWORD___ENCODING__: - case YP_TOKEN_KEYWORD___FILE__: - case YP_TOKEN_KEYWORD___LINE__: - case YP_TOKEN_LESS: - case YP_TOKEN_LESS_EQUAL: - case YP_TOKEN_LESS_EQUAL_GREATER: - case YP_TOKEN_LESS_LESS: - case YP_TOKEN_MINUS: - case YP_TOKEN_PERCENT: - case YP_TOKEN_PERCENT_LOWER_I: - case YP_TOKEN_PERCENT_LOWER_W: - case YP_TOKEN_PERCENT_LOWER_X: - case YP_TOKEN_PERCENT_UPPER_I: - case YP_TOKEN_PERCENT_UPPER_W: - case YP_TOKEN_PIPE: - case YP_TOKEN_PLUS: - case YP_TOKEN_REGEXP_BEGIN: - case YP_TOKEN_SLASH: - case YP_TOKEN_STAR: - case YP_TOKEN_STAR_STAR: - case YP_TOKEN_TILDE: - case YP_TOKEN_UCOLON_COLON: - case YP_TOKEN_UDOT_DOT: - case YP_TOKEN_UDOT_DOT_DOT: - case YP_TOKEN___END__: + case YP_CASE_OPERATOR: + case YP_CASE_KEYWORD: case YP_TOKEN_IDENTIFIER: { parser_lex(parser); @@ -12805,7 +12817,7 @@ yp_parser_init(yp_parser_t *parser, const char *source, size_t size, const char } else if (size >= 2 && source[0] == '#' && source[1] == '!') { // If the first two bytes of the source are a shebang, then we'll indicate // that the encoding comment is at the end of the shebang. - const char *encoding_comment_start = memchr(source, '\n', size); + const char *encoding_comment_start = next_newline(source, (ptrdiff_t) size); if (encoding_comment_start) { parser->encoding_comment_start = encoding_comment_start + 1; } @@ -12891,6 +12903,3 @@ yp_parse_serialize(const char *source, size_t size, yp_buffer_t *buffer) { #undef YP_CASE_KEYWORD #undef YP_CASE_OPERATOR #undef YP_CASE_WRITABLE -#undef YP_STRINGIZE -#undef YP_STRINGIZE0 -#undef YP_VERSION_MACRO diff --git a/yarp/yarp.h b/yarp/yarp.h index 3c43876f9d..4bbffdbb10 100644 --- a/yarp/yarp.h +++ b/yarp/yarp.h @@ -2,19 +2,6 @@ #define YARP_H #include "yarp/defines.h" - -#include <assert.h> -#include <stdarg.h> -#include <stdbool.h> -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#ifndef _WIN32 -#include <strings.h> -#endif - -#include "yarp/missing.h" #include "yarp/ast.h" #include "yarp/diagnostic.h" #include "yarp/node.h" @@ -24,17 +11,26 @@ #include "yarp/unescape.h" #include "yarp/util/yp_buffer.h" #include "yarp/util/yp_char.h" +#include "yarp/util/yp_memchr.h" #include "yarp/util/yp_strpbrk.h" -#define YP_VERSION_MAJOR 0 -#define YP_VERSION_MINOR 4 -#define YP_VERSION_PATCH 0 +#include <assert.h> +#include <stdarg.h> +#include <stdbool.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#ifndef _WIN32 +#include <strings.h> +#endif void yp_serialize_content(yp_parser_t *parser, yp_node_t *node, yp_buffer_t *buffer); void yp_print_node(yp_parser_t *parser, yp_node_t *node); -// Returns the YARP version and notably the serialization format +// The YARP version and the serialization format. YP_EXPORTED_FUNCTION const char * yp_version(void); // Initialize a parser with the given start and end pointers. @@ -57,20 +53,6 @@ YP_EXPORTED_FUNCTION void yp_parser_free(yp_parser_t *parser); // Parse the Ruby source associated with the given parser and return the tree. YP_EXPORTED_FUNCTION yp_node_t * yp_parse(yp_parser_t *parser); -// Deallocate a node and all of its children. -YP_EXPORTED_FUNCTION void yp_node_destroy(yp_parser_t *parser, struct yp_node *node); - -// This struct stores the information gathered by the yp_node_memsize function. -// It contains both the memory footprint and additionally metadata about the -// shape of the tree. -typedef struct { - size_t memsize; - size_t node_count; -} yp_memsize_t; - -// Calculates the memory footprint of a given node. -YP_EXPORTED_FUNCTION void yp_node_memsize(yp_node_t *node, yp_memsize_t *memsize); - // Pretty-prints the AST represented by the given node to the given buffer. YP_EXPORTED_FUNCTION void yp_prettyprint(yp_parser_t *parser, yp_node_t *node, yp_buffer_t *buffer); |