class Parser::Builders::Default

Default AST builder. Uses {AST::Node}s.

Attributes

emit_arg_inside_procarg0[RW]

AST compatibility attribute; causes a single non-mlhs block argument to be wrapped in s(:procarg0).

If set to false (the default), block arguments `|a|` are emitted as `s(:args, s(:procarg0, :a))`

If set to true, block arguments `|a|` are emitted as `s(:args, s(:procarg0, s(:arg, :a))`

@return [Boolean]

emit_encoding[RW]

AST compatibility attribute; locations of `__ENCODING__` are not the same as locations of `Encoding::UTF_8` causing problems during rewriting, all new code should set this attribute to true.

If set to false (the default), `__ENCODING__` is emitted as ` s(:const, s(:const, nil, :Encoding), :UTF_8)`.

If set to true, `__ENCODING__` is emitted as `s(:__ENCODING__)`.

@return [Boolean]

emit_forward_arg[RW]

AST compatibility attribute; arguments forwarding initially didn't have support for leading arguments (i.e. `def m(a, …); end` was a syntax error). However, Ruby 3.0 added support for any number of arguments in front of the `…`.

If set to false (the default):

1. `def m(...) end` is emitted as
   s(:def, :m, s(:forward_args), nil)
2. `def m(a, b, ...) end` is emitted as
   s(:def, :m,
     s(:args, s(:arg, :a), s(:arg, :b), s(:forward_arg)))

If set to true it uses a single format:

1. `def m(...) end` is emitted as
   s(:def, :m, s(:args, s(:forward_arg)))
2. `def m(a, b, ...) end` is emitted as
   s(:def, :m, s(:args, s(:arg, :a), s(:arg, :b), s(:forward_arg)))

It does't matter that much on 2.7 (because there can't be any leading arguments), but on 3.0 it should be better enabled to use a single AST format.

@return [Boolean]

emit_index[RW]

AST compatibility attribute; indexed assignment, `x[] = 1`, is not semantically equivalent to calling the method directly, `x.[]=(1)`. Specifically, in the former case, the expression's value is always 1, and in the latter case, the expression's value is the return value of the `[]=` method.

If set to false (the default), `self` is emitted as `s(:send, s(:self), :[], s(:int, 1))`, and `self = 2` is emitted as `s(:send, s(:self), :[]=, s(:int, 1), s(:int, 2))`.

If set to true, `self` is emitted as `s(:index, s(:self), s(:int, 1))`, and `self = 2` is emitted as `s(:indexasgn, s(:self), s(:int, 1), s(:int, 2))`.

@return [Boolean]

emit_kwargs[RW]

AST compatibility attribute; Starting from Ruby 2.7 keyword arguments of method calls that are passed explicitly as a hash (i.e. with curly braces) are treated as positional arguments and Ruby 2.7 emits a warning on such method call. Ruby 3.0 given an ArgumentError.

If set to false (the default) the last hash argument is emitted as `hash`:

“` (send nil :foo

(hash
  (pair
    (sym :bar)
    (int 42))))

“`

If set to true it is emitted as `kwargs`:

“` (send nil :foo

(kwargs
  (pair
    (sym :bar)
    (int 42))))

“`

Note that `kwargs` node is just a replacement for `hash` argument, so if there's are multiple arguments (or a `kwsplat`) all of them are wrapped into `kwargs` instead of `hash`:

“` (send nil :foo

(kwargs
  (pair
    (sym :a)
    (int 42))
  (kwsplat
    (send nil :b))
  (pair
    (sym :c)
    (int 10))))

“`

emit_lambda[RW]

AST compatibility attribute; since `-> {}` is not semantically equivalent to `lambda {}`, all new code should set this attribute to true.

If set to false (the default), `-> {}` is emitted as `s(:block, s(:send, nil, :lambda), s(:args), nil)`.

If set to true, `-> {}` is emitted as `s(:block, s(:lambda), s(:args), nil)`.

@return [Boolean]

emit_match_pattern[RW]

AST compatibility attribute; Starting from 3.0 Ruby returns true/false from single-line pattern matching with `in` keyword.

Before 3.0 there was an exception if given value doesn't match pattern.

NOTE: This attribute affects only Ruby 2.7 grammar. 3.0 grammar always emits `match_pattern`/`match_pattern_p`

If compatibility attribute set to false `foo in bar` is emitted as `in_match`:

“` (in-match

(send nil :foo)
(match-var :bar))

“`

If set to true it's emitted as `match_pattern_p`: “` (match-pattern-p

(send nil :foo)
(match-var :bar))

“`

emit_procarg0[RW]

AST compatibility attribute; block arguments of `m { |a| }` are not semantically equivalent to block arguments of `m { |a,| }` or `m { |a, b| }`, all new code should set this attribute to true.

If set to false (the default), arguments of `m { |a| }` are emitted as `s(:args, s(:arg, :a))`.

If set to true, arguments of `m { |a| }` are emitted as `s(:args, s(:procarg0, :a)).

@return [Boolean]

emit_file_line_as_literals[RW]

If set to true (the default), `__FILE__` and `__LINE__` are transformed to literal nodes. For example, `s(:str, “lib/foo.rb”)` and `s(:int, 10)`.

If set to false, `__FILE__` and `__LINE__` are emitted as-is, i.e. as `s(:__FILE__)` and `s(:__LINE__)` nodes.

Source maps are identical in both cases.

@return [Boolean]

parser[RW]

@api private

Public Class Methods

modernize() click to toggle source

@api private

# File lib/parser/builders/default.rb, line 211
def modernize
  @emit_lambda = true
  @emit_procarg0 = true
  @emit_encoding = true
  @emit_index = true
  @emit_arg_inside_procarg0 = true
  @emit_forward_arg = true
  @emit_kwargs = true
  @emit_match_pattern = true
end
new() click to toggle source

Initializes attributes:

* `emit_file_line_as_literals`: `true`
# File lib/parser/builders/default.rb, line 243
def initialize
  @emit_file_line_as_literals = true
end

Public Instance Methods

__ENCODING__(__ENCODING__t) click to toggle source
# File lib/parser/builders/default.rb, line 696
def __ENCODING__(__ENCODING__t)
  n0(:__ENCODING__,
    token_map(__ENCODING__t))
end
__FILE__(__FILE__t) click to toggle source
# File lib/parser/builders/default.rb, line 348
def __FILE__(__FILE__t)
  n0(:__FILE__,
    token_map(__FILE__t))
end
__LINE__(__LINE__t) click to toggle source
# File lib/parser/builders/default.rb, line 312
def __LINE__(__LINE__t)
  n0(:__LINE__,
    token_map(__LINE__t))
end
accessible(node) click to toggle source
# File lib/parser/builders/default.rb, line 622
def accessible(node)
  case node.type
  when :__FILE__
    if @emit_file_line_as_literals
      n(:str, [ node.loc.expression.source_buffer.name ],
        node.loc.dup)
    else
      node
    end

  when :__LINE__
    if @emit_file_line_as_literals
      n(:int, [ node.loc.expression.line ],
        node.loc.dup)
    else
      node
    end

  when :__ENCODING__
    if !self.class.emit_encoding
      n(:const, [ n(:const, [ nil, :Encoding], nil), :UTF_8 ],
        node.loc.dup)
    else
      node
    end

  when :ident
    name, = *node

    if %w[? !].any? { |c| name.to_s.end_with?(c) }
      diagnostic :error, :invalid_id_to_get,
                 { :identifier => name.to_s }, node.loc.expression
    end

    # Numbered parameters are not declared anywhere,
    # so they take precedence over method calls in numblock contexts
    if @parser.version >= 27 && @parser.try_declare_numparam(node)
      return node.updated(:lvar)
    end

    unless @parser.static_env.declared?(name)
      return n(:send, [ nil, name ],
        var_send_map(node))
    end

    if name.to_s == parser.current_arg_stack.top
      diagnostic :error, :circular_argument_reference,
                 { :var_name => name.to_s }, node.loc.expression
    end

    node.updated(:lvar)

  else
    node
  end
end
alias(alias_t, to, from) click to toggle source
# File lib/parser/builders/default.rb, line 871
def alias(alias_t, to, from)
  n(:alias, [ to, from ],
    keyword_map(alias_t, nil, [to, from], nil))
end
arg(name_t) click to toggle source
# File lib/parser/builders/default.rb, line 910
def arg(name_t)
  check_reserved_for_numparam(value(name_t), loc(name_t))

  n(:arg, [ value(name_t).to_sym ],
    variable_map(name_t))
end
arg_expr(expr) click to toggle source

Ruby 1.8 block arguments

# File lib/parser/builders/default.rb, line 1000
def arg_expr(expr)
  if expr.type == :lvasgn
    expr.updated(:arg)
  else
    n(:arg_expr, [ expr ],
      expr.loc.dup)
  end
end
args(begin_t, args, end_t, check_args=true) click to toggle source

Formal arguments

# File lib/parser/builders/default.rb, line 880
def args(begin_t, args, end_t, check_args=true)
  args = check_duplicate_args(args) if check_args
  validate_no_forward_arg_after_restarg(args)

  map = collection_map(begin_t, args, end_t)
  if !self.class.emit_forward_arg && args.length == 1 && args[0].type == :forward_arg
    n(:forward_args, [], map)
  else
    n(:args, args, map)
  end
end
array(begin_t, elements, end_t) click to toggle source

Arrays

# File lib/parser/builders/default.rb, line 440
def array(begin_t, elements, end_t)
  n(:array, elements,
    collection_map(begin_t, elements, end_t))
end
array_pattern(lbrack_t, elements, rbrack_t) click to toggle source
# File lib/parser/builders/default.rb, line 1575
def array_pattern(lbrack_t, elements, rbrack_t)
  return n(:array_pattern, nil, collection_map(lbrack_t, [], rbrack_t)) if elements.nil?

  trailing_comma = false

  node_elements = elements.map do |element|
    if element.type == :match_with_trailing_comma
      trailing_comma = true
      element.children.first
    else
      trailing_comma = false
      element
    end
  end

  node_type = trailing_comma ? :array_pattern_with_tail : :array_pattern

  n(node_type, node_elements,
    collection_map(lbrack_t, elements, rbrack_t))
