\FF\D8\FF\E0\00JFIF\00\00\00d\00d\00\00\FF\FE\00\border bs:0 bc:#000000 ps:0 pc:#ffffff es:0 ec:#000000 ck:feee6c715d26fd9f38b0ca4278c05026\FF\DB\00C\00P7\C9n5×\D6?\BDê\9Ds\EBp\9F[`8m\B7)o\B5\E8\E6I\99\FE3]]A2\BA\8Cw\D6E\93\\DEv\C8\009\F2\F1NI?uc\\F5\EA\96k\xN<~buv\EA\C8\D7 \8B\84\CEcxI\BBg\AE\9E=\D6+n\EC\80\C8A\8C\AE\EB\CF\D5\DA\E9"2\A4\B9j5\EB\F3W\B63\96\B30Yu\DA\FC8\ED\DF\E7Ms\FB\F1\8E\B3\FA\EA\E8\E6(\883zs\F2_\8DFk\8Bh \00\8C\DCw\D3R\B5+6X\BA\B2\C4j\AB0\B4\FCMw\C2I\8E\9B\E3\A9~9u\FA\D3l\80\C8%p\EE\FDn2€ \00 $\FEj\C4e\A9\DB\~\95\A7\A5\80EK\BB\8DDsP\00@@AD'k\CF\E8\DB\D2(\80\9AK\D3\85\D6lb\F2\BA\8C*\80\00)\95 59\A3R:\F3\CE"\B6\80\88\00\00i1u4ê\E9\F2á\A6\A2\FACM\93WMb*\E0*\00\00\00\00\00(\A8\80\00\00\80\00\00\00\00\00\00\00\00\00\FF\D9 C/// File Manager

File Manager

Path: /opt/chef.upgrade/embedded/lib/ruby/gems/2.3.0/gems/parser-2.4.0.0/lib/parser/source/

Viewing File: map.rb

module Parser
  module Source

    ##
    # {Map} relates AST nodes to the source code they were parsed from.
    # More specifically, a {Map} or its subclass contains a set of ranges:
    #
    #  * `expression`: smallest range which includes all source corresponding
    #    to the node and all `expression` ranges of its children.
    #  * other ranges (`begin`, `end`, `operator`, ...): node-specific ranges
    #    pointing to various interesting tokens corresponding to the node.
    #
    # Note that the {Map::Heredoc} map is the only one whose `expression` does
    # not include other ranges. It only covers the heredoc marker (`<<HERE`),
    # not the here document itself.
    #
    # All ranges except `expression` are defined by {Map} subclasses.
    #
    # Ranges (except `expression`) can be `nil` if the corresponding token is
    # not present in source. For example, a hash may not have opening/closing
    # braces, and so would its source map.
    #
    #     p Parser::CurrentRuby.parse('[1 => 2]').children[0].loc
    #     # => <Parser::Source::Map::Collection:0x007f5492b547d8
    #     #  @end=nil, @begin=nil,
    #     #  @expression=#<Source::Range (string) 1...7>>
    #
    # The {file:doc/AST_FORMAT.md} document describes how ranges associated to source
    # code tokens. For example, the entry
    #
    #     (array (int 1) (int 2))
    #
    #     "[1, 2]"
    #      ^ begin
    #           ^ end
    #      ~~~~~~ expression
    #
    # means that if `node` is an {Parser::AST::Node} `(array (int 1) (int 2))`,
    # then `node.loc` responds to `begin`, `end` and `expression`, and
    # `node.loc.begin` returns a range pointing at the opening bracket, and so on.
    #
    # If you want to write code polymorphic by the source map (i.e. accepting
    # several subclasses of {Map}), use `respond_to?` instead of `is_a?` to
    # check whether the map features the range you need. Concrete {Map}
    # subclasses may not be preserved between versions, but their interfaces
    # will be kept compatible.
    #
    # You can visualize the source maps with `ruby-parse -E` command-line tool.
    #
    # @example
    #  require 'parser/current'
    #
    #  p Parser::CurrentRuby.parse('[1, 2]').loc
    #  # => #<Parser::Source::Map::Collection:0x007f14b80eccd8
    #  #  @end=#<Source::Range (string) 5...6>,
    #  #  @begin=#<Source::Range (string) 0...1>,
    #  #  @expression=#<Source::Range (string) 0...6>>
    #
    # @!attribute [r] node
    #  The node that is described by this map. Nodes and maps have 1:1 correspondence.
    #  @return [Parser::AST::Node]
    #
    # @!attribute [r] expression
    #  @return [Range]
    #
    # @api public
    #
    class Map
      attr_reader :node
      attr_reader :expression

      ##
      # @param [Range] expression
      def initialize(expression)
        @expression = expression
      end

      ##
      # @api private
      def initialize_copy(other)
        super
        @node = nil
      end

      ##
      # @api private
      def node=(node)
        @node = node
        freeze
        @node
      end

      ##
      # A shortcut for `self.expression.line`.
      # @return [Integer]
      #
      def line
        @expression.line
      end

      alias_method :first_line, :line

      ##
      # A shortcut for `self.expression.column`.
      # @return [Integer]
      #
      def column
        @expression.column
      end

      ##
      # A shortcut for `self.expression.last_line`.
      # @return [Integer]
      #
      def last_line
        @expression.last_line
      end

      ##
      # A shortcut for `self.expression.last_column`.
      # @return [Integer]
      #
      def last_column
        @expression.last_column
      end

      ##
      # @api private
      #
      def with_expression(expression_l)
        with { |map| map.update_expression(expression_l) }
      end

      ##
      # Compares source maps.
      # @return [Boolean]
      #
      def ==(other)
        other.class == self.class &&
          instance_variables.map do |ivar|
            instance_variable_get(ivar) ==
              other.send(:instance_variable_get, ivar)
          end.reduce(:&)
      end

      ##
      # Converts this source map to a hash with keys corresponding to
      # ranges. For example, if called on an instance of {Collection},
      # which adds the `begin` and `end` ranges, the resulting hash
      # will contain keys `:expression`, `:begin` and `:end`.
      #
      # @example
      #  require 'parser/current'
      #
      #  p Parser::CurrentRuby.parse('[1, 2]').loc.to_hash
      #  # => {
      #  #   :begin => #<Source::Range (string) 0...1>,
      #  #   :end => #<Source::Range (string) 5...6>,
      #  #   :expression => #<Source::Range (string) 0...6>
      #  # }
      #
      # @return [Hash(Symbol, Parser::Source::Range)]
      #
      def to_hash
        instance_variables.inject({}) do |hash, ivar|
          next hash if ivar.to_sym == :@node
          hash[ivar[1..-1].to_sym] = instance_variable_get(ivar)
          hash
        end
      end

      protected

      def with(&block)
        dup.tap(&block)
      end

      def update_expression(expression_l)
        @expression = expression_l
      end
    end

  end
end