Sha256: e4afbf0287aeaf3c7f8195cfc4a8a121b53677a679448e1442468cefeeec3a49

Contents?: true

Size: 1.35 KB

Versions: 30

Compression:

Stored size: 1.35 KB

Contents

# frozen_string_literal: true

module Mutant
  module AST
    # Given an AST, finds the sclass that directly(-ish) contains the provided
    # node.
    # This won't match arbitrarily complex structures - it only searches the
    # first level deep (no begins-in-begins, for example). This is in
    # keeping with mutant generally not supporting 'weird' syntax.
    # Descending into 'begin' nodes is supported because these are generated for
    # the one-line syntax class << self; def foo; end
    class FindMetaclassContaining
      include NodePredicates, Concord.new(:root, :target), Procto.call

      SCLASS_BODY_INDEX = 1

      private_constant(*constants(false))

      # Find metaclass node containing target node
      #
      # @return [Parser::AST::Node, nil]
      #
      # @api private
      def call
        AST.find_last_path(root) do |current|
          next unless n_sclass?(current)

          metaclass_of?(current)
        end.last
      end

    private

      def metaclass_of?(sclass)
        body = sclass.children.fetch(SCLASS_BODY_INDEX)
        body.equal?(target) || transparently_contains?(body)
      end

      def transparently_contains?(body)
        n_begin?(body) && include_exact?(body.children, target)
      end

      def include_exact?(haystack, needle)
        haystack.any? { |elem| elem.equal?(needle) }
      end
    end
  end
end

Version data entries

30 entries across 30 versions & 1 rubygems

Version Path
mutant-0.10.25 lib/mutant/ast/find_metaclass_containing.rb
mutant-0.10.24 lib/mutant/ast/find_metaclass_containing.rb
mutant-0.10.23 lib/mutant/ast/find_metaclass_containing.rb
mutant-0.10.22 lib/mutant/ast/find_metaclass_containing.rb
mutant-0.10.21 lib/mutant/ast/find_metaclass_containing.rb
mutant-0.10.20 lib/mutant/ast/find_metaclass_containing.rb
mutant-0.10.19 lib/mutant/ast/find_metaclass_containing.rb
mutant-0.10.18 lib/mutant/ast/find_metaclass_containing.rb
mutant-0.10.17 lib/mutant/ast/find_metaclass_containing.rb
mutant-0.10.16 lib/mutant/ast/find_metaclass_containing.rb
mutant-0.10.15 lib/mutant/ast/find_metaclass_containing.rb
mutant-0.10.14 lib/mutant/ast/find_metaclass_containing.rb
mutant-0.10.13 lib/mutant/ast/find_metaclass_containing.rb
mutant-0.10.12 lib/mutant/ast/find_metaclass_containing.rb
mutant-0.10.11 lib/mutant/ast/find_metaclass_containing.rb
mutant-0.10.10 lib/mutant/ast/find_metaclass_containing.rb
mutant-0.10.9 lib/mutant/ast/find_metaclass_containing.rb
mutant-0.10.8 lib/mutant/ast/find_metaclass_containing.rb
mutant-0.10.7 lib/mutant/ast/find_metaclass_containing.rb
mutant-0.10.6 lib/mutant/ast/find_metaclass_containing.rb