end
assign(lhs, eql_t, rhs) click to toggle source
# File lib/parser/builders/default.rb, line 760
def assign(lhs, eql_t, rhs)
  (lhs << rhs).updated(nil, nil,
    :location => lhs.loc.
      with_operator(loc(eql_t)).
      with_expression(join_exprs(lhs, rhs)))
end
assignable(node) click to toggle source

Assignment

# File lib/parser/builders/default.rb, line 705
def assignable(node)
  case node.type
  when :cvar
    node.updated(:cvasgn)

  when :ivar
    node.updated(:ivasgn)

  when :gvar
    node.updated(:gvasgn)

  when :const
    if @parser.context.in_def
      diagnostic :error, :dynamic_const, nil, node.loc.expression
    end

    node.updated(:casgn)

  when :ident
    name, = *node

    var_name = node.children[0].to_s
    name_loc = node.loc.expression

    check_assignment_to_numparam(var_name, name_loc)
    check_reserved_for_numparam(var_name, name_loc)

    @parser.static_env.declare(name)

    node.updated(:lvasgn)

  when :match_var
    name, = *node

    var_name = node.children[0].to_s
    name_loc = node.loc.expression

    check_assignment_to_numparam(var_name, name_loc)
    check_reserved_for_numparam(var_name, name_loc)

    node

  when :nil, :self, :true, :false,
       :__FILE__, :__LINE__, :__ENCODING__
    diagnostic :error, :invalid_assignment, nil, node.loc.expression

  when :back_ref, :nth_ref
    diagnostic :error, :backref_assignment, nil, node.loc.expression
  end
end
associate(begin_t, pairs, end_t) click to toggle source
# File lib/parser/builders/default.rb, line 540
def associate(begin_t, pairs, end_t)
  0.upto(pairs.length - 1) do |i|
    (i + 1).upto(pairs.length - 1) do |j|
      key1, = *pairs[i]
      key2, = *pairs[j]

      do_warn = false

      # keys have to be simple nodes, MRI ignores equal composite keys like
      # `{ a(1) => 1, a(1) => 1 }`
      case key1.type
      when :sym, :str, :int, :float
        if key1 == key2
          do_warn = true
        end
      when :rational, :complex, :regexp
        if @parser.version >= 31 && key1 == key2
          do_warn = true
        end
      end

      if do_warn
        diagnostic :warning, :duplicate_hash_key, nil, key2.loc.expression
      end
    end
  end

  n(:hash, [ *pairs ],
    collection_map(begin_t, pairs, end_t))
end
attr_asgn(receiver, dot_t, selector_t) click to toggle source
# File lib/parser/builders/default.rb, line 1156
def attr_asgn(receiver, dot_t, selector_t)
  method_name = (value(selector_t) + '=').to_sym
  type = call_type_for_dot(dot_t)

  # Incomplete method call.
  n(type, [ receiver, method_name ],
    send_map(receiver, dot_t, selector_t))
end
back_ref(token) click to toggle source
# File lib/parser/builders/default.rb, line 612
def back_ref(token)
  n(:back_ref, [ value(token).to_sym ],
    token_map(token))
end
begin(begin_t, body, end_t) click to toggle source
# File lib/parser/builders/default.rb, line 1420
def begin(begin_t, body, end_t)
  if body.nil?
    # A nil expression: `()'.
    n0(:begin,
      collection_map(begin_t, nil, end_t))
  elsif body.type == :mlhs  ||
       (body.type == :begin &&
        body.loc.begin.nil? && body.loc.end.nil?)
    # Synthesized (begin) from compstmt "a; b" or (mlhs)
    # from multi_lhs "(a, b) = *foo".
    n(body.type, body.children,
      collection_map(begin_t, body.children, end_t))
  else
    n(:begin, [ body ],
      collection_map(begin_t, [ body ], end_t))
  end
end
begin_body(compound_stmt, rescue_bodies=[], else_t=nil, else_=nil, ensure_t=nil, ensure_=nil) click to toggle source
# File lib/parser/builders/default.rb, line 1362
def begin_body(compound_stmt, rescue_bodies=[],
               else_t=nil,    else_=nil,
               ensure_t=nil,  ensure_=nil)
  if rescue_bodies.any?
    if else_t
      compound_stmt =
        n(:rescue,
          [ compound_stmt, *(rescue_bodies + [ else_ ]) ],
          eh_keyword_map(compound_stmt, nil, rescue_bodies, else_t, else_))
    else
      compound_stmt =
        n(:rescue,
          [ compound_stmt, *(rescue_bodies + [ nil ]) ],
          eh_keyword_map(compound_stmt, nil, rescue_bodies, nil, nil))
    end
  elsif else_t
    statements = []
    if !compound_stmt.nil?
      if compound_stmt.type == :begin
        statements += compound_stmt.children
      else
        statements.push(compound_stmt)
      end
    end
    statements.push(
      n(:begin, [ else_ ],
        collection_map(else_t, [ else_ ], nil)))
    compound_stmt =
      n(:begin, statements,
        collection_map(nil, statements, nil))
  end

  if ensure_t
    compound_stmt =
      n(:ensure,
        [ compound_stmt, ensure_ ],
        eh_keyword_map(compound_stmt, ensure_t, [ ensure_ ], nil, nil))
  end

  compound_stmt
end
begin_keyword(begin_t, body, end_t) click to toggle source
# File lib/parser/builders/default.rb, line 1438
def begin_keyword(begin_t, body, end_t)
  if body.nil?
    # A nil expression: `begin end'.
    n0(:kwbegin,
      collection_map(begin_t, nil, end_t))
  elsif (body.type == :begin &&
         body.loc.begin.nil? && body.loc.end.nil?)
    # Synthesized (begin) from compstmt "a; b".
    n(:kwbegin, body.children,
      collection_map(begin_t, body.children, end_t))
  else
    n(:kwbegin, [ body ],
      collection_map(begin_t, [ body ], end_t))
  end
end
binary_op(receiver, operator_t, arg) click to toggle source
# File lib/parser/builders/default.rb, line 1190
def binary_op(receiver, operator_t, arg)
  source_map = send_binary_op_map(receiver, operator_t, arg)

  if @parser.version == 18
    operator = value(operator_t)

    if operator == '!='
      method_call = n(:send, [ receiver, :==, arg ], source_map)
    elsif operator == '!~'
      method_call = n(:send, [ receiver, :=~, arg ], source_map)
    end

    if %w(!= !~).include?(operator)
      return n(:not, [ method_call ],
               expr_map(source_map.expression))
    end
  end

  n(:send, [ receiver, value(operator_t).to_sym, arg ],
    source_map)
end
block(method_call, begin_t, args, body, end_t) click to toggle source
# File lib/parser/builders/default.rb, line 1107
def block(method_call, begin_t, args, body, end_t)
  _receiver, _selector, *call_args = *method_call

  if method_call.type == :yield
    diagnostic :error, :block_given_to_yield, nil, method_call.loc.keyword, [loc(begin_t)]
  end

  last_arg = call_args.last
  if last_arg && (last_arg.type == :block_pass || last_arg.type == :forwarded_args)
    diagnostic :error, :block_and_blockarg, nil, last_arg.loc.expression, [loc(begin_t)]
  end

  if args.type == :numargs
    block_type = :numblock
    args = args.children[0]
  else
    block_type = :block
  end

  if [:send, :csend, :index, :super, :zsuper, :lambda].include?(method_call.type)
    n(block_type, [ method_call, args, body ],
      block_map(method_call.loc.expression, begin_t, end_t))
  else
    # Code like "return foo 1 do end" is reduced in a weird sequence.
    # Here, method_call is actually (return).
    actual_send, = *method_call
    block =
      n(block_type, [ actual_send, args, body ],
        block_map(actual_send.loc.expression, begin_t, end_t))

    n(method_call.type, [ block ],
      method_call.loc.with_expression(join_exprs(method_call, block)))
  end
end
block_pass(amper_t, arg) click to toggle source
# File lib/parser/builders/default.rb, line 1142
def block_pass(amper_t, arg)
  n(:block_pass, [ arg ],
    unary_op_map(amper_t, arg))
end
blockarg(amper_t, name_t) click to toggle source
# File lib/parser/builders/default.rb, line 975
def blockarg(amper_t, name_t)
  if !name_t.nil?
    check_reserved_for_numparam(value(name_t), loc(name_t))
  end

  arg_name = name_t ? value(name_t).to_sym : nil
  n(:blockarg, [ arg_name ],
    arg_prefix_map(amper_t, name_t))
end
blockarg_expr(amper_t, expr) click to toggle source
# File lib/parser/builders/default.rb, line 1020
def blockarg_expr(amper_t, expr)
  if expr.type == :lvasgn
    expr.updated(:blockarg)
  else
    n(:blockarg_expr, [ expr ],
      expr.loc.dup)
  end
end
call_lambda(lambda_t) click to toggle source
# File lib/parser/builders/default.rb, line 1098
def call_lambda(lambda_t)
  if self.class.emit_lambda
    n0(:lambda, expr_map(loc(lambda_t)))
  else
    n(:send, [ nil, :lambda ],
      send_map(nil, nil, lambda_t))
  end
end
call_method(receiver, dot_t, selector_t, lparen_t=nil, args=[], rparen_t=nil) click to toggle source
# File lib/parser/builders/default.rb, line 1081
def call_method(receiver, dot_t, selector_t,
                lparen_t=nil, args=[], rparen_t=nil)
  type = call_type_for_dot(dot_t)

  if self.class.emit_kwargs
    rewrite_hash_args_to_kwargs(args)
  end

  if selector_t.nil?
    n(type, [ receiver, :call, *args ],
      send_map(receiver, dot_t, nil, lparen_t, args, rparen_t))
  else
    n(type, [ receiver, value(selector_t).to_sym, *args ],
      send_map(receiver, dot_t, selector_t, lparen_t, args, rparen_t))
  end
end
call_type_for_dot(dot_t) click to toggle source

Method calls

# File lib/parser/builders/default.rb, line 1061
def call_type_for_dot(dot_t)
  if !dot_t.nil? && value(dot_t) == :anddot
    :csend
  else
    # This case is a bit tricky. ruby23.y returns the token tDOT with
    # the value :dot, and the token :tANDDOT with the value :anddot.
    #
    # But, ruby{18..22}.y (which unconditionally expect tDOT) just
    # return "." there, since they are to be kept close to the corresponding
    # Ruby MRI grammars.
    #
    # Thankfully, we don't have to care.
    :send
  end
