Sha256: 56924bc11fbb4288db288f8e71d8e9f75a36891065cccd0c7b2b133d931c2992

Contents?: true

Size: 1.98 KB

Versions: 3

Compression:

Stored size: 1.98 KB

Contents

# encoding: utf-8

module Rubocop
  module Cop
    module VariableInspector
      # A Scope represents a context of local variable visibility.
      # This is a place where local variables belong to.
      # A scope instance holds a scope node and variable entries.
      class Scope
        attr_reader :node, :variables

        def initialize(node)
          # Accept begin node for top level scope.
          unless SCOPE_TYPES.include?(node.type) || node.type == :begin
            fail ArgumentError,
                 "Node type must be any of #{SCOPE_TYPES}, " +
                 "passed #{node.type}"
          end
          @node = node
          @variables = {}
        end

        def ==(other)
          @node.equal?(other.node)
        end

        def body_node
          child_index = case @node.type
                        when :top_level           then 0
                        when :module, :sclass     then 1
                        when :def, :class, :block then 2
                        when :defs                then 3
                        end

          @node.children[child_index]
        end

        def ancestors_of_node(target_node)
          ASTScanner.scan(@node) do |scanning_node, ancestor_nodes|
            return ancestor_nodes[1..-1] if scanning_node.equal?(target_node)
          end

          fail "Node #{target_node} is not found in scope #{@node}"
        end

        # This class provides a ways to scan AST with tracking ancestor nodes.
        class ASTScanner
          def self.scan(node, &block)
            new.scan(node, &block)
          end

          def initialize
            @ancestor_nodes = []
          end

          def scan(node, &block)
            @ancestor_nodes.push(node)

            node.children.each do |child|
              next unless child.is_a?(Parser::AST::Node)
              yield child, @ancestor_nodes
              scan(child, &block)
            end

            @ancestor_nodes.pop
          end
        end
      end
    end
  end
end

Version data entries

3 entries across 3 versions & 1 rubygems

Version Path
rubocop-0.18.1 lib/rubocop/cop/variable_inspector/scope.rb
rubocop-0.18.0 lib/rubocop/cop/variable_inspector/scope.rb
rubocop-0.17.0 lib/rubocop/cop/variable_inspector/scope.rb