\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/embedded/lib/ruby/gems/2.7.0/gems/pry-0.13.1/lib/pry/commands/

Viewing File: find_method.rb

# frozen_string_literal: true

class Pry
  class Command
    class FindMethod < Pry::ClassCommand
      extend Pry::Helpers::BaseHelpers

      match 'find-method'
      group 'Context'
      description 'Recursively search for a method within a Class/Module or ' \
                  'the current namespace.'
      command_options shellwords: false

      banner <<-'BANNER'
        Usage: find-method  [-n|-c] METHOD [NAMESPACE]

        Recursively search for a method within a Class/Module or the current namespace.
        Use the `-n` switch (the default) to search for methods whose name matches the
        given regex. Use the `-c` switch to search for methods that contain the given
        code.

        # Find all methods whose name match /re/ inside
        # the Pry namespace. Matches Pry#repl, etc.
        find-method re Pry

        # Find all methods that contain the code:
        # output.puts inside the Pry namespace.
        find-method -c 'output.puts' Pry
      BANNER

      def options(opt)
        opt.on :n, :name,    "Search for a method by name"
        opt.on :c, :content, "Search for a method based on content in Regex form"
      end

      def process
        return if args.empty?

        klass = search_class

        matches = opts.content? ? content_search(klass) : name_search(klass)
        show_search_results(matches)
      end

      private

      # @return [Regexp] The pattern to search for.
      def pattern
        @pattern ||= ::Regexp.new args[0]
      end

      # Output the result of the search.
      #
      # @param [Array] matches
      def show_search_results(matches)
        if matches.empty?
          output.puts bold("No Methods Matched")
        else
          print_matches(matches)
        end
      end

      # The class to search for methods.
      # We only search classes, so if the search object is an
      # instance, return its class. If no search object is given
      # search `target_self`.
      def search_class
        klass = if args[1]
                  target.eval(args[1])
                else
                  target_self
                end

        klass.is_a?(Module) ? klass : klass.class
      end

      # pretty-print a list of matching methods.
      #
      # @param [Array<Method>] matches
      def print_matches(matches)
        grouped = matches.group_by(&:owner)
        order = grouped.keys.sort_by { |x| x.name || x.to_s }

        order.each do |klass|
          print_matches_for_class(klass, grouped)
        end
      end

      # Print matched methods for a class
      def print_matches_for_class(klass, grouped)
        output.puts bold(klass.name)
        grouped[klass].each do |method|
          header = method.name_with_owner
          output.puts header + additional_info(header, method)
        end
      end

      # Return the matched lines of method source if `-c` is given or ""
      # if `-c` was not given
      def additional_info(header, method)
        if opts.content?
          ': ' + colorize_code(matched_method_lines(header, method))
        else
          ""
        end
      end

      def matched_method_lines(header, method)
        method.source.split(/\n/).select { |x| x =~ pattern }.join(
          "\n#{' ' * header.length}"
        )
      end

      # Run the given block against every constant in the provided namespace.
      #
      # @param [Module] klass The namespace in which to start the search.
      # @param [Hash<Module,Boolean>] done The namespaces we've already visited (private)
      # @yieldparam klass Each class/module in the namespace.
      #
      def recurse_namespace(klass, done = {}, &block)
        return if !klass.is_a?(Module) || done[klass]

        done[klass] = true

        yield klass

        klass.constants.each do |name|
          next if klass.autoload?(name)

          begin
            const = klass.const_get(name)
          rescue RescuableException # rubocop:disable Lint/HandleExceptions
            # constant loading is an inexact science at the best of times,
            # this often happens when a constant was .autoload? but someone
            # tried to load it. It's now not .autoload? but will still raise
            # a NameError when you access it.
          else
            recurse_namespace(const, done, &block)
          end
        end
      end

      # Gather all the methods in a namespace that pass the given block.
      #
      # @param [Module] namespace The namespace in which to search.
      # @yieldparam [Method] method The method to test
      # @yieldreturn [Boolean]
      # @return [Array<Method>]
      #
      def search_all_methods(namespace)
        done = Hash.new { |h, k| h[k] = {} }
        matches = []

        recurse_namespace(namespace) do |klass|
          methods = Pry::Method.all_from_class(klass) + Pry::Method.all_from_obj(klass)
          methods.each do |method|
            next if done[method.owner][method.name]

            done[method.owner][method.name] = true

            matches << method if yield method
          end
        end

        matches
      end

      # Search for all methods with a name that matches the given regex
      # within a namespace.
      #
      # @param [Module] namespace The namespace to search
      # @return [Array<Method>]
      #
      def name_search(namespace)
        search_all_methods(namespace) do |meth|
          meth.name =~ pattern
        end
      end

      # Search for all methods who's implementation matches the given regex
      # within a namespace.
      #
      # @param [Module] namespace The namespace to search
      # @return [Array<Method>]
      #
      def content_search(namespace)
        search_all_methods(namespace) do |meth|
          begin
            meth.source =~ pattern
          rescue RescuableException
            false
          end
        end
      end
    end

    Pry::Commands.add_command(Pry::Command::FindMethod)
  end
end