end
case(case_t, expr, when_bodies, else_t, else_body, end_t) click to toggle source
# File lib/parser/builders/default.rb, line 1295
def case(case_t, expr, when_bodies, else_t, else_body, end_t)
  n(:case, [ expr, *(when_bodies << else_body)],
    condition_map(case_t, expr, nil, nil, else_t, else_body, end_t))
end
case_match(case_t, expr, in_bodies, else_t, else_body, end_t) click to toggle source

PATTERN MATCHING

# File lib/parser/builders/default.rb, line 1458
def case_match(case_t, expr, in_bodies, else_t, else_body, end_t)
  else_body = n(:empty_else, nil, token_map(else_t)) if else_t && !else_body
  n(:case_match, [ expr, *(in_bodies << else_body)],
    condition_map(case_t, expr, nil, nil, else_t, else_body, end_t))
end
character(char_t) click to toggle source
# File lib/parser/builders/default.rb, line 343
def character(char_t)
  n(:str, [ string_value(char_t) ],
    prefix_string_map(char_t))
end
complex(complex_t) click to toggle source
# File lib/parser/builders/default.rb, line 284
def complex(complex_t)
  numeric(:complex, complex_t)
end
compstmt(statements) click to toggle source

Expression grouping

# File lib/parser/builders/default.rb, line 1408
def compstmt(statements)
  case
  when statements.none?
    nil
  when statements.one?
    statements.first
  else
    n(:begin, statements,
      collection_map(nil, statements, nil))
  end
end
condition(cond_t, cond, then_t, if_true, else_t, if_false, end_t) click to toggle source

Conditionals

# File lib/parser/builders/default.rb, line 1271
def condition(cond_t, cond, then_t,
              if_true, else_t, if_false, end_t)
  n(:if, [ check_condition(cond), if_true, if_false ],
    condition_map(cond_t, cond, then_t, if_true, else_t, if_false, end_t))
end
condition_mod(if_true, if_false, cond_t, cond) click to toggle source
# File lib/parser/builders/default.rb, line 1277
def condition_mod(if_true, if_false, cond_t, cond)
  n(:if, [ check_condition(cond), if_true, if_false ],
    keyword_mod_map(if_true || if_false, cond_t, cond))
end
const(name_t) click to toggle source
# File lib/parser/builders/default.rb, line 679
def const(name_t)
  n(:const, [ nil, value(name_t).to_sym ],
    constant_map(nil, nil, name_t))
end
const_fetch(scope, t_colon2, name_t) click to toggle source
# File lib/parser/builders/default.rb, line 691
def const_fetch(scope, t_colon2, name_t)
  n(:const, [ scope, value(name_t).to_sym ],
    constant_map(scope, t_colon2, name_t))
end
const_global(t_colon3, name_t) click to toggle source
# File lib/parser/builders/default.rb, line 684
def const_global(t_colon3, name_t)
  cbase = n0(:cbase, token_map(t_colon3))

  n(:const, [ cbase, value(name_t).to_sym ],
    constant_map(cbase, t_colon3, name_t))
end
const_op_assignable(node) click to toggle source
# File lib/parser/builders/default.rb, line 756
def const_op_assignable(node)
  node.updated(:casgn)
end
const_pattern(const, ldelim_t, pattern, rdelim_t) click to toggle source
# File lib/parser/builders/default.rb, line 1605
def const_pattern(const, ldelim_t, pattern, rdelim_t)
  n(:const_pattern, [const, pattern],
    Source::Map::Collection.new(
      loc(ldelim_t), loc(rdelim_t),
      const.loc.expression.join(loc(rdelim_t))
    )
  )
end
cvar(token) click to toggle source
# File lib/parser/builders/default.rb, line 607
def cvar(token)
  n(:cvar, [ value(token).to_sym ],
    variable_map(token))
end
dedent_string(node, dedent_level) click to toggle source

Indented (interpolated, noninterpolated, executable) strings

# File lib/parser/builders/default.rb, line 388
def dedent_string(node, dedent_level)
  if !dedent_level.nil?
    dedenter = Lexer::Dedenter.new(dedent_level)

    case node.type
    when :str
      str = node.children.first
      dedenter.dedent(str)
    when :dstr, :xstr
      children = node.children.map do |str_node|
        if str_node.type == :str
          str = str_node.children.first
          dedenter.dedent(str)
          next nil if str.empty?
        else
          dedenter.interrupt
        end
        str_node
      end

      node = node.updated(nil, children.compact)
    end
  end

  node
end
def_class(class_t, name, lt_t, superclass, body, end_t) click to toggle source

Class and module definition

# File lib/parser/builders/default.rb, line 807
def def_class(class_t, name,
              lt_t, superclass,
              body, end_t)
  n(:class, [ name, superclass, body ],
    module_definition_map(class_t, name, lt_t, end_t))
end
def_endless_method(def_t, name_t, args, assignment_t, body) click to toggle source
# File lib/parser/builders/default.rb, line 838
def def_endless_method(def_t, name_t, args,
                       assignment_t, body)
  check_reserved_for_numparam(value(name_t), loc(name_t))

  n(:def, [ value(name_t).to_sym, args, body ],
    endless_definition_map(def_t, nil, name_t, assignment_t, body))
end
def_endless_singleton(def_t, definee, dot_t, name_t, args, assignment_t, body) click to toggle source
# File lib/parser/builders/default.rb, line 856
def def_endless_singleton(def_t, definee, dot_t,
                          name_t, args,
                          assignment_t, body)
  validate_definee(definee)
  check_reserved_for_numparam(value(name_t), loc(name_t))

  n(:defs, [ definee, value(name_t).to_sym, args, body ],
    endless_definition_map(def_t, dot_t, name_t, assignment_t, body))
end
def_method(def_t, name_t, args, body, end_t) click to toggle source

Method (un)definition

# File lib/parser/builders/default.rb, line 830
def def_method(def_t, name_t, args,
               body, end_t)
  check_reserved_for_numparam(value(name_t), loc(name_t))

  n(:def, [ value(name_t).to_sym, args, body ],
    definition_map(def_t, nil, name_t, end_t))
end
def_module(module_t, name, body, end_t) click to toggle source
# File lib/parser/builders/default.rb, line 820
def def_module(module_t, name,
               body, end_t)
  n(:module, [ name, body ],
    module_definition_map(module_t, name, nil, end_t))
end
def_sclass(class_t, lshft_t, expr, body, end_t) click to toggle source
# File lib/parser/builders/default.rb, line 814
def def_sclass(class_t, lshft_t, expr,
               body, end_t)
  n(:sclass, [ expr, body ],
    module_definition_map(class_t, nil, lshft_t, end_t))
end
def_singleton(def_t, definee, dot_t, name_t, args, body, end_t) click to toggle source
# File lib/parser/builders/default.rb, line 846
def def_singleton(def_t, definee, dot_t,
                  name_t, args,
                  body, end_t)
  validate_definee(definee)
  check_reserved_for_numparam(value(name_t), loc(name_t))

  n(:defs, [ definee, value(name_t).to_sym, args, body ],
    definition_map(def_t, dot_t, name_t, end_t))
end
false(false_t) click to toggle source
# File lib/parser/builders/default.rb, line 265
def false(false_t)
  n0(:false,
    token_map(false_t))
end
find_pattern(lbrack_t, elements, rbrack_t) click to toggle source
# File lib/parser/builders/default.rb, line 1596
def find_pattern(lbrack_t, elements, rbrack_t)
  n(:find_pattern, elements,
    collection_map(lbrack_t, elements, rbrack_t))
end
float(float_t) click to toggle source
# File lib/parser/builders/default.rb, line 276
def float(float_t)
  numeric(:float, float_t)
end
for(for_t, iterator, in_t, iteratee, do_t, body, end_t) click to toggle source
# File lib/parser/builders/default.rb, line 1316
def for(for_t, iterator, in_t, iteratee,
        do_t, body, end_t)
  n(:for, [ iterator, iteratee, body ],
    for_map(for_t, in_t, do_t, end_t))
end
forward_arg(dots_t) click to toggle source
# File lib/parser/builders/default.rb, line 906
def forward_arg(dots_t)
  n(:forward_arg, [], token_map(dots_t))
end
forward_only_args(begin_t, dots_t, end_t) click to toggle source
# File lib/parser/builders/default.rb, line 896
def forward_only_args(begin_t, dots_t, end_t)
  if self.class.emit_forward_arg
    arg = forward_arg(dots_t)
    n(:args, [ arg ],
      collection_map(begin_t, [ arg ], end_t))
  else
    n(:forward_args, [], collection_map(begin_t, token_map(dots_t), end_t))
  end
end
forwarded_args(dots_t) click to toggle source
# File lib/parser/builders/default.rb, line 1077
def forwarded_args(dots_t)
  n(:forwarded_args, [], token_map(dots_t))
end
gvar(token) click to toggle source
# File lib/parser/builders/default.rb, line 602
def gvar(token)
  n(:gvar, [ value(token).to_sym ],
    variable_map(token))
end
hash_pattern(lbrace_t, kwargs, rbrace_t) click to toggle source
# File lib/parser/builders/default.rb, line 1569
def hash_pattern(lbrace_t, kwargs, rbrace_t)
  args = check_duplicate_args(kwargs)
  n(:hash_pattern, args,
    collection_map(lbrace_t, args, rbrace_t))
end
ident(token) click to toggle source
# File lib/parser/builders/default.rb, line 592
def ident(token)
  n(:ident, [ value(token).to_sym ],
    variable_map(token))
end
if_guard(if_t, if_body) click to toggle source
# File lib/parser/builders/default.rb, line 1485
def if_guard(if_t, if_body)
  n(:if_guard, [if_body], guard_map(if_t, if_body))
end
in_match(lhs, in_t, rhs) click to toggle source
# File lib/parser/builders/default.rb, line 1464
def in_match(lhs, in_t, rhs)
  n(:in_match, [lhs, rhs],
    binary_op_map(lhs, in_t, rhs))
end
in_pattern(in_t, pattern, guard, then_t, body) click to toggle source
# File lib/parser/builders/default.rb, line 1479
def in_pattern(in_t, pattern, guard, then_t, body)
  children = [pattern, guard, body]
  n(:in_pattern, children,
    keyword_map(in_t, then_t, children.compact, nil))
end
index(receiver, lbrack_t, indexes, rbrack_t) click to toggle source
# File lib/parser/builders/default.rb, line 1165
def index(receiver, lbrack_t, indexes, rbrack_t)
  if self.class.emit_kwargs
    rewrite_hash_args_to_kwargs(indexes)
  end

  if self.class.emit_index
    n(:index, [ receiver, *indexes ],
      index_map(receiver, lbrack_t, rbrack_t))
  else
    n(:send, [ receiver, :[], *indexes ],
      send_index_map(receiver, lbrack_t, rbrack_t))
  end
end
index_asgn(receiver, lbrack_t, indexes, rbrack_t) click to toggle source
# File lib/parser/builders/default.rb, line 1179
def index_asgn(receiver, lbrack_t, indexes, rbrack_t)
  if self.class.emit_index
    n(:indexasgn, [ receiver, *indexes ],
      index_map(receiver, lbrack_t, rbrack_t))
  else
    # Incomplete method call.
    n(:send, [ receiver, :[]=, *indexes ],
      send_index_map(receiver, lbrack_t, rbrack_t))
  end
end
integer(integer_t) click to toggle source

Numerics

# File lib/parser/builders/default.rb, line 272
def integer(integer_t)
  numeric(:int, integer_t)
end
ivar(token) click to toggle source
# File lib/parser/builders/default.rb, line 597
def ivar(token)
  n(:ivar, [ value(token).to_sym ],
    variable_map(token))
end
keyword_cmd(type, keyword_t, lparen_t=nil, args=[], rparen_t=nil) click to toggle source

Keywords

# File lib/parser/builders/default.rb, line 1324
def keyword_cmd(type, keyword_t, lparen_t=nil, args=[], rparen_t=nil)
  if type == :yield && args.count > 0
    last_arg = args.last
    if last_arg.type == :block_pass
      diagnostic :error, :block_given_to_yield, nil, loc(keyword_t), [last_arg.loc.expression]
    end
  end

  if %i[yield super].include?(type) && self.class.emit_kwargs
    rewrite_hash_args_to_kwargs(args)
  end

  n(type, args,
    keyword_map(keyword_t, lparen_t, args, rparen_t))
end
kwarg(name_t) click to toggle source
# File lib/parser/builders/default.rb, line 937
def kwarg(name_t)
  check_reserved_for_numparam(value(name_t), loc(name_t))

  n(:kwarg, [ value(name_t).to_sym ],
    kwarg_map(name_t))
end
kwnilarg(dstar_t, nil_t) click to toggle source
# File lib/parser/builders/default.rb, line 963
def kwnilarg(dstar_t, nil_t)
  n0(:kwnilarg,
    arg_prefix_map(dstar_t, nil_t))
end
kwoptarg(name_t, value) click to toggle source
# File lib/parser/builders/default.rb, line 944
def kwoptarg(name_t, value)
  check_reserved_for_numparam(value(name_t), loc(name_t))

  n(:kwoptarg, [ value(name_t).to_sym, value ],
    kwarg_map(name_t, value))
end
kwrestarg(dstar_t, name_t=nil) click to toggle source
# File lib/parser/builders/default.rb, line 951
def kwrestarg(dstar_t, name_t=nil)
  if name_t
    check_reserved_for_numparam(value(name_t), loc(name_t))

    n(:kwrestarg, [ value(name_t).to_sym ],
      arg_prefix_map(dstar_t, name_t))
  else
    n0(:kwrestarg,
      arg_prefix_map(dstar_t))
  end
end
kwsplat(dstar_t, arg) click to toggle source
# File lib/parser/builders/default.rb, line 535
def kwsplat(dstar_t, arg)
  n(:kwsplat, [ arg ],
    unary_op_map(dstar_t, arg))
end
logical_op(type, lhs, op_t, rhs) click to toggle source

Logical operations: and, or

# File lib/parser/builders/default.rb, line 1264
def logical_op(type, lhs, op_t, rhs)
  n(type, [ lhs, rhs ],
    binary_op_map(lhs, op_t, rhs))
end
loop(type, keyword_t, cond, do_t, body, end_t) click to toggle source

Loops

# File lib/parser/builders/default.rb, line 1302
def loop(type, keyword_t, cond, do_t, body, end_t)
  n(type, [ check_condition(cond), body ],
    keyword_map(keyword_t, do_t, nil, end_t))
end
loop_mod(type, body, keyword_t, cond) click to toggle source
# File lib/parser/builders/default.rb, line 1307
def loop_mod(type, body, keyword_t, cond)
  if body.type == :kwbegin
    type = :"#{type}_post"
  end

  n(type, [ check_condition(cond), body ],
    keyword_mod_map(body, keyword_t, cond))
end
match_alt(left, pipe_t, right) click to toggle source
# File lib/parser/builders/default.rb, line 1619
def match_alt(left, pipe_t, right)
  source_map = binary_op_map(left, pipe_t, right)

  n(:match_alt, [ left, right ],
    source_map)
end
match_as(value, assoc_t, as) click to toggle source
# File lib/parser/builders/default.rb, line 1626
def match_as(value, assoc_t, as)
  source_map = binary_op_map(value, assoc_t, as)

  n(:match_as, [ value, as ],
    source_map)
end
match_hash_var(name_t) click to toggle source
# File lib/parser/builders/default.rb, line 1505
def match_hash_var(name_t)
  name = value(name_t).to_sym

  expr_l = loc(name_t)
  name_l = expr_l.adjust(end_pos: -1)

  check_lvar_name(name, name_l)
  check_duplicate_pattern_variable(name, name_l)
  @parser.static_env.declare(name)

  n(:match_var, [ name ],
    Source::Map::Variable.new(name_l, expr_l))
end
match_hash_var_from_str(begin_t, strings, end_t) click to toggle source
# File lib/parser/builders/default.rb, line 1519
def match_hash_var_from_str(begin_t, strings, end_t)
  if strings.length > 1
    diagnostic :error, :pm_interp_in_var_name, nil, loc(begin_t).join(loc(end_t))
  end

  string = strings[0]

  case string.type
  when :str
    # MRI supports plain strings in hash pattern matching
    name, = *string
    name_l = string.loc.expression

    check_lvar_name(name, name_l)
    check_duplicate_pattern_variable(name, name_l)

    @parser.static_env.declare(name)

    if (begin_l = string.loc.begin)
      # exclude beginning of the string from the location of the variable
      name_l = name_l.adjust(begin_pos: begin_l.length)
    end

    if (end_l = string.loc.end)
      # exclude end of the string from the location of the variable
      name_l = name_l.adjust(end_pos: -end_l.length)
    end

    expr_l = loc(begin_t).join(string.loc.expression).join(loc(end_t))
    n(:match_var, [ name.to_sym ],
      Source::Map::Variable.new(name_l, expr_l))
  when :begin
    match_hash_var_from_str(begin_t, string.children, end_t)
  else
    # we only can get here if there is an interpolation, e.g., ``in "#{ a }":`
    diagnostic :error, :pm_interp_in_var_name, nil, loc(begin_t).join(loc(end_t))
  end
end
match_label(label_type, label) click to toggle source
# File lib/parser/builders/default.rb, line 1657
def match_label(label_type, label)
  if label_type == :label
    match_hash_var(label)
  else
    # quoted label like "label": value
    begin_t, strings, end_t = label
    match_hash_var_from_str(begin_t, strings, end_t)
  end
end
match_nil_pattern(dstar_t, nil_t) click to toggle source
# File lib/parser/builders/default.rb, line 1633
def match_nil_pattern(dstar_t, nil_t)
  n0(:match_nil_pattern,
    arg_prefix_map(dstar_t, nil_t))
end
match_op(receiver, match_t, arg) click to toggle source
# File lib/parser/builders/default.rb, line 1212
def match_op(receiver, match_t, arg)
  source_map = send_binary_op_map(receiver, match_t, arg)

  if (regexp = static_regexp_node(receiver))
    regexp.names.each do |name|
      @parser.static_env.declare(name)
    end

    n(:match_with_lvasgn, [ receiver, arg ],
      source_map)
  else
    n(:send, [ receiver, :=~, arg ],
      source_map)
  end
end
match_pair(label_type, label, value) click to toggle source
# File lib/parser/builders/default.rb, line 1638
def match_pair(label_type, label, value)
  if label_type == :label
    check_duplicate_pattern_key(label[0], label[1])
    pair_keyword(label, value)
  else
    begin_t, parts, end_t = label
    label_loc = loc(begin_t).join(loc(end_t))

    # quoted label like "label": value
    if (var_name = static_string(parts))
      check_duplicate_pattern_key(var_name, label_loc)
    else
      diagnostic :error, :pm_interp_in_var_name, nil, label_loc
    end

    pair_quoted(begin_t, parts, end_t, value)
  end
end
match_pattern(lhs, match_t, rhs) click to toggle source
# File lib/parser/builders/default.rb, line 1469
def match_pattern(lhs, match_t, rhs)
  n(:match_pattern, [lhs, rhs],
    binary_op_map(lhs, match_t, rhs))
end
match_pattern_p(lhs, match_t, rhs) click to toggle source
# File lib/parser/builders/default.rb, line 1474
def match_pattern_p(lhs, match_t, rhs)
  n(:match_pattern_p, [lhs, rhs],
    binary_op_map(lhs, match_t, rhs))
end
match_rest(star_t, name_t = nil) click to toggle source
# File lib/parser/builders/default.rb, line 1558
def match_rest(star_t, name_t = nil)
  if name_t.nil?
    n0(:match_rest,
      unary_op_map(star_t))
  else
    name = match_var(name_t)
    n(:match_rest, [ name ],
      unary_op_map(star_t, name))
  end
end
match_var(name_t) click to toggle source
# File lib/parser/builders/default.rb, line 1493
def match_var(name_t)
  name = value(name_t).to_sym
  name_l = loc(name_t)

  check_lvar_name(name, name_l)
  check_duplicate_pattern_variable(name, name_l)
  @parser.static_env.declare(name)

  n(:match_var, [ name ],
    variable_map(name_t))
end
match_with_trailing_comma(match, comma_t) click to toggle source
# File lib/parser/builders/default.rb, line 1601
def match_with_trailing_comma(match, comma_t)
  n(:match_with_trailing_comma, [ match ], expr_map(match.loc.expression.join(loc(comma_t))))
end
multi_assign(lhs, eql_t, rhs) click to toggle source
# File lib/parser/builders/default.rb, line 798
def multi_assign(lhs, eql_t, rhs)
  n(:masgn, [ lhs, rhs ],
    binary_op_map(lhs, eql_t, rhs))
end
multi_lhs(begin_t, items, end_t) click to toggle source
# File lib/parser/builders/default.rb, line 793
def multi_lhs(begin_t, items, end_t)
  n(:mlhs, [ *items ],
    collection_map(begin_t, items, end_t))
end
nil(nil_t) click to toggle source

Singletons

# File lib/parser/builders/default.rb, line 255
def nil(nil_t)
  n0(:nil,
    token_map(nil_t))
end
not_op(not_t, begin_t=nil, receiver=nil, end_t=nil) click to toggle source
# File lib/parser/builders/default.rb, line 1240
def not_op(not_t, begin_t=nil, receiver=nil, end_t=nil)
  if @parser.version == 18
    n(:not, [ check_condition(receiver) ],
      unary_op_map(not_t, receiver))
  else
    if receiver.nil?
      nil_node = n0(:begin, collection_map(begin_t, nil, end_t))

      n(:send, [
        nil_node, :'!'
      ], send_unary_op_map(not_t, nil_node))
    else
      n(:send, [ check_condition(receiver), :'!' ],
        send_map(nil, nil, not_t, begin_t, [receiver], end_t))
    end
  end
end
nth_ref(token) click to toggle source
# File lib/parser/builders/default.rb, line 617
def nth_ref(token)
  n(:nth_ref, [ value(token) ],
    token_map(token))
end
numargs(max_numparam) click to toggle source
# File lib/parser/builders/default.rb, line 892
def numargs(max_numparam)
  n(:numargs, [ max_numparam ], nil)
end
objc_kwarg(kwname_t, assoc_t, name_t) click to toggle source

MacRuby Objective-C arguments

# File lib/parser/builders/default.rb, line 1031
def objc_kwarg(kwname_t, assoc_t, name_t)
  kwname_l = loc(kwname_t)
  if assoc_t.nil? # a: b, not a => b
    kwname_l   = kwname_l.resize(kwname_l.size - 1)
    operator_l = kwname_l.end.resize(1)
  else
    operator_l = loc(assoc_t)
  end

  n(:objc_kwarg, [ value(kwname_t).to_sym, value(name_t).to_sym ],
    Source::Map::ObjcKwarg.new(kwname_l, operator_l, loc(name_t),
                               kwname_l.join(loc(name_t))))
end
objc_restarg(star_t, name=nil) click to toggle source
# File lib/parser/builders/default.rb, line 1045
def objc_restarg(star_t, name=nil)
  if name.nil?
    n0(:restarg, arg_prefix_map(star_t))
  elsif name.type == :arg # regular restarg
    name.updated(:restarg, nil,
      { :location => name.loc.with_operator(loc(star_t)) })
  else # restarg with objc_kwarg inside
    n(:objc_restarg, [ name ],
      unary_op_map(star_t, name))
  end
end
objc_varargs(pair, rest_of_varargs) click to toggle source
# File lib/parser/builders/default.rb, line 1147
def objc_varargs(pair, rest_of_varargs)
  value, first_vararg = *pair
  vararg_array = array(nil, [ first_vararg, *rest_of_varargs ], nil).
    updated(:objc_varargs)
  pair.updated(nil, [ value, vararg_array ],
    { :location => pair.loc.with_expression(
          pair.loc.expression.join(vararg_array.loc.expression)) })
end
op_assign(lhs, op_t, rhs) click to toggle source
# File lib/parser/builders/default.rb, line 767
def op_assign(lhs, op_t, rhs)
  case lhs.type
  when :gvasgn, :ivasgn, :lvasgn, :cvasgn, :casgn, :send, :csend, :index
    operator   = value(op_t)[0..-1].to_sym
    source_map = lhs.loc.
                    with_operator(loc(op_t)).
                    with_expression(join_exprs(lhs, rhs))

    if lhs.type  == :index
      lhs = lhs.updated(:indexasgn)
    end

    case operator
    when :'&&'
      n(:and_asgn, [ lhs, rhs ], source_map)
    when :'||'
      n(:or_asgn, [ lhs, rhs ], source_map)
    else
      n(:op_asgn, [ lhs, operator, rhs ], source_map)
    end

  when :back_ref, :nth_ref
    diagnostic :error, :backref_assignment, nil, lhs.loc.expression
  end
end
optarg(name_t, eql_t, value) click to toggle source
# File lib/parser/builders/default.rb, line 917
def optarg(name_t, eql_t, value)
  check_reserved_for_numparam(value(name_t), loc(name_t))

  n(:optarg, [ value(name_t).to_sym, value ],
    variable_map(name_t).
      with_operator(loc(eql_t)).
      with_expression(loc(name_t).join(value.loc.expression)))
end
pair(key, assoc_t, value) click to toggle source

Hashes

# File lib/parser/builders/default.rb, line 488
def pair(key, assoc_t, value)
  n(:pair, [ key, value ],
    binary_op_map(key, assoc_t, value))
end
pair_keyword(key_t, value) click to toggle source
# File lib/parser/builders/default.rb, line 505
def pair_keyword(key_t, value)
  key_map, pair_map = pair_keyword_map(key_t, value)

  key = n(:sym, [ value(key_t).to_sym ], key_map)

  n(:pair, [ key, value ], pair_map)
end
pair_label(key_t) click to toggle source
# File lib/parser/builders/default.rb, line 521
def pair_label(key_t)
  key_l = loc(key_t)
  value_l = key_l.adjust(end_pos: -1)

  label = value(key_t)
  value =
    if label =~ /\A[[:lower:]]/
      n(:ident, [ label.to_sym ], Source::Map::Variable.new(value_l))
    else
      n(:const, [ nil, label.to_sym ], Source::Map::Constant.new(nil, value_l, value_l))
    end
  pair_keyword(key_t, accessible(value))
end
pair_list_18(list) click to toggle source
# File lib/parser/builders/default.rb, line 493
def pair_list_18(list)
  if list.size % 2 != 0
    diagnostic :error, :odd_hash, nil, list.last.loc.expression
  else
    list.
      each_slice(2).map do |key, value|
        n(:pair, [ key, value ],
          binary_op_map(key, nil, value))
      end
  end
end
pair_quoted(begin_t, parts, end_t, value) click to toggle source
# File lib/parser/builders/default.rb, line 513
def pair_quoted(begin_t, parts, end_t, value)
  end_t, pair_map = pair_quoted_map(begin_t, end_t, value)

  key = symbol_compose(begin_t, parts, end_t)

  n(:pair, [ key, value ], pair_map)
end
pin(pin_t, var) click to toggle source
# File lib/parser/builders/default.rb, line 1614
def pin(pin_t, var)
  n(:pin, [ var ],
    send_unary_op_map(pin_t, var))
end
postexe(postexe_t, lbrace_t, compstmt, rbrace_t) click to toggle source
# File lib/parser/builders/default.rb, line 1347
def postexe(postexe_t, lbrace_t, compstmt, rbrace_t)
  n(:postexe, [ compstmt ],
    keyword_map(postexe_t, lbrace_t, [], rbrace_t))
end
preexe(preexe_t, lbrace_t, compstmt, rbrace_t) click to toggle source

BEGIN, END

# File lib/parser/builders/default.rb, line 1342
def preexe(preexe_t, lbrace_t, compstmt, rbrace_t)
  n(:preexe, [ compstmt ],
    keyword_map(preexe_t, lbrace_t, [], rbrace_t))
end
procarg0(arg) click to toggle source
# File lib/parser/builders/default.rb, line 985
def procarg0(arg)
  if self.class.emit_procarg0
    if arg.type == :arg && self.class.emit_arg_inside_procarg0
      n(:procarg0, [ arg ],
        Source::Map::Collection.new(nil, nil, arg.location.expression))
    else
      arg.updated(:procarg0)
    end
  else
    arg
  end
end
range_exclusive(lhs, dot3_t, rhs) click to toggle source
# File lib/parser/builders/default.rb, line 578
def range_exclusive(lhs, dot3_t, rhs)
  n(:erange, [ lhs, rhs ],
    range_map(lhs, dot3_t, rhs))
end
range_inclusive(lhs, dot2_t, rhs) click to toggle source

Ranges

# File lib/parser/builders/default.rb, line 573
def range_inclusive(lhs, dot2_t, rhs)
  n(:irange, [ lhs, rhs ],
    range_map(lhs, dot2_t, rhs))
end
rational(rational_t) click to toggle source
# File lib/parser/builders/default.rb, line 280
def rational(rational_t)
  numeric(:rational, rational_t)
end
regexp_compose(begin_t, parts, end_t, options) click to toggle source
# File lib/parser/builders/default.rb, line 426
def regexp_compose(begin_t, parts, end_t, options)
  begin
    static_regexp(parts, options)
  rescue RegexpError => e
    diagnostic :error, :invalid_regexp, { :message => e.message },
               loc(begin_t).join(loc(end_t))
  end

  n(:regexp, (parts << options),
    regexp_map(begin_t, end_t, options))
end
regexp_options(regopt_t) click to toggle source

Regular expressions

# File lib/parser/builders/default.rb, line 417
def regexp_options(regopt_t)
  options = value(regopt_t).
    each_char.sort.uniq.
    map(&:to_sym)

  n(:regopt, options,
    token_map(regopt_t))
end
rescue_body(rescue_t, exc_list, assoc_t, exc_var, then_t, compound_stmt) click to toggle source

Exception handling

# File lib/parser/builders/default.rb, line 1354
def rescue_body(rescue_t,
                exc_list, assoc_t, exc_var,
                then_t, compound_stmt)
  n(:resbody, [ exc_list, exc_var, compound_stmt ],
    rescue_body_map(rescue_t, exc_list, assoc_t,
                    exc_var, then_t, compound_stmt))
end
restarg(star_t, name_t=nil) click to toggle source
# File lib/parser/builders/default.rb, line 926
def restarg(star_t, name_t=nil)
  if name_t
    check_reserved_for_numparam(value(name_t), loc(name_t))
    n(:restarg, [ value(name_t).to_sym ],
      arg_prefix_map(star_t, name_t))
  else
    n0(:restarg,
      arg_prefix_map(star_t))
  end
end
restarg_expr(star_t, expr=nil) click to toggle source
# File lib/parser/builders/default.rb, line 1009
def restarg_expr(star_t, expr=nil)
  if expr.nil?
    n0(:restarg, token_map(star_t))
  elsif expr.type == :lvasgn
    expr.updated(:restarg)
  else
    n(:restarg_expr, [ expr ],
      expr.loc.dup)
  end
end
self(token) click to toggle source

Access

# File lib/parser/builders/default.rb, line 587
def self(token)
  n0(:self,
    token_map(token))
end
shadowarg(name_t) click to toggle source
# File lib/parser/builders/default.rb, line 968
def shadowarg(name_t)
  check_reserved_for_numparam(value(name_t), loc(name_t))

  n(:shadowarg, [ value(name_t).to_sym ],
    variable_map(name_t))
end
splat(star_t, arg=nil) click to toggle source
# File lib/parser/builders/default.rb, line 445
def splat(star_t, arg=nil)
  if arg.nil?
    n0(:splat,
      unary_op_map(star_t))
  else
    n(:splat, [ arg ],
      unary_op_map(star_t, arg))
  end
end
string(string_t) click to toggle source

Strings

# File lib/parser/builders/default.rb, line 319
def string(string_t)
  n(:str, [ string_value(string_t) ],
    delimited_string_map(string_t))
end
string_compose(begin_t, parts, end_t) click to toggle source
# File lib/parser/builders/default.rb, line 329
def string_compose(begin_t, parts, end_t)
  if collapse_string_parts?(parts)
    if begin_t.nil? && end_t.nil?
      parts.first
    else
      n(:str, parts.first.children,
        string_map(begin_t, parts, end_t))
    end
  else
    n(:dstr, [ *parts ],
      string_map(begin_t, parts, end_t))
  end
end
string_internal(string_t) click to toggle source
# File lib/parser/builders/default.rb, line 324
def string_internal(string_t)
  n(:str, [ string_value(string_t) ],
    unquoted_map(string_t))
end
symbol(symbol_t) click to toggle source

Symbols

# File lib/parser/builders/default.rb, line 355
def symbol(symbol_t)
  n(:sym, [ string_value(symbol_t).to_sym ],
    prefix_string_map(symbol_t))
end
symbol_compose(begin_t, parts, end_t) click to toggle source
# File lib/parser/builders/default.rb, line 365
def symbol_compose(begin_t, parts, end_t)
  if collapse_string_parts?(parts)
    str = parts.first

    n(:sym, [ str.children.first.to_sym ],
      collection_map(begin_t, str.loc.expression, end_t))
  elsif @parser.version == 18 && parts.empty?
    diagnostic :error, :empty_symbol, nil, loc(begin_t).join(loc(end_t))
  else
    n(:dsym, [ *parts ],
      collection_map(begin_t, parts, end_t))
  end
end
symbol_internal(symbol_t) click to toggle source
# File lib/parser/builders/default.rb, line 360
def symbol_internal(symbol_t)
  n(:sym, [ string_value(symbol_t).to_sym ],
    unquoted_map(symbol_t))
end
symbols_compose(begin_t, parts, end_t) click to toggle source
# File lib/parser/builders/default.rb, line 469
def symbols_compose(begin_t, parts, end_t)
  parts = parts.map do |part|
    case part.type
    when :str
      value, = *part
      part.updated(:sym, [ value.to_sym ])
    when :dstr
      part.updated(:dsym)
    else
      part
    end
  end

  n(:array, [ *parts ],
    collection_map(begin_t, parts, end_t))
end
ternary(cond, question_t, if_true, colon_t, if_false) click to toggle source
# File lib/parser/builders/default.rb, line 1282
def ternary(cond, question_t, if_true, colon_t, if_false)
  n(:if, [ check_condition(cond), if_true, if_false ],
    ternary_map(cond, question_t, if_true, colon_t, if_false))
end
true(true_t) click to toggle source
# File lib/parser/builders/default.rb, line 260
def true(true_t)
  n0(:true,
    token_map(true_t))
end
unary_num(unary_t, numeric) click to toggle source
# File lib/parser/builders/default.rb, line 294
def unary_num(unary_t, numeric)
  value, = *numeric
  operator_loc = loc(unary_t)

  case value(unary_t)
  when '+'
    value = +value
  when '-'
    value = -value
  end

  numeric.updated(nil, [ value ],
    :location =>
      Source::Map::Operator.new(
        operator_loc,
        operator_loc.join(numeric.loc.expression)))
end
unary_op(op_t, receiver) click to toggle source
# File lib/parser/builders/default.rb, line 1228
def unary_op(op_t, receiver)
  case value(op_t)
  when '+', '-'
    method = value(op_t) + '@'
  else
    method = value(op_t)
  end

  n(:send, [ receiver, method.to_sym ],
    send_unary_op_map(op_t, receiver))
end
undef_method(undef_t, names) click to toggle source
# File lib/parser/builders/default.rb, line 866
def undef_method(undef_t, names)
  n(:undef, [ *names ],
    keyword_map(undef_t, nil, names, nil))
end
unless_guard(unless_t, unless_body) click to toggle source
# File lib/parser/builders/default.rb, line 1489
def unless_guard(unless_t, unless_body)
  n(:unless_guard, [unless_body], guard_map(unless_t, unless_body))
end
when(when_t, patterns, then_t, body) click to toggle source

Case matching

# File lib/parser/builders/default.rb, line 1289
def when(when_t, patterns, then_t, body)
  children = patterns << body
  n(:when, children,
    keyword_map(when_t, then_t, children, nil))
end
word(parts) click to toggle source
# File lib/parser/builders/default.rb, line 455
def word(parts)
  if collapse_string_parts?(parts)
    parts.first
  else
    n(:dstr, [ *parts ],
      collection_map(nil, parts, nil))
  end
end
words_compose(begin_t, parts, end_t) click to toggle source
# File lib/parser/builders/default.rb, line 464
def words_compose(begin_t, parts, end_t)
  n(:array, [ *parts ],
    collection_map(begin_t, parts, end_t))
end
xstring_compose(begin_t, parts, end_t) click to toggle source

Executable strings

# File lib/parser/builders/default.rb, line 381
def xstring_compose(begin_t, parts, end_t)
  n(:xstr, [ *parts ],
    string_map(begin_t, parts, end_t))
end

Private Instance Methods

arg_name_collides?(this_name, that_name) click to toggle source
# File lib/parser/builders/default.rb, line 1796
def arg_name_collides?(this_name, that_name)
  case @parser.version
  when 18
    this_name == that_name
  when 19
    # Ignore underscore.
    this_name != :_ &&
      this_name == that_name
  else
    # Ignore everything beginning with underscore.
    this_name && this_name[0] != '_' &&
      this_name == that_name
  end
end
arg_prefix_map(op_t, name_t=nil) click to toggle source
# File lib/parser/builders/default.rb, line 1992
def arg_prefix_map(op_t, name_t=nil)
  if name_t.nil?
    expr_l = loc(op_t)
  else
    expr_l = loc(op_t).join(loc(name_t))
  end

  Source::Map::Variable.new(loc(name_t), expr_l)
end
binary_op_map(left_e, op_t, right_e) click to toggle source
# File lib/parser/builders/default.rb, line 1966
def binary_op_map(left_e, op_t, right_e)
  Source::Map::Operator.new(loc(op_t), join_exprs(left_e, right_e))
end
block_map(receiver_l, begin_t, end_t) click to toggle source
# File lib/parser/builders/default.rb, line 2094
def block_map(receiver_l, begin_t, end_t)
  Source::Map::Collection.new(loc(begin_t), loc(end_t),
                              receiver_l.join(loc(end_t)))
end
check_assignment_to_numparam(name, loc) click to toggle source
# File lib/parser/builders/default.rb, line 1771
def check_assignment_to_numparam(name, loc)
  # MRI < 2.7 treats numbered parameters as regular variables
  # and so it's allowed to perform assignments like `_1 = 42`.
  return if @parser.version < 27

  assigning_to_numparam =
    @parser.context.in_dynamic_block? &&
    name =~ /\A_([1-9])\z/ &&
    @parser.max_numparam_stack.has_numparams?

  if assigning_to_numparam
    diagnostic :error, :cant_assign_to_numparam, { :name => name }, loc
  end
end
check_condition(cond) click to toggle source

VERIFICATION

# File lib/parser/builders/default.rb, line 1673
def check_condition(cond)
  case cond.type
  when :masgn
    if @parser.version <= 23
      diagnostic :error, :masgn_as_condition, nil, cond.loc.expression
    else
      cond
    end

  when :begin
    if cond.children.count == 1
      cond.updated(nil, [
        check_condition(cond.children.last)
      ])
    else
      cond
    end

  when :and, :or, :irange, :erange
    lhs, rhs = *cond

    type = case cond.type
    when :irange then :iflipflop
    when :erange then :eflipflop
    end

    if [:and, :or].include?(cond.type) &&
           @parser.version == 18
      cond
    else
      cond.updated(type, [
        check_condition(lhs),
        check_condition(rhs)
      ])
    end

  when :regexp
    n(:match_current_line, [ cond ], expr_map(cond.loc.expression))

  else
    cond
  end
end
check_duplicate_arg(this_arg, map={}) click to toggle source
# File lib/parser/builders/default.rb, line 1742
def check_duplicate_arg(this_arg, map={})
  this_name, = *this_arg

  that_arg   = map[this_name]
  that_name, = *that_arg

  if that_arg.nil?
    map[this_name] = this_arg
  elsif arg_name_collides?(this_name, that_name)
    diagnostic :error, :duplicate_argument, nil,
               this_arg.loc.name, [ that_arg.loc.name ]
  end
end
check_duplicate_args(args, map={}) click to toggle source
# File lib/parser/builders/default.rb, line 1717
def check_duplicate_args(args, map={})
  args.each do |this_arg|
    case this_arg.type
    when :arg, :optarg, :restarg, :blockarg,
         :kwarg, :kwoptarg, :kwrestarg,
         :shadowarg

      check_duplicate_arg(this_arg, map)

    when :procarg0

      if this_arg.children[0].is_a?(Symbol)
        # s(:procarg0, :a)
        check_duplicate_arg(this_arg, map)
      else
        # s(:procarg0, s(:arg, :a), ...)
        check_duplicate_args(this_arg.children, map)
      end

    when :mlhs
      check_duplicate_args(this_arg.children, map)
    end
  end
end
check_duplicate_pattern_key(name, loc) click to toggle source
# File lib/parser/builders/default.rb, line 1829
def check_duplicate_pattern_key(name, loc)
  if @parser.pattern_hash_keys.declared?(name)
    diagnostic :error, :duplicate_pattern_key, { name: name.to_s }, loc
  end

  @parser.pattern_hash_keys.declare(name)
end
check_duplicate_pattern_variable(name, loc) click to toggle source
# File lib/parser/builders/default.rb, line 1819
def check_duplicate_pattern_variable(name, loc)
  return if name.to_s.start_with?('_')

  if @parser.pattern_variables.declared?(name)
    diagnostic :error, :duplicate_variable_name, { name: name.to_s }, loc
  end

  @parser.pattern_variables.declare(name)
end
check_lvar_name(name, loc) click to toggle source
# File lib/parser/builders/default.rb, line 1811
def check_lvar_name(name, loc)
  if name =~ /\A[[[:lower:]]_][[[:alnum:]]_]*\z/
    # OK
  else
    diagnostic :error, :lvar_name, { name: name }, loc
  end
end
check_reserved_for_numparam(name, loc) click to toggle source
# File lib/parser/builders/default.rb, line 1786
def check_reserved_for_numparam(name, loc)
  # MRI < 3.0 accepts assignemnt to variables like _1
  # if it's not a numbered parameter. MRI 3.0 and newer throws an error.
  return if @parser.version < 30

  if name =~ /\A_([1-9])\z/
    diagnostic :error, :reserved_for_numparam, { :name => name }, loc
  end
end
collapse_string_parts?(parts) click to toggle source
# File lib/parser/builders/default.rb, line 2251
def collapse_string_parts?(parts)
  parts.one? &&
      [:str, :dstr].include?(parts.first.type)
end
collection_map(begin_t, parts, end_t) click to toggle source
# File lib/parser/builders/default.rb, line 1917
def collection_map(begin_t, parts, end_t)
  if begin_t.nil? || end_t.nil?
    if parts.any?
      expr_l = join_exprs(parts.first, parts.last)
    elsif !begin_t.nil?
      expr_l = loc(begin_t)
    elsif !end_t.nil?
      expr_l = loc(end_t)
    end
  else
    expr_l = loc(begin_t).join(loc(end_t))
  end

  Source::Map::Collection.new(loc(begin_t), loc(end_t), expr_l)
end
condition_map(keyword_t, cond_e, begin_t, body_e, else_t, else_e, end_t) click to toggle source
# File lib/parser/builders/default.rb, line 2121
def condition_map(keyword_t, cond_e, begin_t, body_e, else_t, else_e, end_t)
  if end_t
    end_l = loc(end_t)
  elsif else_e && else_e.loc.expression
    end_l = else_e.loc.expression
  elsif loc(else_t)
    end_l = loc(else_t)
  elsif body_e && body_e.loc.expression
    end_l = body_e.loc.expression
  elsif loc(begin_t)
    end_l = loc(begin_t)
  else
    end_l = cond_e.loc.expression
  end

  Source::Map::Condition.new(loc(keyword_t),
                             loc(begin_t), loc(else_t), loc(end_t),
                             loc(keyword_t).join(end_l))
end
constant_map(scope, colon2_t, name_t) click to toggle source
# File lib/parser/builders/default.rb, line 1952
def constant_map(scope, colon2_t, name_t)
  if scope.nil?
    expr_l = loc(name_t)
  else
    expr_l = scope.loc.expression.join(loc(name_t))
  end

  Source::Map::Constant.new(loc(colon2_t), loc(name_t), expr_l)
end
definition_map(keyword_t, operator_t, name_t, end_t) click to toggle source
# File lib/parser/builders/default.rb, line 2025
def definition_map(keyword_t, operator_t, name_t, end_t)
  Source::Map::MethodDefinition.new(loc(keyword_t),
                                    loc(operator_t), loc(name_t),
                                    loc(end_t), nil, nil)
end
delimited_string_map(string_t) click to toggle source
# File lib/parser/builders/default.rb, line 1858
def delimited_string_map(string_t)
  str_range = loc(string_t)

  begin_l = str_range.with(end_pos: str_range.begin_pos + 1)

  end_l   = str_range.with(begin_pos: str_range.end_pos - 1)

  Source::Map::Collection.new(begin_l, end_l,
                              loc(string_t))
end
diagnostic(type, reason, arguments, location, highlights=[]) click to toggle source
# File lib/parser/builders/default.rb, line 2273
def diagnostic(type, reason, arguments, location, highlights=[])
  @parser.diagnostics.process(
      Diagnostic.new(type, reason, arguments, location, highlights))

  if type == :error
    @parser.send :yyerror
  end
end
eh_keyword_map(compstmt_e, keyword_t, body_es, else_t, else_e) click to toggle source
# File lib/parser/builders/default.rb, line 2165
def eh_keyword_map(compstmt_e, keyword_t, body_es,
                   else_t, else_e)
  if compstmt_e.nil?
    if keyword_t.nil?
      begin_l = body_es.first.loc.expression
    else
      begin_l = loc(keyword_t)
    end
  else
    begin_l = compstmt_e.loc.expression
  end

  if else_t
    if else_e.nil?
      end_l = loc(else_t)
    else
      end_l = else_e.loc.expression
    end
  elsif !body_es.last.nil?
    end_l = body_es.last.loc.expression
  else
    end_l = loc(keyword_t)
  end

  Source::Map::Condition.new(loc(keyword_t), nil, loc(else_t), nil,
                             begin_l.join(end_l))
end
endless_definition_map(keyword_t, operator_t, name_t, assignment_t, body_e) click to toggle source
# File lib/parser/builders/default.rb, line 2031
def endless_definition_map(keyword_t, operator_t, name_t, assignment_t, body_e)
  body_l = body_e.loc.expression

  Source::Map::MethodDefinition.new(loc(keyword_t),
                                    loc(operator_t), loc(name_t), nil,
                                    loc(assignment_t), body_l)
end
expr_map(loc) click to toggle source
# File lib/parser/builders/default.rb, line 1913
def expr_map(loc)
  Source::Map.new(loc)
end
for_map(keyword_t, in_t, begin_t, end_t) click to toggle source
# File lib/parser/builders/default.rb, line 2146
def for_map(keyword_t, in_t, begin_t, end_t)
  Source::Map::For.new(loc(keyword_t), loc(in_t),
                       loc(begin_t), loc(end_t),
                       loc(keyword_t).join(loc(end_t)))
end
guard_map(keyword_t, guard_body_e) click to toggle source
# File lib/parser/builders/default.rb, line 2193
def guard_map(keyword_t, guard_body_e)
  keyword_l = loc(keyword_t)
  guard_body_l = guard_body_e.loc.expression

  Source::Map::Keyword.new(keyword_l, nil, nil, keyword_l.join(guard_body_l))
end
index_map(receiver_e, lbrack_t, rbrack_t) click to toggle source
# File lib/parser/builders/default.rb, line 2083
def index_map(receiver_e, lbrack_t, rbrack_t)
  Source::Map::Index.new(loc(lbrack_t), loc(rbrack_t),
                         receiver_e.loc.expression.join(loc(rbrack_t)))
end
join_exprs(left_expr, right_expr) click to toggle source
# File lib/parser/builders/default.rb, line 1849
def join_exprs(left_expr, right_expr)
  left_expr.loc.expression.
    join(right_expr.loc.expression)
end
keyword_map(keyword_t, begin_t, args, end_t) click to toggle source
# File lib/parser/builders/default.rb, line 2099
def keyword_map(keyword_t, begin_t, args, end_t)
  args ||= []

  if end_t
    end_l = loc(end_t)
  elsif args.any? && !args.last.nil?
    end_l = args.last.loc.expression
  elsif args.any? && args.count > 1
    end_l = args[-2].loc.expression
  else
    end_l = loc(keyword_t)
  end

  Source::Map::Keyword.new(loc(keyword_t), loc(begin_t), loc(end_t),
                           loc(keyword_t).join(end_l))
end
keyword_mod_map(pre_e, keyword_t, post_e) click to toggle source
# File lib/parser/builders/default.rb, line 2116
def keyword_mod_map(pre_e, keyword_t, post_e)
  Source::Map::Keyword.new(loc(keyword_t), nil, nil,
                           join_exprs(pre_e, post_e))
end
kwarg_map(name_t, value_e=nil) click to toggle source
# File lib/parser/builders/default.rb, line 2002
def kwarg_map(name_t, value_e=nil)
  label_range = loc(name_t)
  name_range  = label_range.adjust(end_pos: -1)

  if value_e
    expr_l = loc(name_t).join(value_e.loc.expression)
  else
    expr_l = loc(name_t)
  end

  Source::Map::Variable.new(name_range, expr_l)
end
kwargs?(node) click to toggle source
# File lib/parser/builders/default.rb, line 2304
def kwargs?(node)
  node.type == :hash && node.loc.begin.nil? && node.loc.end.nil?
end
loc(token) click to toggle source
# File lib/parser/builders/default.rb, line 2268
def loc(token)
  # Pass through `nil`s and return nil for tNL.
  token[1] if token && token[0]
end
module_definition_map(keyword_t, name_e, operator_t, end_t) click to toggle source
# File lib/parser/builders/default.rb, line 2015
def module_definition_map(keyword_t, name_e, operator_t, end_t)
  if name_e
    name_l = name_e.loc.expression
  end

  Source::Map::Definition.new(loc(keyword_t),
                              loc(operator_t), name_l,
                              loc(end_t))
end
n(type, children, source_map) click to toggle source

SOURCE MAPS

# File lib/parser/builders/default.rb, line 1841
def n(type, children, source_map)
  AST::Node.new(type, children, :location => source_map)
end
n0(type, source_map) click to toggle source
# File lib/parser/builders/default.rb, line 1845
def n0(type, source_map)
  n(type, [], source_map)
end
numeric(kind, token) click to toggle source
# File lib/parser/builders/default.rb, line 288
def numeric(kind, token)
  n(kind, [ value(token) ],
    Source::Map::Operator.new(nil, loc(token)))
end
pair_keyword_map(key_t, value_e) click to toggle source
# File lib/parser/builders/default.rb, line 1883
def pair_keyword_map(key_t, value_e)
  key_range = loc(key_t)

  key_l   = key_range.adjust(end_pos: -1)

  colon_l = key_range.with(begin_pos: key_range.end_pos - 1)

  [ # key map
    Source::Map::Collection.new(nil, nil,
                                key_l),
    # pair map
    Source::Map::Operator.new(colon_l,
                              key_range.join(value_e.loc.expression)) ]
end
pair_quoted_map(begin_t, end_t, value_e) click to toggle source
# File lib/parser/builders/default.rb, line 1898
def pair_quoted_map(begin_t, end_t, value_e)
  end_l = loc(end_t)

  quote_l = end_l.with(begin_pos: end_l.end_pos - 2,
                       end_pos: end_l.end_pos - 1)

  colon_l = end_l.with(begin_pos: end_l.end_pos - 1)

  [ # modified end token
    [ value(end_t), quote_l ],
    # pair map
    Source::Map::Operator.new(colon_l,
                              loc(begin_t).join(value_e.loc.expression)) ]
end
prefix_string_map(symbol) click to toggle source
# File lib/parser/builders/default.rb, line 1869
def prefix_string_map(symbol)
  str_range = loc(symbol)

  begin_l = str_range.with(end_pos: str_range.begin_pos + 1)

  Source::Map::Collection.new(begin_l, nil,
                              loc(symbol))
end
range_map(start_e, op_t, end_e) click to toggle source
# File lib/parser/builders/default.rb, line 1980
def range_map(start_e, op_t, end_e)
  if start_e && end_e
    expr_l = join_exprs(start_e, end_e)
  elsif start_e
    expr_l = start_e.loc.expression.join(loc(op_t))
  elsif end_e
    expr_l = loc(op_t).join(end_e.loc.expression)
  end

  Source::Map::Operator.new(loc(op_t), expr_l)
end
regexp_map(begin_t, end_t, options_e) click to toggle source
# File lib/parser/builders/default.rb, line 1947
def regexp_map(begin_t, end_t, options_e)
  Source::Map::Collection.new(loc(begin_t), loc(end_t),
                              loc(begin_t).join(options_e.loc.expression))
end
rescue_body_map(keyword_t, exc_list_e, assoc_t, exc_var_e, then_t, compstmt_e) click to toggle source
# File lib/parser/builders/default.rb, line 2152
def rescue_body_map(keyword_t, exc_list_e, assoc_t,
                    exc_var_e, then_t,
                    compstmt_e)
  end_l = compstmt_e.loc.expression if compstmt_e
  end_l = loc(then_t)               if end_l.nil? && then_t
  end_l = exc_var_e.loc.expression  if end_l.nil? && exc_var_e
  end_l = exc_list_e.loc.expression if end_l.nil? && exc_list_e
  end_l = loc(keyword_t)            if end_l.nil?

  Source::Map::RescueBody.new(loc(keyword_t), loc(assoc_t), loc(then_t),
                              loc(keyword_t).join(end_l))
end
rewrite_hash_args_to_kwargs(args) click to toggle source
# File lib/parser/builders/default.rb, line 2294
def rewrite_hash_args_to_kwargs(args)
  if args.any? && kwargs?(args.last)
    # foo(..., bar: baz)
    args[args.length - 1] = args[args.length - 1].updated(:kwargs)
  elsif args.length > 1 && args.last.type == :block_pass && kwargs?(args[args.length - 2])
    # foo(..., bar: baz, &blk)
    args[args.length - 2] = args[args.length - 2].updated(:kwargs)
  end
end
send_binary_op_map(lhs_e, selector_t, rhs_e) click to toggle source
# File lib/parser/builders/default.rb, line 2065
def send_binary_op_map(lhs_e, selector_t, rhs_e)
  Source::Map::Send.new(nil, loc(selector_t),
                        nil, nil,
                        join_exprs(lhs_e, rhs_e))
end
send_index_map(receiver_e, lbrack_t, rbrack_t) click to toggle source
# File lib/parser/builders/default.rb, line 2088
def send_index_map(receiver_e, lbrack_t, rbrack_t)
  Source::Map::Send.new(nil, loc(lbrack_t).join(loc(rbrack_t)),
                        nil, nil,
                        receiver_e.loc.expression.join(loc(rbrack_t)))
end
send_map(receiver_e, dot_t, selector_t, begin_t=nil, args=[], end_t=nil) click to toggle source
# File lib/parser/builders/default.rb, line 2039
def send_map(receiver_e, dot_t, selector_t, begin_t=nil, args=[], end_t=nil)
  if receiver_e
    begin_l = receiver_e.loc.expression
  elsif selector_t
    begin_l = loc(selector_t)
  end

  if end_t
    end_l   = loc(end_t)
  elsif args.any?
    end_l   = args.last.loc.expression
  elsif selector_t
    end_l   = loc(selector_t)
  end

  Source::Map::Send.new(loc(dot_t),   loc(selector_t),
                        loc(begin_t), loc(end_t),
                        begin_l.join(end_l))
end
send_unary_op_map(selector_t, arg_e) click to toggle source
# File lib/parser/builders/default.rb, line 2071
def send_unary_op_map(selector_t, arg_e)
  if arg_e.nil?
    expr_l = loc(selector_t)
  else
    expr_l = loc(selector_t).join(arg_e.loc.expression)
  end

  Source::Map::Send.new(nil, loc(selector_t),
                        nil, nil,
                        expr_l)
end
static_regexp(parts, options) click to toggle source
# File lib/parser/builders/default.rb, line 2224
def static_regexp(parts, options)
  source = static_string(parts)
  return nil if source.nil?

  source = case
  when options.children.include?(:u)
    source.encode(Encoding::UTF_8)
  when options.children.include?(:e)
    source.encode(Encoding::EUC_JP)
  when options.children.include?(:s)
    source.encode(Encoding::WINDOWS_31J)
  when options.children.include?(:n)
    source.encode(Encoding::BINARY)
  else
    source
  end

  Regexp.new(source, (Regexp::EXTENDED if options.children.include?(:x)))
end
static_regexp_node(node) click to toggle source
# File lib/parser/builders/default.rb, line 2244
def static_regexp_node(node)
  if node.type == :regexp
    parts, options = node.children[0..-2], node.children[-1]
    static_regexp(parts, options)
  end
end
static_string(nodes) click to toggle source

Extract a static string from e.g. a regular expression, honoring the fact that MRI expands interpolations like #{“”} at parse time.

# File lib/parser/builders/default.rb, line 2207
def static_string(nodes)
  nodes.map do |node|
    case node.type
    when :str
      node.children[0]
    when :begin
      if (string = static_string(node.children))
        string
      else
        return nil
      end
    else
      return nil
    end
  end.join
end
string_map(begin_t, parts, end_t) click to toggle source
# File lib/parser/builders/default.rb, line 1933
def string_map(begin_t, parts, end_t)
  if begin_t && value(begin_t).start_with?('<<')
    if parts.any?
      expr_l = join_exprs(parts.first, parts.last)
    else
      expr_l = loc(end_t).begin
    end

    Source::Map::Heredoc.new(loc(begin_t), expr_l, loc(end_t))
  else
    collection_map(begin_t, parts, end_t)
  end
end
string_value(token) click to toggle source
# File lib/parser/builders/default.rb, line 2260
def string_value(token)
  unless token[0].valid_encoding?
    diagnostic(:error, :invalid_encoding, nil, token[1])
  end

  token[0]
end
ternary_map(begin_e, question_t, mid_e, colon_t, end_e) click to toggle source
# File lib/parser/builders/default.rb, line 2141
def ternary_map(begin_e, question_t, mid_e, colon_t, end_e)
  Source::Map::Ternary.new(loc(question_t), loc(colon_t),
                           join_exprs(begin_e, end_e))
end
token_map(token) click to toggle source
# File lib/parser/builders/default.rb, line 1854
def token_map(token)
  Source::Map.new(loc(token))
end
unary_op_map(op_t, arg_e=nil) click to toggle source
# File lib/parser/builders/default.rb, line 1970
def unary_op_map(op_t, arg_e=nil)
  if arg_e.nil?
    expr_l = loc(op_t)
  else
    expr_l = loc(op_t).join(arg_e.loc.expression)
  end

  Source::Map::Operator.new(loc(op_t), expr_l)
end
unquoted_map(token) click to toggle source
# File lib/parser/builders/default.rb, line 1878
def unquoted_map(token)
  Source::Map::Collection.new(nil, nil,
                              loc(token))
end
validate_definee(definee) click to toggle source
# File lib/parser/builders/default.rb, line 2282
def validate_definee(definee)
  case definee.type
  when :int, :str, :dstr, :sym, :dsym,
       :regexp, :array, :hash

    diagnostic :error, :singleton_literal, nil, definee.loc.expression
    false
  else
    true
  end
end
validate_no_forward_arg_after_restarg(args) click to toggle source
# File lib/parser/builders/default.rb, line 1756
def validate_no_forward_arg_after_restarg(args)
  restarg = nil
  forward_arg = nil
  args.each do |arg|
    case arg.type
    when :restarg then restarg = arg
    when :forward_arg then forward_arg = arg
    end
  end

  if !forward_arg.nil? && !restarg.nil?
    diagnostic :error, :forward_arg_after_restarg, nil, forward_arg.loc.expression, [restarg.loc.expression]
  end
end
value(token) click to toggle source
# File lib/parser/builders/default.rb, line 2256
def value(token)
  token[0]
end
var_send_map(variable_e) click to toggle source
# File lib/parser/builders/default.rb, line 2059
def var_send_map(variable_e)
  Source::Map::Send.new(nil, variable_e.loc.expression,
                        nil, nil,
                        variable_e.loc.expression)
end
variable_map(name_t) click to toggle source
# File lib/parser/builders/default.rb, line 1962
def variable_map(name_t)
  Source::Map::Variable.new(loc(name_t))
end